prometheus_exporter 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5e708b8c63be6ecff9750deebf18cad149d9b4fa7350a4523af2f145caffec5
4
- data.tar.gz: 1204a53af367dc60e24ded2e1630e2b447ef79d3caff32165ac5c40b62955ded
3
+ metadata.gz: 0a8fb6585d155b56625dcd0d89c41301659e5b32cfc8272a340c7b067dbf686a
4
+ data.tar.gz: 6e5715300786de15f2906b4f8a5603bd19150cb1c511cb83e5c3a3bdf53a5f5b
5
5
  SHA512:
6
- metadata.gz: 5dee50712e73be92702e2948a0a69aa8b8007df59de35f10c5980d9d5a2653092a4247e7ad207713460df80f59bb0691835a3aa2b04fa751d28cc5b9c3f66f48
7
- data.tar.gz: 0af7415fd207b1eb5f7f62639f8d48bc7735df9397537524c536631d24150b9b7daa87d17652f070a79f8134d50e780c9143ddeedcfc2d44eaa27586ffe64b19
6
+ metadata.gz: 52cce25c1403f889f65fc25b054ec22703f32dad1c32d14e35af74b65308c2bf7f0a10e8343bd906c98f884167243484f43114700c3175113e8e75f002421823
7
+ data.tar.gz: de8bc77ce936ad4f045c0f34907febb881518b537d5828bfeba5476924355157902f6618a0acc37aa1202ff604853f7bb3908ba78478a6cd3cf57bb1b0f5ff66
data/CHANGELOG CHANGED
@@ -1,6 +1,10 @@
1
+ 2.0.1 - 2022-02-24
2
+
3
+ - FIX: ensure threads do not leak when calling #start repeatedly on instrumentation classes, this is an urgent patch for Puma integration
4
+
1
5
  2.0.0 - 2022-02-18
2
6
 
3
- - FEATURE: Add per worker custom labels
7
+ - FEATURE: Add per worker custom labels
4
8
  - FEATURE: support custom histogram buckets
5
9
  - FIX: all metrics are exposing status label, and not only `http_requests_total`
