Class: Fractor::ErrorStatistics
- Inherits:
-
Object
- Object
- Fractor::ErrorStatistics
- Defined in:
- lib/fractor/error_statistics.rb
Overview
Error statistics for a specific category or job. Tracks error counts, severity distribution, and trends over time.
Instance Attribute Summary collapse
-
#by_code ⇒ Object
readonly
Returns the value of attribute by_code.
-
#by_severity ⇒ Object
readonly
Returns the value of attribute by_severity.
-
#category ⇒ Object
readonly
Returns the value of attribute category.
-
#recent_errors ⇒ Object
readonly
Returns the value of attribute recent_errors.
-
#total_count ⇒ Object
readonly
Returns the value of attribute total_count.
Instance Method Summary collapse
-
#error_rate ⇒ Float
Get error rate (errors per second).
-
#highest_severity ⇒ String?
Get most severe error level.
-
#increasing? ⇒ Boolean
Check if error rate is increasing.
-
#initialize(category) ⇒ ErrorStatistics
constructor
A new instance of ErrorStatistics.
-
#most_common_code ⇒ String?
Get most common error code.
-
#record(work_result) ⇒ void
Record an error from a work result.
-
#to_h ⇒ Hash
Get summary hash.
Constructor Details
#initialize(category) ⇒ ErrorStatistics
Returns a new instance of ErrorStatistics.
9 10 11 12 13 14 15 16 17 18 |
# File 'lib/fractor/error_statistics.rb', line 9 def initialize(category) @category = category @total_count = 0 @by_severity = Hash.new(0) @by_code = Hash.new(0) @recent_errors = [] @first_seen = nil @last_seen = nil @mutex = Mutex.new end |
Instance Attribute Details
#by_code ⇒ Object (readonly)
Returns the value of attribute by_code.
7 8 9 |
# File 'lib/fractor/error_statistics.rb', line 7 def by_code @by_code end |
#by_severity ⇒ Object (readonly)
Returns the value of attribute by_severity.
7 8 9 |
# File 'lib/fractor/error_statistics.rb', line 7 def by_severity @by_severity end |
#category ⇒ Object (readonly)
Returns the value of attribute category.
7 8 9 |
# File 'lib/fractor/error_statistics.rb', line 7 def category @category end |
#recent_errors ⇒ Object (readonly)
Returns the value of attribute recent_errors.
7 8 9 |
# File 'lib/fractor/error_statistics.rb', line 7 def recent_errors @recent_errors end |
#total_count ⇒ Object (readonly)
Returns the value of attribute total_count.
7 8 9 |
# File 'lib/fractor/error_statistics.rb', line 7 def total_count @total_count end |
Instance Method Details
#error_rate ⇒ Float
Get error rate (errors per second)
60 61 62 63 64 65 66 67 |
# File 'lib/fractor/error_statistics.rb', line 60 def error_rate return 0.0 unless @first_seen && @last_seen duration = @last_seen - @first_seen return 0.0 if duration <= 0 @total_count / duration end |
#highest_severity ⇒ String?
Get most severe error level
81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/fractor/error_statistics.rb', line 81 def highest_severity return nil if @by_severity.empty? severities = [ WorkResult::SEVERITY_CRITICAL, WorkResult::SEVERITY_ERROR, WorkResult::SEVERITY_WARNING, WorkResult::SEVERITY_INFO, ] severities.find { |severity| @by_severity[severity].positive? } end |
#increasing? ⇒ Boolean
Check if error rate is increasing
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/fractor/error_statistics.rb', line 97 def increasing? return false if @recent_errors.size < 10 recent_10 = @recent_errors.last(10) # Check if errors are happening in a short time span (rapid burst) = recent_10.first[:timestamp] = recent_10.last[:timestamp] total_timespan = - # If all errors happened in a very short time (burst), consider it increasing return true if total_timespan < 1.0 # Less than 1 second for 10 errors # Otherwise, check if the rate is increasing by comparing first half vs second half first_5 = recent_10.first(5) last_5 = recent_10.last(5) first_5_timespan = first_5.last[:timestamp] - first_5.first[:timestamp] last_5_timespan = last_5.last[:timestamp] - last_5.first[:timestamp] # Avoid division by zero - use small epsilon if timespan is very small first_5_timespan = 0.001 if first_5_timespan <= 0 last_5_timespan = 0.001 if last_5_timespan <= 0 # Calculate error rate (errors per second) for each group first_5_rate = 5.0 / first_5_timespan last_5_rate = 5.0 / last_5_timespan # Consider increasing if the rate is 50% higher last_5_rate > first_5_rate * 1.5 end |
#most_common_code ⇒ String?
Get most common error code
72 73 74 75 76 |
# File 'lib/fractor/error_statistics.rb', line 72 def most_common_code return nil if @by_code.empty? @by_code.max_by { |_code, count| count }&.first end |
#record(work_result) ⇒ void
This method returns an undefined value.
Record an error from a work result
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/fractor/error_statistics.rb', line 24 def record(work_result) @mutex.synchronize do @total_count += 1 @by_severity[work_result.error_severity] += 1 @by_code[work_result.error_code] += 1 if work_result.error_code # Handle both String and Exception error types error_obj = work_result.error = if error_obj.is_a?(Exception) error_obj. elsif error_obj.is_a?(String) error_obj else error_obj&.to_s end error_entry = { timestamp: Time.now, error_class: error_obj.is_a?(Exception) ? error_obj.class.name : nil, error_message: , error_code: work_result.error_code, error_severity: work_result.error_severity, error_context: work_result.error_context, } @recent_errors << error_entry @recent_errors.shift if @recent_errors.size > 100 @first_seen ||= Time.now @last_seen = Time.now end end |
#to_h ⇒ Hash
Get summary hash
132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/fractor/error_statistics.rb', line 132 def to_h { category: @category, total_count: @total_count, error_rate: error_rate.round(2), by_severity: @by_severity, by_code: @by_code, most_common_code: most_common_code, highest_severity: highest_severity, first_seen: @first_seen, last_seen: @last_seen, trending: increasing? ? "increasing" : "stable", } end |