prometheus_exporter 0.8.0 → 2.0.0

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +36 -25
  3. data/CHANGELOG +51 -26
  4. data/README.md +151 -52
  5. data/bin/prometheus_exporter +19 -6
  6. data/lib/prometheus_exporter/client.rb +13 -6
  7. data/lib/prometheus_exporter/instrumentation/active_record.rb +5 -5
  8. data/lib/prometheus_exporter/instrumentation/process.rb +1 -1
  9. data/lib/prometheus_exporter/instrumentation/puma.rb +12 -12
  10. data/lib/prometheus_exporter/instrumentation/resque.rb +7 -7
  11. data/lib/prometheus_exporter/instrumentation/sidekiq.rb +27 -7
  12. data/lib/prometheus_exporter/instrumentation/sidekiq_process.rb +58 -0
  13. data/lib/prometheus_exporter/instrumentation/sidekiq_queue.rb +27 -13
  14. data/lib/prometheus_exporter/instrumentation/sidekiq_stats.rb +43 -0
  15. data/lib/prometheus_exporter/instrumentation/unicorn.rb +4 -4
  16. data/lib/prometheus_exporter/instrumentation.rb +2 -0
  17. data/lib/prometheus_exporter/metric/base.rb +11 -9
  18. data/lib/prometheus_exporter/metric/gauge.rb +4 -0
  19. data/lib/prometheus_exporter/metric/histogram.rb +13 -1
  20. data/lib/prometheus_exporter/middleware.rb +8 -4
  21. data/lib/prometheus_exporter/server/collector.rb +2 -0
  22. data/lib/prometheus_exporter/server/delayed_job_collector.rb +17 -18
  23. data/lib/prometheus_exporter/server/puma_collector.rb +7 -7
  24. data/lib/prometheus_exporter/server/resque_collector.rb +6 -6
  25. data/lib/prometheus_exporter/server/runner.rb +11 -2
  26. data/lib/prometheus_exporter/server/sidekiq_collector.rb +1 -1
  27. data/lib/prometheus_exporter/server/sidekiq_process_collector.rb +46 -0
  28. data/lib/prometheus_exporter/server/sidekiq_queue_collector.rb +1 -1
  29. data/lib/prometheus_exporter/server/sidekiq_stats_collector.rb +46 -0
  30. data/lib/prometheus_exporter/server/unicorn_collector.rb +3 -3
  31. data/lib/prometheus_exporter/server/web_collector.rb +17 -17
  32. data/lib/prometheus_exporter/server/web_server.rb +6 -8
  33. data/lib/prometheus_exporter/server.rb +2 -0
  34. data/lib/prometheus_exporter/version.rb +1 -1
  35. data/prometheus_exporter.gemspec +1 -1
  36. metadata +10 -6
@@ -4,13 +4,13 @@ module PrometheusExporter::Server
4
4
  class PumaCollector < TypeCollector
5
5
  MAX_PUMA_METRIC_AGE = 30
6
6
  PUMA_GAUGES = {
7
- workers_total: "Number of puma workers.",
8
- booted_workers_total: "Number of puma workers booted.",
9
- old_workers_total: "Number of old puma workers.",
10
- running_threads_total: "Number of puma threads currently running.",
11
- request_backlog_total: "Number of requests waiting to be processed by a puma thread.",
12
- thread_pool_capacity_total: "Number of puma threads available at current scale.",
13
- max_threads_total: "Number of puma threads at available at max scale.",
7
+ workers: "Number of puma workers.",
8
+ booted_workers: "Number of puma workers booted.",
9
+ old_workers: "Number of old puma workers.",
10
+ running_threads: "Number of puma threads currently running.",
11
+ request_backlog: "Number of requests waiting to be processed by a puma thread.",
12
+ thread_pool_capacity: "Number of puma threads available at current scale.",
13
+ max_threads: "Number of puma threads at available at max scale.",
14
14
  }
15
15
 
16
16
  def initialize
@@ -4,12 +4,12 @@ module PrometheusExporter::Server
4
4
  class ResqueCollector < TypeCollector
5
5
  MAX_RESQUE_METRIC_AGE = 30