6
10
  - BREAKING: rename all `http_duration` metrics to `http_request_duration` to match prometheus official naming conventions (See https://prometheus.io/docs/practices/naming/#metric-names).
data/README.md CHANGED
@@ -575,7 +575,10 @@ The easiest way to gather this metrics is to put the following in your `puma.rb`
575
575
  # puma.rb config
576
576
  after_worker_boot do
577
577
  require 'prometheus_exporter/instrumentation'
578
- PrometheusExporter::Instrumentation::Puma.start
578
+ # optional check, avoids spinning up and down threads per worker
579
+ if !PrometheusExporter::Instrumentation::Puma.started?
580
+ PrometheusExporter::Instrumentation::Puma.start
581
+ end
579
582
  end
580
583
  ```
581
584
 
@@ -2,11 +2,10 @@
2
2
 
3
3
  # collects stats from currently running process
4
4
  module PrometheusExporter::Instrumentation
5
- class ActiveRecord
5
+ class ActiveRecord < PeriodicStats
6
6
  ALLOWED_CONFIG_LABELS = %i(database username host port)
7
7
 
8
8
  def self.start(client: nil, frequency: 30, custom_labels: {}, config_labels: [])
9
-
10
9
  client ||= PrometheusExporter::Client.default
11
10
 
12
11
  # Not all rails versions support connection pool stats
@@ -20,20 +19,12 @@ module PrometheusExporter::Instrumentation
20
19
 
21
20
  active_record_collector = new(custom_labels, config_labels)
22
21
 
23
- stop if @thread
24
-
25
- @thread = Thread.new do
26
- while true
27
- begin
28
- metrics = active_record_collector.collect
29
- metrics.each { |metric| client.send_json metric }
30
- rescue => e
31
- client.logger.error("Prometheus Exporter Failed To Collect Process Stats #{e}")
32
- ensure
33
- sleep frequency
34
- end
35
- end
22
+ worker_loop do
23
+ metrics = active_record_collector.collect
24
+ metrics.each { |metric| client.send_json metric }
36
25
  end
26
+
27
+ super
37
28
  end
38
29
 
39
30
  def self.validate_config_labels(config_labels)
@@ -41,13 +32,6 @@ module PrometheusExporter::Instrumentation
41
32
  raise "Invalid Config Labels, available options #{ALLOWED_CONFIG_LABELS}" if (config_labels - ALLOWED_CONFIG_LABELS).size > 0
42
33
  end
43
34
 
44
- def self.stop
45
- if t = @thread
46
- t.kill
47
- @thread = nil
48
- end
49
- end
50
-
51
35
  def initialize(metric_labels, config_labels)
52
36
  @metric_labels = metric_labels
53
37
  @config_labels = config_labels
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrometheusExporter::Instrumentation
4
+ class PeriodicStats
5
+
6
+ def self.start(*args, frequency:, client: nil, **kwargs)
7
+ client ||= PrometheusExporter::Client.default
8
+
9
+ if !(Numeric === frequency)
10
+ raise ArgumentError.new("Expected frequency to be a number")
11
+ end
12
+
13
+ if frequency < 0
14
+ raise ArgumentError.new("Expected frequency to be a positive number")
15
+ end
16
+
17
+ if !@worker_loop
18
+ raise ArgumentError.new("Worker loop was not set")
19
+ end
20
+
21
+ klass = self
22
+
23
+ stop
24
+
25
+ @stop_thread = false
26
+
27
+ @thread = Thread.new do
28
+ while !@stop_thread
29
+ begin
30
+ @worker_loop.call
31
+ rescue => e
32
+ client.logger.error("#{klass} Prometheus Exporter Failed To Collect Stats #{e}")
33
+ ensure
34
+ sleep frequency
35
+ end
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ def self.started?
42
+ !!@thread&.alive?
43
+ end
44
+
45
+ def self.worker_loop(&blk)
46
+ @worker_loop = blk
47
+ end
48
+
49
+ def self.stop
50
+ # to avoid a warning
51
+ @thread = nil if !defined?(@thread)
52
+
53
+ if @thread&.alive?
54
+ @stop_thread = true
55
+ @thread.wakeup
56
+ @thread.join
57
+ end
58
+ @thread = nil
59
+ end
60
+
61
+ end
62
+ end
@@ -2,8 +2,7 @@
2
2
 
3
3
  # collects stats from currently running process
4
4
  module PrometheusExporter::Instrumentation
5
- class Process
6
- @thread = nil if !defined?(@thread)
5
+ class Process < PeriodicStats
7
6
 
8
7
  def self.start(client: nil, type: "ruby", frequency: 30, labels: nil)
9
8
 
@@ -19,27 +18,12 @@ module PrometheusExporter::Instrumentation
19
18
  process_collector = new(metric_labels)
20
19
  client ||= PrometheusExporter::Client.default
21
20
 
22
- stop if @thread
23
-
24
- @thread = Thread.new do
25
- while true
26
- begin
27
- metric = process_collector.collect
28
- client.send_json metric
29
- rescue => e
30
- client.logger.error("Prometheus Exporter Failed To Collect Process Stats #{e}")
31
- ensure
32
- sleep frequency
33
- end
34
- end
21
+ worker_loop do
22
+ metric = process_collector.collect
23
+ client.send_json metric
35
24
  end
36
- end
37
25
 
38
- def self.stop
39
- if t = @thread
40
- t.kill
41
- @thread = nil
42
- end
26
+ super
43
27
  end
44
28
 
45
29
  def initialize(metric_labels)
@@ -4,22 +4,17 @@ require "json"
4
4
 
5
5
  # collects stats from puma
6
6
  module PrometheusExporter::Instrumentation
7
- class Puma
7
+ class Puma < PeriodicStats
8
8
  def self.start(client: nil, frequency: 30, labels: {})
9
9
  puma_collector = new(labels)
10
10
  client ||= PrometheusExporter::Client.default
11
- Thread.new do
12
- while true
13
- begin
14
- metric = puma_collector.collect
15
- client.send_json metric
16
- rescue => e
17
- client.logger.error("Prometheus Exporter Failed To Collect Puma Stats #{e}")
18
- ensure
19
- sleep frequency
20
- end
21
- end
11
+
12
+ worker_loop do
13
+ metric = puma_collector.collect
14
+ client.send_json metric
22
15
  end
16
+
17
+ super
23
18
  end
24
19
 
25
20
  def initialize(metric_labels = {})
@@ -2,21 +2,16 @@
2
2
 
3
3
  # collects stats from resque
4
4
  module PrometheusExporter::Instrumentation
5
- class Resque
5
+ class Resque < PeriodicStats
6
6
  def self.start(client: nil, frequency: 30)
7
7
  resque_collector = new
8
8
  client ||= PrometheusExporter::Client.default
9
- Thread.new do
10
- while true
11
- begin
12
- client.send_json(resque_collector.collect)
13
- rescue => e
14
- client.logger.error("Prometheus Exporter Failed To Collect Resque Stats #{e}")
15
- ensure
16
- sleep frequency
17
- end
18
- end
9
+
10
+ worker_loop do
11
+ client.send_json(resque_collector.collect)
19
12
  end
13
+
14
+ super
20
15
  end
21
16
 
22
17
  def collect
@@ -1,22 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrometheusExporter::Instrumentation
4
- class SidekiqProcess
4
+ class SidekiqProcess < PeriodicStats
5
5
  def self.start(client: nil, frequency: 30)
6
6
  client ||= PrometheusExporter::Client.default
7
7
  sidekiq_process_collector = new
8
8
 
9
- Thread.new do
10
- loop do
11
- begin
12
- client.send_json(sidekiq_process_collector.collect)
13
- rescue StandardError => e
14
- STDERR.puts("Prometheus Exporter Failed To Collect Sidekiq Processes metrics #{e}")
15
- ensure
16
- sleep frequency
17
- end
18
- end
9
+ worker_loop do
10
+ client.send_json(sidekiq_process_collector.collect)
19
11
  end
12
+
13
+ super
20
14
  end
21
15
 
22
16
  def initialize
@@ -1,22 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrometheusExporter::Instrumentation
4
- class SidekiqQueue
4
+ class SidekiqQueue < PeriodicStats
5
5
  def self.start(client: nil, frequency: 30, all_queues: false)
6
6
  client ||= PrometheusExporter::Client.default
7
7
  sidekiq_queue_collector = new(all_queues: all_queues)
8
8
 
9
- Thread.new do
10
- loop do
11
- begin
12
- client.send_json(sidekiq_queue_collector.collect)
13
- rescue StandardError => e
14
- client.logger.error("Prometheus Exporter Failed To Collect Sidekiq Queue metrics #{e}")
15
- ensure
16
- sleep frequency
17
- end
18
- end
9
+ worker_loop do
10
+ client.send_json(sidekiq_queue_collector.collect)
19
11
  end
12
+
13
+ super
20
14
  end
21
15
 
22
16
  def initialize(all_queues: false)
@@ -1,22 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrometheusExporter::Instrumentation
4
- class SidekiqStats
4
+ class SidekiqStats < PeriodicStats
5
5
  def self.start(client: nil, frequency: 30)
6
6
  client ||= PrometheusExporter::Client.default
7
7
  sidekiq_stats_collector = new
8
8
 
9
- Thread.new do
10
- loop do
11
- begin
12
- client.send_json(sidekiq_stats_collector.collect)
13
- rescue StandardError => e
14
- STDERR.puts("Prometheus Exporter Failed To Collect Sidekiq Stats metrics #{e}")
15
- ensure
16
- sleep frequency
17
- end
18
- end
9
+ worker_loop do
10
+ client.send_json(sidekiq_stats_collector.collect)
19
11
  end
12
+
13
+ super
20
14
  end
21
15
 
22
16
  def collect
@@ -8,22 +8,17 @@ end
8
8
 
9
9
  module PrometheusExporter::Instrumentation
10
10
  # collects stats from unicorn
11
- class Unicorn
11
+ class Unicorn < PeriodicStats
12
12
  def self.start(pid_file:, listener_address:, client: nil, frequency: 30)
13
13
  unicorn_collector = new(pid_file: pid_file, listener_address: listener_address)
14
14
  client ||= PrometheusExporter::Client.default
15
- Thread.new do
16
- loop do
17
- begin
18
- metric = unicorn_collector.collect
19
- client.send_json metric
20
- rescue StandardError => e
21
- client.logger.error("Prometheus Exporter Failed To Collect Unicorn Stats #{e}")
22
- ensure
23
- sleep frequency
24
- end
25
- end
15
+
16
+ worker_loop do
17
+ metric = unicorn_collector.collect
18
+ client.send_json metric
26
19
  end
20
+
21
+ super
27
22
  end
28
23
 
29
24
  def initialize(pid_file:, listener_address:)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "client"
4
+ require_relative "instrumentation/periodic_stats"
4
5
  require_relative "instrumentation/process"
5
6
  require_relative "instrumentation/method_profiler"
6
7
  require_relative "instrumentation/sidekiq"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrometheusExporter
4
- VERSION = '2.0.0'
4
+ VERSION = '2.0.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prometheus_exporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-18 00:00:00.000000000 Z
11
+ date: 2022-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: webrick
@@ -238,6 +238,7 @@ files:
238
238
  - lib/prometheus_exporter/instrumentation/delayed_job.rb
239
239
  - lib/prometheus_exporter/instrumentation/hutch.rb
240
240
  - lib/prometheus_exporter/instrumentation/method_profiler.rb
241
+ - lib/prometheus_exporter/instrumentation/periodic_stats.rb
241
242
  - lib/prometheus_exporter/instrumentation/process.rb
242
243
  - lib/prometheus_exporter/instrumentation/puma.rb
243
244
  - lib/prometheus_exporter/instrumentation/resque.rb