Class: RailsErrorDashboard::Queries::CoOccurringErrors
- Inherits:
-
Object
- Object
- RailsErrorDashboard::Queries::CoOccurringErrors
- Defined in:
- lib/rails_error_dashboard/queries/co_occurring_errors.rb
Overview
Find errors that occur together in time (co-occurring errors)
This query analyzes error occurrences to find patterns of errors that happen within the same time window, which can indicate:
-
Cascading failures (one error causes another)
-
Related errors from the same underlying issue
-
Correlated errors from the same feature/endpoint
Class Method Summary collapse
-
.call(error_log_id:, window_minutes: 5, min_frequency: 2, limit: 10) ⇒ Array<Hash>
Find co-occurring errors.
Instance Method Summary collapse
- #find_co_occurring ⇒ Object
-
#initialize(error_log_id, window_minutes: 5, min_frequency: 2, limit: 10) ⇒ CoOccurringErrors
constructor
A new instance of CoOccurringErrors.
Constructor Details
#initialize(error_log_id, window_minutes: 5, min_frequency: 2, limit: 10) ⇒ CoOccurringErrors
Returns a new instance of CoOccurringErrors.
30 31 32 33 34 35 |
# File 'lib/rails_error_dashboard/queries/co_occurring_errors.rb', line 30 def initialize(error_log_id, window_minutes: 5, min_frequency: 2, limit: 10) @error_log_id = error_log_id @window_minutes = window_minutes.to_i @min_frequency = min_frequency.to_i @limit = limit.to_i end |
Class Method Details
.call(error_log_id:, window_minutes: 5, min_frequency: 2, limit: 10) ⇒ Array<Hash>
Find co-occurring errors
26 27 28 |
# File 'lib/rails_error_dashboard/queries/co_occurring_errors.rb', line 26 def self.call(error_log_id:, window_minutes: 5, min_frequency: 2, limit: 10) new(error_log_id, window_minutes: window_minutes, min_frequency: min_frequency, limit: limit).find_co_occurring end |
Instance Method Details
#find_co_occurring ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rails_error_dashboard/queries/co_occurring_errors.rb', line 37 def find_co_occurring target_error = ErrorLog.find_by(id: @error_log_id) return [] unless target_error # Get all occurrences of the target error target_occurrences = ErrorOccurrence.where(error_log_id: @error_log_id) return [] if target_occurrences.empty? # For each occurrence, find other errors in the time window co_occurrence_data = Hash.new { |h, k| h[k] = { count: 0, delays: [] } } target_occurrences.find_each do |occurrence| window = @window_minutes.minutes start_time = occurrence.occurred_at - window end_time = occurrence.occurred_at + window # Find other error occurrences in this time window nearby_occurrences = ErrorOccurrence .in_time_window(start_time, end_time) .where.not(error_log_id: @error_log_id) .includes(:error_log) nearby_occurrences.each do |nearby| error_log_id = nearby.error_log_id co_occurrence_data[error_log_id][:count] += 1 # Calculate delay (negative = before, positive = after target error) delay = (nearby.occurred_at - occurrence.occurred_at).to_f co_occurrence_data[error_log_id][:delays] << delay end end # Filter by minimum frequency and build results results = co_occurrence_data.select { |_id, data| data[:count] >= @min_frequency }.map do |error_log_id, data| error = ErrorLog.find(error_log_id) avg_delay = data[:delays].sum / data[:delays].size { error: error, frequency: data[:count], avg_delay_seconds: avg_delay.round(2) } end # Sort by frequency (most common first) and limit results results.sort_by { |r| -r[:frequency] }.first(@limit) end |