6
6
  RESQUE_GAUGES = {
7
- processed_jobs_total: "Total number of processed Resque jobs.",
8
- failed_jobs_total: "Total number of failed Resque jobs.",
9
- pending_jobs_total: "Total number of pending Resque jobs.",
10
- queues_total: "Total number of Resque queues.",
11
- workers_total: "Total number of Resque workers running.",
12
- working_total: "Total number of Resque workers working."
7
+ processed_jobs: "Total number of processed Resque jobs.",
8
+ failed_jobs: "Total number of failed Resque jobs.",
9
+ pending_jobs: "Total number of pending Resque jobs.",
10
+ queues: "Total number of Resque queues.",
11
+ workers: "Total number of Resque workers running.",
12
+ working: "Total number of Resque workers working."
13
13
  }
14
14
 
15
15
  def initialize
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'prometheus_exporter/client'
3
+ require_relative '../client'
4
4
  require_relative '../instrumentation/unicorn'
5
5
 
6
6
  module PrometheusExporter::Server
@@ -17,6 +17,7 @@ module PrometheusExporter::Server
17
17
  @prefix = nil
18
18
  @auth = nil
19
19
  @realm = nil
20
+ @histogram = nil
20
21
 
21
22
  options.each do |k, v|
22
23
  send("#{k}=", v) if self.class.method_defined?("#{k}=")
@@ -27,6 +28,10 @@ module PrometheusExporter::Server
27
28
  PrometheusExporter::Metric::Base.default_prefix = prefix
28
29
  PrometheusExporter::Metric::Base.default_labels = label
29
30
 
31
+ if histogram
32
+ PrometheusExporter::Metric::Base.default_aggregation = PrometheusExporter::Metric::Histogram
33
+ end
34
+
30
35
  register_type_collectors
31
36
 
32
37
  unless collector.is_a?(PrometheusExporter::Server::CollectorBase)
@@ -47,7 +52,7 @@ module PrometheusExporter::Server
47
52
  end
48
53
 
49
54
  attr_accessor :unicorn_listen_address, :unicorn_pid_file
50
- attr_writer :prefix, :port, :bind, :collector_class, :type_collectors, :timeout, :verbose, :server_class, :label, :auth, :realm
55
+ attr_writer :prefix, :port, :bind, :collector_class, :type_collectors, :timeout, :verbose, :server_class, :label, :auth, :realm, :histogram
51
56
 
52
57
  def auth
53
58
  @auth || nil
@@ -98,6 +103,10 @@ module PrometheusExporter::Server
98
103
  @label ||= PrometheusExporter::DEFAULT_LABEL
99
104
  end
100
105
 
106
+ def histogram
107
+ @histogram || false
108
+ end
109
+
101
110
  private
102
111
 
103
112
  def register_type_collectors
@@ -52,7 +52,7 @@ module PrometheusExporter::Server
52
52
  if !@sidekiq_jobs_total
53
53
 
54
54
  @sidekiq_job_duration_seconds =
