Class: Sqreen::PerformanceNotifications::BinnedMetrics

Inherits:
Object
  • Object
show all
Defined in:
lib/sqreen/performance_notifications/binned_metrics.rb

Overview

Logs callback performance

Constant Summary collapse

DEFAULT_PERF_BASE =
2.0
DEFAULT_PERF_UNIT =

ms

0.1
DEFAULT_PERF_PCT_BASE =
1.3
DEFAULT_PERF_PCT_UNIT =

%

1.0
EVENT_REQ =

request total time

'req'.freeze
EVENT_TOTAL_TIME =

sqreen total overhead callback time

'sq'.freeze
EVENT_PERCENT =

sqreen total overhead percent of time

'pct'.freeze
EVENT_SQ_THREAD_CPU_PCT =

sqreen thread cpu time

'sq_thread_cpu_pct'.freeze

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(metrics_store, period, perf_metric_opts, perf_metric_percent_opts) ⇒ BinnedMetrics

Returns a new instance of BinnedMetrics.

Parameters:



23
24
25
26
27
28
29
30
31
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 23

def initialize(metrics_store, period, perf_metric_opts, perf_metric_percent_opts)
  @metrics_store = metrics_store
  @period = period
  @subid = nil
  @perf_metric_opts = perf_metric_opts
  @perf_metric_percent_opts = perf_metric_percent_opts
  @clock_time = Sqreen.time
  @watcher_cpu_time = 0
end

Class Attribute Details

.instanceSqreen::PerformanceNotifications::BinnedMetrics (readonly)



141
142
143
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 141

def instance
  @instance
end

Class Method Details

.disableObject



154
155
156
157
158
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 154

def disable
  return unless instance
  instance.disable
  @instance = nil
end

.enable(metrics_store, period = 60, base = DEFAULT_PERF_BASE, factor = DEFAULT_PERF_UNIT, base_pct = DEFAULT_PERF_PCT_BASE, factor_pct = DEFAULT_PERF_PCT_UNIT) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 142

def enable(metrics_store, period = 60,
           base = DEFAULT_PERF_BASE,
           factor = DEFAULT_PERF_UNIT,
           base_pct = DEFAULT_PERF_PCT_BASE,
           factor_pct = DEFAULT_PERF_PCT_UNIT)
  disable
  @instance = new(metrics_store, period,
                  {'base'=> base, 'factor' => factor},
                  {'base' => base_pct, 'factor' => factor_pct}
                 ).tap(&:enable)
end

.finish_requestObject



165
166
167
168
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 165

def finish_request
  return unless instance
  instance.finish_request
end

.finish_watcher_runObject



170
171
172
173
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 170

def finish_watcher_run
  return unless instance
  instance.finish_watcher_run
end

.start_requestObject



160
161
162
163
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 160

def start_request
  return unless instance
  instance.start_request
end

Instance Method Details

#disableObject



55
56
57
58
59
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 55

def disable
  return if @subid.nil?
  Sqreen::PerformanceNotifications.unsubscribe(@subid)
  @subid = nil
end

#enableObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 33

def enable
  return unless @subid.nil?

  metrics_store.create_metric(
    'name' => EVENT_REQ, 'period' => period, 'kind' => 'Binning', 'options' => @perf_metric_opts
  )
  metrics_store.create_metric(
    'name' => EVENT_TOTAL_TIME, 'period' => period, 'kind' => 'Binning', 'options' => @perf_metric_opts
  )
  metrics_store.create_metric(
    'name' => EVENT_PERCENT, 'period' => period, 'kind' => 'Binning', 'options' => @perf_metric_percent_opts
  )

  if Sqreen.thread_cpu_time?
    metrics_store.create_metric('name' => EVENT_SQ_THREAD_CPU_PCT,
                                'period' => period, 'kind' => 'Binning',
                                'options' => @perf_metric_percent_opts)
  end

  @subid = Sqreen::PerformanceNotifications.subscribe(&method(:log))
end

#finish_requestObject



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 77

def finish_request
  start_time = SharedStorage[:request_start_time]
  finish_time = Sqreen.time
  duration_millis = (finish_time - start_time) * 1000

  finish_time_obj = Time.now.utc
  # format of evt is [cat, key, value, timestamp]
  Sqreen.observations_queue.push(
    [EVENT_REQ, nil, duration_millis, finish_time_obj]
  )
  total_t = SharedStorage[:sqreen_request_time]
  Sqreen.observations_queue.push(
    [EVENT_TOTAL_TIME, nil,
     total_t, finish_time_obj]
  )
  return if !duration_millis or total_t >= duration_millis
  Sqreen.observations_queue.push(
    [EVENT_PERCENT, nil,
     (total_t*100.0)/(duration_millis-total_t), finish_time_obj]
  )
end

#finish_watcher_runObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 99

def finish_watcher_run
  return unless Sqreen.thread_cpu_time?
  new_clock_time = Sqreen.time
  # collect observation at min 30 second intervals so it's nicely averaged
  return if new_clock_time - @clock_time < 30.0

  clock_time_before = @clock_time
  watcher_cpu_time_before = @watcher_cpu_time
  @clock_time = new_clock_time
  @watcher_cpu_time = Sqreen.thread_cpu_time

  clock_time_diff = @clock_time - clock_time_before
  watcher_cpu_diff = @watcher_cpu_time - watcher_cpu_time_before

  Sqreen.observations_queue.push(
    [EVENT_SQ_THREAD_CPU_PCT, nil,
     (watcher_cpu_diff * 100.0) / clock_time_diff, Time.now.utc]
  )
end

#log(rule, cb, start, finish, _meta) ⇒ Object



61
62
63
64
65
66
67
68
69
70
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 61

def log(rule, cb, start, finish, _meta)
  metric_name = "sq.#{rule}.#{cb}"
  ensure_metric(metric_name)

  time_millis = (finish - start) * 1000
  # Ensure we always have a timings if we somehow missed the request start
  SharedStorage[:sqreen_request_time] =
    (SharedStorage[:sqreen_request_time] || 0) + time_millis
  metrics_store.update(metric_name, finish, nil, time_millis)
end

#start_requestObject



72
73
74
75
# File 'lib/sqreen/performance_notifications/binned_metrics.rb', line 72

def start_request
  SharedStorage[:request_start_time] = Sqreen.time
  SharedStorage[:sqreen_request_time] = 0.0
end