Class: Chronicle::ErrorGroup
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Chronicle::ErrorGroup
- Defined in:
- app/models/chronicle/error_group.rb
Constant Summary collapse
- OPEN =
'open'.freeze
- RESOLVED =
'resolved'.freeze
- IGNORED =
'ignored'.freeze
- VALID_STATUSES =
[OPEN, RESOLVED, IGNORED].freeze
Class Method Summary collapse
-
.compute_fingerprint(error_log) ⇒ Object
Derives a deterministic fingerprint from the structural identity of an error.
Instance Method Summary collapse
- #as_json(_options = {}) ⇒ Object
- #get_hash ⇒ Object
-
#record_occurrence!(backend_version: nil, client_version: nil, at: Time.current) ⇒ Object
Atomically records a new occurrence of this error.
Class Method Details
.compute_fingerprint(error_log) ⇒ Object
Derives a deterministic fingerprint from the structural identity of an error. Same source location + message + cleaned backtrace always yields the same hash, so two occurrences of the same bug map to the same group.
23 24 25 26 27 28 29 30 31 |
# File 'app/models/chronicle/error_group.rb', line 23 def self.compute_fingerprint(error_log) payload = [ error_log.source_type, error_log.source_name, error_log., error_log.cleaned_backtrace.to_s.first(2000), ].join("\xff") Digest::SHA256.hexdigest(payload) end |
Instance Method Details
#as_json(_options = {}) ⇒ Object
49 50 51 |
# File 'app/models/chronicle/error_group.rb', line 49 def as_json( = {}) get_hash end |
#get_hash ⇒ Object
45 46 47 |
# File 'app/models/chronicle/error_group.rb', line 45 def get_hash attributes.symbolize_keys.merge(error_fingerprint: fingerprint) end |
#record_occurrence!(backend_version: nil, client_version: nil, at: Time.current) ⇒ Object
Atomically records a new occurrence of this error. Uses a row-level lock so concurrent increments never collide.
35 36 37 38 39 40 41 42 43 |
# File 'app/models/chronicle/error_group.rb', line 35 def record_occurrence!(backend_version: nil, client_version: nil, at: Time.current) with_lock do self.last_seen_at = [last_seen_at, at].compact.max self.backend_version = backend_version if backend_version.present? self.client_version = client_version if client_version.present? self.occurrence_count += 1 save! end end |