55
- PrometheusExporter::Metric::Summary.new(
55
+ PrometheusExporter::Metric::Base.default_aggregation.new(
56
56
  "sidekiq_job_duration_seconds", "Total time spent in sidekiq jobs.")
57
57
 
58
58
  @sidekiq_jobs_total =
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrometheusExporter::Server
4
+ class SidekiqProcessCollector < PrometheusExporter::Server::TypeCollector
5
+ MAX_SIDEKIQ_METRIC_AGE = 60
6
+
7
+ SIDEKIQ_PROCESS_GAUGES = {
8
+ 'busy' => 'Number of running jobs',
9
+ 'concurrency' => 'Maximum concurrency',
10
+ }.freeze
11
+
12
+ attr_reader :sidekiq_metrics, :gauges
13
+
14
+ def initialize
15
+ @sidekiq_metrics = []
16
+ @gauges = {}
17
+ end
18
+
19
+ def type
20
+ 'sidekiq_process'
21
+ end
22
+
23
+ def metrics
24
+ sidekiq_metrics.map do |metric|
25
+ labels = metric.fetch('labels', {})
26
+ SIDEKIQ_PROCESS_GAUGES.map do |name, help|
27
+ if (value = metric[name])
28
+ gauge = gauges[name] ||= PrometheusExporter::Metric::Gauge.new("sidekiq_process_#{name}", help)
29
+ gauge.observe(value, labels)
30
+ end
31
+ end
32
+ end
33
+
34
+ gauges.values
35
+ end
36
+
37
+ def collect(object)
38
+ now = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
39
+ process = object['process']
40
+
41
+ process["created_at"] = now
42
+ sidekiq_metrics.delete_if { |metric| metric['created_at'] + MAX_SIDEKIQ_METRIC_AGE < now }
43
+ sidekiq_metrics << process
44
+ end
45
+ end
46
+ end
@@ -4,7 +4,7 @@ module PrometheusExporter::Server
4
4
  MAX_SIDEKIQ_METRIC_AGE = 60
5
5
 
6
6
  SIDEKIQ_QUEUE_GAUGES = {
7
- 'backlog_total' => 'Size of the sidekiq queue.',
7
+ 'backlog' => 'Size of the sidekiq queue.',
8
8
  'latency_seconds' => 'Latency of the sidekiq queue.',
9
9
  }.freeze
10
10
 
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrometheusExporter::Server
4
+ class SidekiqStatsCollector < TypeCollector
5
+ MAX_SIDEKIQ_METRIC_AGE = 60
6
+
7
+ SIDEKIQ_STATS_GAUGES = {
8
+ 'dead_size' => 'Size of dead the queue',
9
+ 'enqueued' => 'Number of enqueued jobs',
10
+ 'failed' => 'Number of failed jobs',
11
+ 'processed' => 'Total number of processed jobs',
12
+ 'processes_size' => 'Number of processes',
13
+ 'retry_size' => 'Size of the retries queue',
14
+ 'scheduled_size' => 'Size of the scheduled queue',
15
+ 'workers_size' => 'Number of jobs actively being processed',
16
+ }.freeze
17
+
18
+ attr_reader :sidekiq_metrics, :gauges
19
+
20
+ def initialize
21
+ @sidekiq_metrics = []
22
+ @gauges = {}
23
+ end
24
+
25
+ def type
26
+ 'sidekiq_stats'
27
+ end
28
+
29
+ def metrics
30
+ sidekiq_metrics.map do |metric|
31
+ SIDEKIQ_STATS_GAUGES.map do |name, help|
32
+ if (value = metric['stats'][name])
33
+ gauge = gauges[name] ||= PrometheusExporter::Metric::Gauge.new("sidekiq_stats_#{name}", help)
34
+ gauge.observe(value)
35
+ end
36
+ end
37
+ end
38
+
39
+ gauges.values
40
+ end
41
+
42
+ def collect(object)
43
+ sidekiq_metrics << object
44
+ end
45
+ end
46
+ end
@@ -6,9 +6,9 @@ class PrometheusExporter::Server::UnicornCollector < PrometheusExporter::Server:
6
6
  MAX_UNICORN_METRIC_AGE = 60
7
7
 
8
8
  UNICORN_GAUGES = {
9
- workers_total: 'Number of unicorn workers.',
10
- active_workers_total: 'Number of active unicorn workers',
11
- request_backlog_total: 'Number of requests waiting to be processed by a unicorn worker.'
9
+ workers: 'Number of unicorn workers.',
10
+ active_workers: 'Number of active unicorn workers',
11
+ request_backlog: 'Number of requests waiting to be processed by a unicorn worker.'
12
12
  }.freeze
13
13
 
14
14
  def initialize
@@ -5,10 +5,10 @@ module PrometheusExporter::Server
5
5
  def initialize
6
6
  @metrics = {}
7
7
  @http_requests_total = nil
8
- @http_duration_seconds = nil
9
- @http_redis_duration_seconds = nil
10
- @http_sql_duration_seconds = nil
11
- @http_queue_duration_seconds = nil
8
+ @http_request_duration_seconds = nil
9
+ @http_request_redis_duration_seconds = nil
10
+ @http_request_sql_duration_seconds = nil
11
+ @http_request_queue_duration_seconds = nil
12
12
  end
13
13
 
14
14
  def type
@@ -33,23 +33,23 @@ module PrometheusExporter::Server
33
33
  "Total HTTP requests from web app."
34
34
  )
35
35
 
