Class: Fractor::PerformanceReportGenerator
- Inherits:
-
Object
- Object
- Fractor::PerformanceReportGenerator
- Defined in:
- lib/fractor/performance_report_generator.rb
Overview
Generates formatted reports from performance metrics snapshots. Supports text, JSON, and Prometheus output formats.
Class Method Summary collapse
-
.format_duration(seconds) ⇒ String
Format duration in human-readable format.
-
.format_float(value) ⇒ String
Format float value with 2 decimal places.
-
.format_ms(seconds) ⇒ String
Format seconds as milliseconds.
-
.format_percent(ratio) ⇒ String
Format ratio as percentage.
-
.generate_report(stats) ⇒ String
Generate a human-readable text report.
-
.success_rate(stats) ⇒ Float
Calculate success rate from metrics.
-
.to_json(stats) ⇒ String
Export metrics in JSON format.
-
.to_prometheus(stats, total_latency, prefix: "fractor") ⇒ String
Export metrics in Prometheus format.
Class Method Details
.format_duration(seconds) ⇒ String
Format duration in human-readable format
158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/fractor/performance_report_generator.rb', line 158 def self.format_duration(seconds) return "0s" if seconds.nil? || seconds.zero? hours = (seconds / 3600).floor minutes = ((seconds % 3600) / 60).floor secs = (seconds % 60).round(2) parts = [] parts << "#{hours}h" if hours.positive? parts << "#{minutes}m" if minutes.positive? parts << "#{secs}s" parts.join(" ") end |
.format_float(value) ⇒ String
Format float value with 2 decimal places
186 187 188 189 190 |
# File 'lib/fractor/performance_report_generator.rb', line 186 def self.format_float(value) return "0.00" if value.nil? value.round(2) end |
.format_ms(seconds) ⇒ String
Format seconds as milliseconds
176 177 178 179 180 |
# File 'lib/fractor/performance_report_generator.rb', line 176 def self.format_ms(seconds) return "0.00" if seconds.nil? (seconds * 1000).round(2) end |
.format_percent(ratio) ⇒ String
Format ratio as percentage
196 197 198 199 200 |
# File 'lib/fractor/performance_report_generator.rb', line 196 def self.format_percent(ratio) return "0.00%" if ratio.nil? "#{(ratio * 100).round(2)}%" end |
.generate_report(stats) ⇒ String
Generate a human-readable text report
13 14 15 16 17 18 19 20 21 22 23 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/performance_report_generator.rb', line 13 def self.generate_report(stats) <<~REPORT Performance Metrics =================== Duration: #{format_duration(stats[:uptime])} Jobs: Processed: #{stats[:jobs_processed]} Succeeded: #{stats[:jobs_succeeded]} Failed: #{stats[:jobs_failed]} Success Rate: #{success_rate(stats)}% Latency (ms): Average: #{format_ms(stats[:average_latency])} P50: #{format_ms(stats[:p50_latency])} P95: #{format_ms(stats[:p95_latency])} P99: #{format_ms(stats[:p99_latency])} Throughput: Jobs/sec: #{format_float(stats[:throughput])} Workers: Total: #{stats[:worker_count]} Active: #{stats[:active_workers]} Utilization: #{format_percent(stats[:worker_utilization])} Queue: Current Depth: #{stats[:queue_depth]} Average Depth: #{format_float(stats[:queue_depth_avg])} Max Depth: #{stats[:queue_depth_max]} Enqueue Rate: #{format_float(stats[:enqueue_rate])} items/sec Dequeue Rate: #{format_float(stats[:dequeue_rate])} items/sec Wait Time (ms): Average: #{format_ms(stats[:average_wait_time])} P50: #{format_ms(stats[:p50_wait_time])} P95: #{format_ms(stats[:p95_wait_time])} P99: #{format_ms(stats[:p99_wait_time])} Memory: Current: #{format_float(stats[:memory_mb])} MB REPORT end |
.success_rate(stats) ⇒ Float
Calculate success rate from metrics
147 148 149 150 151 152 |
# File 'lib/fractor/performance_report_generator.rb', line 147 def self.success_rate(stats) total = stats[:jobs_processed] return 0.0 if total.zero? (stats[:jobs_succeeded].to_f / total * 100).round(2) end |
.to_json(stats) ⇒ String
Export metrics in JSON format
61 62 63 |
# File 'lib/fractor/performance_report_generator.rb', line 61 def self.to_json(stats) stats.to_json end |
.to_prometheus(stats, total_latency, prefix: "fractor") ⇒ String
Export metrics in Prometheus format
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/fractor/performance_report_generator.rb', line 71 def self.to_prometheus(stats, total_latency, prefix: "fractor") <<~PROMETHEUS # HELP #{prefix}_jobs_processed_total Total number of jobs processed # TYPE #{prefix}_jobs_processed_total counter #{prefix}_jobs_processed_total #{stats[:jobs_processed]} # HELP #{prefix}_jobs_succeeded_total Total number of jobs that succeeded # TYPE #{prefix}_jobs_succeeded_total counter #{prefix}_jobs_succeeded_total #{stats[:jobs_succeeded]} # HELP #{prefix}_jobs_failed_total Total number of jobs that failed # TYPE #{prefix}_jobs_failed_total counter #{prefix}_jobs_failed_total #{stats[:jobs_failed]} # HELP #{prefix}_latency_seconds Job processing latency # TYPE #{prefix}_latency_seconds summary #{prefix}_latency_seconds{quantile="0.5"} #{stats[:p50_latency] || 0} #{prefix}_latency_seconds{quantile="0.95"} #{stats[:p95_latency] || 0} #{prefix}_latency_seconds{quantile="0.99"} #{stats[:p99_latency] || 0} #{prefix}_latency_seconds_sum #{total_latency} #{prefix}_latency_seconds_count #{stats[:jobs_processed]} # HELP #{prefix}_throughput_jobs_per_second Current throughput # TYPE #{prefix}_throughput_jobs_per_second gauge #{prefix}_throughput_jobs_per_second #{stats[:throughput] || 0} # HELP #{prefix}_queue_depth Current queue depth # TYPE #{prefix}_queue_depth gauge #{prefix}_queue_depth #{stats[:queue_depth]} # HELP #{prefix}_queue_depth_avg Average queue depth # TYPE #{prefix}_queue_depth_avg gauge #{prefix}_queue_depth_avg #{stats[:queue_depth_avg] || 0} # HELP #{prefix}_queue_depth_max Maximum queue depth # TYPE #{prefix}_queue_depth_max gauge #{prefix}_queue_depth_max #{stats[:queue_depth_max] || 0} # HELP #{prefix}_enqueue_rate_total Items enqueued per second # TYPE #{prefix}_enqueue_rate_total gauge #{prefix}_enqueue_rate_total #{stats[:enqueue_rate] || 0} # HELP #{prefix}_dequeue_rate_total Items dequeued per second # TYPE #{prefix}_dequeue_rate_total gauge #{prefix}_dequeue_rate_total #{stats[:dequeue_rate] || 0} # HELP #{prefix}_wait_time_seconds Queue wait time # TYPE #{prefix}_wait_time_seconds summary #{prefix}_wait_time_seconds{quantile="0.5"} #{stats[:p50_wait_time] || 0} #{prefix}_wait_time_seconds{quantile="0.95"} #{stats[:p95_wait_time] || 0} #{prefix}_wait_time_seconds{quantile="0.99"} #{stats[:p99_wait_time] || 0} #{prefix}_wait_time_seconds_sum #{stats[:average_wait_time] || 0} #{prefix}_wait_time_seconds_count #{stats[:jobs_processed]} # HELP #{prefix}_workers_total Total number of workers # TYPE #{prefix}_workers_total gauge #{prefix}_workers_total #{stats[:worker_count]} # HELP #{prefix}_workers_active Number of active workers # TYPE #{prefix}_workers_active gauge #{prefix}_workers_active #{stats[:active_workers]} # HELP #{prefix}_worker_utilization Worker utilization ratio # TYPE #{prefix}_worker_utilization gauge #{prefix}_worker_utilization #{stats[:worker_utilization] || 0} # HELP #{prefix}_memory_bytes Current memory usage # TYPE #{prefix}_memory_bytes gauge #{prefix}_memory_bytes #{(stats[:memory_mb] || 0) * 1024 * 1024} PROMETHEUS end |