Class: RailsPulse::Jobs::Charts::Duration

Inherits:
Charts::Base show all
Defined in:
app/models/rails_pulse/jobs/charts/duration.rb

Instance Method Summary collapse

Methods inherited from Charts::Base

#initialize

Constructor Details

This class inherits a constructor from RailsPulse::Charts::Base

Instance Method Details

#to_chart_dataObject



5
6
7
8
9
10
11
12
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
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 'app/models/rails_pulse/jobs/charts/duration.rb', line 5

def to_chart_data
  summaries = base_summary_query

  # Group by period_start and calculate weighted percentiles
  summaries = summaries
    .group(:period_start)
    .select(
      :period_start,
      "SUM(rails_pulse_summaries.count) as total_count",
      "SUM(rails_pulse_summaries.p50_duration * rails_pulse_summaries.count) as total_weighted_p50",
      "SUM(rails_pulse_summaries.p95_duration * rails_pulse_summaries.count) as total_weighted_p95",
      "SUM(rails_pulse_summaries.p99_duration * rails_pulse_summaries.count) as total_weighted_p99"
    )

  # Build raw_data hash from grouped results
  raw_data = {}
  summaries.each do |summary|
    timestamp = summary.period_start.to_i
    count = summary.total_count || 0

    raw_data[timestamp] = {
      total_weighted_p50: summary.total_weighted_p50 || 0,
      total_weighted_p95: summary.total_weighted_p95 || 0,
      total_weighted_p99: summary.total_weighted_p99 || 0,
      total_count: count
    }
  end

  # Convert to final values (weighted averages) and pad missing data
  step = time_step
  daily_data = {}
  (@start_time.to_i..@end_time.to_i).step(step) do |timestamp|
    if raw_data[timestamp]
      count = raw_data[timestamp][:total_count]
      daily_data[timestamp] = {
        p50: count > 0 ? (raw_data[timestamp][:total_weighted_p50] / count).round(0) : nil,
        p95: count > 0 ? (raw_data[timestamp][:total_weighted_p95] / count).round(0) : nil,
        p99: count > 0 ? (raw_data[timestamp][:total_weighted_p99] / count).round(0) : nil
      }
    else
      daily_data[timestamp] = { p50: nil, p95: nil, p99: nil }
    end
  end

  # Build labels array (timestamps in milliseconds for JavaScript)
  labels = daily_data.keys.map { |timestamp| timestamp * 1000 }

  # Build series data
  series = []

  p50_data = daily_data.values.map { |data| data[:p50] }
  series << {
    name: "P50",
    data: p50_data,
    type: "line",
    color: RailsPulse::ChartColors::DEFAULT
  }

  p95_data = daily_data.values.map { |data| data[:p95] }
  series << {
    name: "P95",
    data: p95_data,
    type: "line",
    color: RailsPulse::ChartColors::P95
  }

  p99_data = daily_data.values.map { |data| data[:p99] }
  series << {
    name: "P99",
    data: p99_data,
    type: "line",
    color: RailsPulse::ChartColors::P99
  }

  {
    labels: labels,
    series: series
  }
end