36
- @metrics["http_duration_seconds"] = @http_duration_seconds = PrometheusExporter::Metric::Summary.new(
37
- "http_duration_seconds",
36
+ @metrics["http_request_duration_seconds"] = @http_request_duration_seconds = PrometheusExporter::Metric::Base.default_aggregation.new(
37
+ "http_request_duration_seconds",
38
38
  "Time spent in HTTP reqs in seconds."
39
39
  )
40
40
 
41
- @metrics["http_redis_duration_seconds"] = @http_redis_duration_seconds = PrometheusExporter::Metric::Summary.new(
42
- "http_redis_duration_seconds",
41
+ @metrics["http_request_redis_duration_seconds"] = @http_request_redis_duration_seconds = PrometheusExporter::Metric::Base.default_aggregation.new(
42
+ "http_request_redis_duration_seconds",
43
43
  "Time spent in HTTP reqs in Redis, in seconds."
44
44
  )
45
45
 
46
- @metrics["http_sql_duration_seconds"] = @http_sql_duration_seconds = PrometheusExporter::Metric::Summary.new(
47
- "http_sql_duration_seconds",
46
+ @metrics["http_request_sql_duration_seconds"] = @http_request_sql_duration_seconds = PrometheusExporter::Metric::Base.default_aggregation.new(
47
+ "http_request_sql_duration_seconds",
48
48
  "Time spent in HTTP reqs in SQL in seconds."
49
49
  )
50
50
 
51
- @metrics["http_queue_duration_seconds"] = @http_queue_duration_seconds = PrometheusExporter::Metric::Summary.new(
52
- "http_queue_duration_seconds",
51
+ @metrics["http_request_queue_duration_seconds"] = @http_request_queue_duration_seconds = PrometheusExporter::Metric::Base.default_aggregation.new(
52
+ "http_request_queue_duration_seconds",
53
53
  "Time spent queueing the request in load balancer in seconds."
54
54
  )
55
55
  end
@@ -60,19 +60,19 @@ module PrometheusExporter::Server
60
60
  custom_labels = obj['custom_labels']
61
61
  labels = custom_labels.nil? ? default_labels : default_labels.merge(custom_labels)
62
62
 
63
- @http_requests_total.observe(1, labels)
63
+ @http_requests_total.observe(1, labels.merge(status: obj["status"]))
64
64
 
65
65
  if timings = obj["timings"]
66
- @http_duration_seconds.observe(timings["total_duration"], labels)
66
+ @http_request_duration_seconds.observe(timings["total_duration"], labels)
67
67
  if redis = timings["redis"]
68
- @http_redis_duration_seconds.observe(redis["duration"], labels)
68
+ @http_request_redis_duration_seconds.observe(redis["duration"], labels)
69
69
  end
70
70
  if sql = timings["sql"]
71
- @http_sql_duration_seconds.observe(sql["duration"], labels)
71
+ @http_request_sql_duration_seconds.observe(sql["duration"], labels)
72
72
  end
73
73
  end
74
74
  if queue_time = obj["queue_time"]
75
- @http_queue_duration_seconds.observe(queue_time, labels)
75
+ @http_request_queue_duration_seconds.observe(queue_time, labels)
76
76
  end
77
77
  end
78
78
  end
@@ -29,16 +29,17 @@ module PrometheusExporter::Server
29
29
  @bad_metrics_total.observe(0)
30
30
 
31
31
  @access_log, @logger = nil
32
+ log_target = opts[:log_target]
32
33
 
33
34
  if @verbose
34
35
  @access_log = [
35
36
  [$stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT],
36
37
  [$stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT],
37
38
  ]
38
- @logger = WEBrick::Log.new($stderr)
39
+ @logger = WEBrick::Log.new(log_target || $stderr)
39
40
  else
40
41
  @access_log = []
41
- @logger = WEBrick::Log.new("/dev/null")
42
+ @logger = WEBrick::Log.new(log_target || "/dev/null")
42
43
  end
43
44
 
44
45
  @logger.info "Using Basic Authentication via #{@auth}" if @verbose && @auth
@@ -87,10 +88,7 @@ module PrometheusExporter::Server
87
88
  @collector.process(block)
88
89
  rescue => e
89
90
  if @verbose
90
- STDERR.puts
91
- STDERR.puts e.inspect
92
- STDERR.puts e.backtrace
93
- STDERR.puts
91
+ @logger.error "\n\n#{e.inspect}\n#{e.backtrace}\n\n"
94
92
  end
95
93
  @bad_metrics_total.observe
96
94
  res.body = "Bad Metrics #{e}"
@@ -108,7 +106,7 @@ module PrometheusExporter::Server
108
106
  begin
109
107
  @server.start
110
108
  rescue => e
111
- STDERR.puts "Failed to start prometheus collector web on port #{@port}: #{e}"
109
+ @logger.error "Failed to start prometheus collector web on port #{@port}: #{e}"
112
110
  end
113
111
  end
114
112
  end
@@ -125,7 +123,7 @@ module PrometheusExporter::Server
125
123
  end
126
124
  rescue Timeout::Error
127
125
  # we timed out ... bummer
128
- STDERR.puts "Generating Prometheus metrics text timed out"
126
+ @logger.error "Generating Prometheus metrics text timed out"
129
127
  end
130
128
 
131
129
  metrics = []
@@ -6,6 +6,8 @@ require_relative "server/web_collector"
6
6
  require_relative "server/process_collector"
7
7
  require_relative "server/sidekiq_collector"
8
8
  require_relative "server/sidekiq_queue_collector"
9
+ require_relative "server/sidekiq_process_collector"
10
+ require_relative "server/sidekiq_stats_collector"
9
11
  require_relative "server/delayed_job_collector"
10
12
  require_relative "server/collector_base"
11
13
  require_relative "server/collector"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrometheusExporter
4
- VERSION = '0.8.0'
4
+ VERSION = '2.0.0'
5
5
  end
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "rake", "~> 13.0"
32
32
  spec.add_development_dependency "minitest", "~> 5.0"
33
33
  spec.add_development_dependency "guard", "~> 2.0"
34
- spec.add_development_dependency "mini_racer", "~> 0.3.1"
34
+ spec.add_development_dependency "mini_racer", "~> 0.5.0"
35
35
  spec.add_development_dependency "guard-minitest", "~> 2.0"
36
36
  spec.add_development_dependency "oj", "~> 3.0"
37
37
  spec.add_development_dependency "rack-test", "~> 0.8.3"
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: 0.8.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-05 00:00:00.000000000 Z
11
+ date: 2022-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: webrick
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.3.1
103
+ version: 0.5.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.3.1
110
+ version: 0.5.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: guard-minitest
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -243,7 +243,9 @@ files:
243
243
  - lib/prometheus_exporter/instrumentation/resque.rb
244
244
  - lib/prometheus_exporter/instrumentation/shoryuken.rb
245
245
  - lib/prometheus_exporter/instrumentation/sidekiq.rb
246
+ - lib/prometheus_exporter/instrumentation/sidekiq_process.rb
246
247
  - lib/prometheus_exporter/instrumentation/sidekiq_queue.rb
248
+ - lib/prometheus_exporter/instrumentation/sidekiq_stats.rb
247
249
  - lib/prometheus_exporter/instrumentation/unicorn.rb
248
250
  - lib/prometheus_exporter/metric.rb
249
251
  - lib/prometheus_exporter/metric/base.rb
@@ -264,7 +266,9 @@ files:
264
266
  - lib/prometheus_exporter/server/runner.rb
265
267
  - lib/prometheus_exporter/server/shoryuken_collector.rb
266
268
  - lib/prometheus_exporter/server/sidekiq_collector.rb
269
+ - lib/prometheus_exporter/server/sidekiq_process_collector.rb
267
270
  - lib/prometheus_exporter/server/sidekiq_queue_collector.rb
271
+ - lib/prometheus_exporter/server/sidekiq_stats_collector.rb
268
272
  - lib/prometheus_exporter/server/type_collector.rb
269
273
  - lib/prometheus_exporter/server/unicorn_collector.rb
270
274
  - lib/prometheus_exporter/server/web_collector.rb
@@ -292,7 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
292
296
  version: '0'
293
297
  requirements: []
294
298
  rubygems_version: 3.1.6
295
- signing_key:
299
+ signing_key:
296
300
  specification_version: 4
297
301
  summary: Prometheus Exporter
298
302
  test_files: []