|
6 | 6 | require "aws-sdk-cloudwatch" |
7 | 7 | require "singleton" |
8 | 8 |
|
9 | | -module AutoScalingMetrics |
10 | | - class Reporter |
11 | | - include Singleton |
| 9 | +module RequestQueueTime |
| 10 | + module AutoScalingMetrics |
| 11 | + class Reporter |
| 12 | + include Singleton |
12 | 13 |
|
13 | | - DIMENSIONS = [ |
14 | | - {name: "service", value: ENV["APP_NAME"]}, |
15 | | - {name: "environment", value: ENV["SERVER_ENVIRONMENT"]} |
16 | | - ] |
| 14 | + DIMENSIONS = [ |
| 15 | + {name: "service", value: ENV["APP_NAME"]}, |
| 16 | + {name: "environment", value: ENV["SERVER_ENVIRONMENT"]} |
| 17 | + ] |
17 | 18 |
|
18 | | - attr_accessor :collector |
| 19 | + attr_accessor :collector |
19 | 20 |
|
20 | | - def self.start(&) |
21 | | - return false if instance.started? |
| 21 | + def self.start(&) |
| 22 | + return false if instance.started? |
22 | 23 |
|
23 | | - instance.start!(&) |
24 | | - end |
25 | | - |
26 | | - def self.stop |
27 | | - return unless instance.started? |
28 | | - instance.stop! |
29 | | - end |
30 | | - |
31 | | - def start!(&block) |
32 | | - Rails.logger.info "Starting AutoScalingMetrics::Reporter" |
33 | | - @interval = 30 |
34 | | - @buffer = Queue.new |
35 | | - @buffer_size_limit = 1000 |
36 | | - @cloudwatch = Aws::CloudWatch::Client.new |
37 | | - @last_flush_time = Time.now |
38 | | - @pid = Process.pid |
| 24 | + instance.start!(&) |
| 25 | + end |
39 | 26 |
|
40 | | - yield self if block |
| 27 | + def self.stop |
| 28 | + return unless instance.started? |
| 29 | + instance.stop! |
| 30 | + end |
41 | 31 |
|
42 | | - start_flush_thread |
43 | | - end |
| 32 | + def start!(&block) |
| 33 | + Rails.logger.info "Starting AutoScalingMetrics::Reporter" |
| 34 | + @interval = 30 |
| 35 | + @buffer = Queue.new |
| 36 | + @buffer_size_limit = 1000 |
| 37 | + @cloudwatch = Aws::CloudWatch::Client.new |
| 38 | + @last_flush_time = Time.now |
| 39 | + @pid = Process.pid |
44 | 40 |
|
45 | | - def started? |
46 | | - @pid == Process.pid |
47 | | - end |
| 41 | + yield self if block |
48 | 42 |
|
49 | | - def stop! |
50 | | - @_thread&.terminate |
51 | | - @_thread = nil |
52 | | - @pid = nil |
53 | | - end |
| 43 | + start_flush_thread |
| 44 | + end |
54 | 45 |
|
55 | | - def track_request_queue_time(time) |
56 | | - add_metric(metric_name: "request_queue_time", value: time, unit: "Milliseconds", timestamp: Time.now) |
57 | | - end |
| 46 | + def started? |
| 47 | + @pid == Process.pid |
| 48 | + end |
58 | 49 |
|
59 | | - def self.add_metric(metric) |
60 | | - instance.add_metric(metric) |
61 | | - end |
| 50 | + def stop! |
| 51 | + @_thread&.terminate |
| 52 | + @_thread = nil |
| 53 | + @pid = nil |
| 54 | + end |
62 | 55 |
|
63 | | - def add_metric(metric) |
64 | | - metric[:dimensions] = (metric[:dimensions] || []) + DIMENSIONS |
65 | | - @buffer << metric |
66 | | - end |
| 56 | + def track_request_queue_time(time) |
| 57 | + add_metric(metric_name: "request_queue_time", value: time, unit: "Milliseconds", timestamp: Time.now) |
| 58 | + end |
67 | 59 |
|
68 | | - private |
| 60 | + def self.add_metric(metric) |
| 61 | + instance.add_metric(metric) |
| 62 | + end |
69 | 63 |
|
70 | | - def start_flush_thread |
71 | | - @_thread = Thread.new do |
72 | | - Thread.current.name = "auto_scaling_metrics.#{@pid}" |
| 64 | + def add_metric(metric) |
| 65 | + metric[:dimensions] = (metric[:dimensions] || []) + DIMENSIONS |
| 66 | + @buffer << metric |
| 67 | + end |
73 | 68 |
|
74 | | - loop do |
75 | | - if should_flush? |
76 | | - collector&.call |
77 | | - flush_metrics |
| 69 | + private |
| 70 | + |
| 71 | + def start_flush_thread |
| 72 | + @_thread = Thread.new do |
| 73 | + Thread.current.name = "auto_scaling_metrics.#{@pid}" |
| 74 | + |
| 75 | + loop do |
| 76 | + if should_flush? |
| 77 | + collector&.call |
| 78 | + flush_metrics |
| 79 | + end |
| 80 | + rescue => ex |
| 81 | + Sentry.capture_exception(ex) |
| 82 | + ensure |
| 83 | + sleep(1) |
78 | 84 | end |
79 | | - rescue => ex |
80 | | - Sentry.capture_exception(ex) |
81 | | - ensure |
82 | | - sleep(1) |
83 | 85 | end |
84 | 86 | end |
85 | | - end |
86 | 87 |
|
87 | | - def should_flush? |
88 | | - @buffer.size >= @buffer_size_limit || (Time.now - @last_flush_time) >= @interval |
89 | | - end |
| 88 | + def should_flush? |
| 89 | + @buffer.size >= @buffer_size_limit || (Time.now - @last_flush_time) >= @interval |
| 90 | + end |
90 | 91 |
|
91 | | - def flush_metrics |
92 | | - metrics_to_flush = [] |
93 | | - metrics_to_flush << @buffer.pop until @buffer.empty? |
| 92 | + def flush_metrics |
| 93 | + metrics_to_flush = [] |
| 94 | + metrics_to_flush << @buffer.pop until @buffer.empty? |
94 | 95 |
|
95 | | - unless metrics_to_flush.empty? |
96 | | - put_metrics_to_cloudwatch(metrics_to_flush) |
97 | | - @last_flush_time = Time.now |
| 96 | + unless metrics_to_flush.empty? |
| 97 | + put_metrics_to_cloudwatch(metrics_to_flush) |
| 98 | + @last_flush_time = Time.now |
| 99 | + end |
98 | 100 | end |
99 | | - end |
100 | 101 |
|
101 | | - def put_metrics_to_cloudwatch(metrics) |
102 | | - return if Rails.env.development? |
| 102 | + def put_metrics_to_cloudwatch(metrics) |
| 103 | + return if Rails.env.development? |
103 | 104 |
|
104 | | - @cloudwatch.put_metric_data( |
105 | | - namespace: "Teamtailor/queue_times", |
106 | | - metric_data: metrics.take(1000) |
107 | | - ) |
| 105 | + @cloudwatch.put_metric_data( |
| 106 | + namespace: "Teamtailor/queue_times", |
| 107 | + metric_data: metrics.take(1000) |
| 108 | + ) |
| 109 | + end |
108 | 110 | end |
109 | 111 | end |
110 | 112 | end |
0 commit comments