prometheus_exporter 0.4.17 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca59b198973bbfb5df6e5204f7a74138df05759f6a44839a60eaabd1d0d58697
4
- data.tar.gz: 384a5a138d1eb8c24ccc47984d6f6437bcced89f058cc55460bf3dcb60f326fb
3
+ metadata.gz: c77ede3528c6008266620498f698c8a0e9e17bfa0c0691fedf5a3c4c3bdb8ebd
4
+ data.tar.gz: 62f8b159f68036f05b785fea4eebef48df66606b083136eda5c37e4d3c294132
5
5
  SHA512:
6
- metadata.gz: 7406bf4ed7f65ee3dd243ac01294737292b721b9cd04f34a93b84200ad3259bc18ee8326aa8f5bea438a6ada13dab42453dd380e0fd2d34008378ecd8f581504
7
- data.tar.gz: 8834124a60121673f01023a2e564b3afb55f3977d2d0214cccc2b7fb201788c2b15650992c49402180e6468a7676278ce963a0bded8f2fcf6ccc9984937a9199
6
+ metadata.gz: 2c0699014753102b514f1bd6fa965cd82f6d83c34084daf4a3b07537b9224295a1df02aedce3082588e44f4c001e71ea83178456bd7efd8a8eae836b2fc6e9a7
7
+ data.tar.gz: df738517c22422ba9e4e2e7cfd6ea6bbcf7542175a827b1632e7ff69af4651d4acf45bcec9693c4dd899b9b305b952fac989999ebea23013f3ddad0d3c396e00
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ 0.5.0 - 14-02-2019
2
+
3
+ - Breaking change: listen only to localhost by default to prevent unintended insecure configuration
4
+ - FIX: Avoid calling `hostname` aggressively, instead cache it on the exporter instance
5
+
1
6
  0.4.17 - 13-01-2019
2
7
 
3
8
  - FEATURE: add support for `to_h` on all metrics which can be used to query existing key/values
data/README.md CHANGED
@@ -13,6 +13,7 @@ To learn more see [Instrumenting Rails with Prometheus](https://samsaffron.com/a
13
13
  * [Rails integration](#rails-integration)
14
14
  * [Per-process stats](#per-process-stats)
15
15
  * [Sidekiq metrics](#sidekiq-metrics)
16
+ * [Shoryuken metrics](#shoryuken-metrics)
16
17
  * [ActiveRecord Connection Pool Metrics](#activerecord-connection-pool-metrics)
17
18
  * [Delayed Job plugin](#delayed-job-plugin)
18
19
  * [Hutch metrics](#hutch-message-processing-tracer)
@@ -62,8 +63,9 @@ require 'prometheus_exporter/server'
62
63
  require 'prometheus_exporter/client'
63
64
  require 'prometheus_exporter/instrumentation'
64
65
 
66
+ # bind is the address, on which the webserver will listen
65
67
  # port is the port that will provide the /metrics route
66
- server = PrometheusExporter::Server::WebServer.new port: 12345
68
+ server = PrometheusExporter::Server::WebServer.new bind: 'localhost', port: 12345
67
69
  server.start
68
70
 
69
71
  # wire up a default local client
@@ -115,7 +117,7 @@ In some cases (for example, unicorn or puma clusters) you may want to aggregate
115
117
 
116
118
  Simplest way to achieve this is to use the built-in collector.
117
119
 
118
- First, run an exporter on your desired port (we use the default port of 9394):
120
+ First, run an exporter on your desired port (we use the default bind to localhost and port of 9394):
119
121
 
120
122
  ```
121
123
  $ prometheus_exporter
@@ -219,7 +221,7 @@ end
219
221
  For Unicorn / Passenger
220
222
 
221
223
  ```ruby
222
- after_fork do
224
+ after_fork do |_server, _worker|
223
225
  require 'prometheus_exporter/instrumentation'
224
226
  PrometheusExporter::Instrumentation::ActiveRecord.start(
225
227
  custom_labels: { type: "unicorn_worker" }, #optional params
@@ -297,6 +299,19 @@ Sometimes the Sidekiq server shuts down before it can send metrics, that were ge
297
299
  end
298
300
  ```
299
301
 
302
+ #### Shoryuken metrics
303
+
304
+ For Shoryuken metrics (how many jobs ran? how many failed? how long did they take? how many were restarted?)
305
+
306
+ ```ruby
307
+ Shoryuken.configure_server do |config|
308
+ config.server_middleware do |chain|
309
+ require 'prometheus_exporter/instrumentation'
310
+ chain.add PrometheusExporter::Instrumentation::Shoryuken
311
+ end
312
+ end
313
+ ```
314
+
300
315
  #### Delayed Job plugin
301
316
 
302
317
  In an initializer:
@@ -19,6 +19,12 @@ def run
19
19
  "Port exporter should listen on (default: #{PrometheusExporter::DEFAULT_PORT})") do |o|
20
20
  options[:port] = o.to_i
21
21
  end
22
+ opt.on('-b',
23
+ '--bind STRING',
24
+ String,
25
+ "IP address exporter should listen on (default: #{PrometheusExporter::DEFAULT_BIND_ADDRESS})") do |o|
26
+ options[:bind] = o.to_s
27
+ end
22
28
  opt.on('-t',
23
29
  '--timeout INTEGER',
24
30
  Integer,
@@ -81,7 +87,7 @@ def run
81
87
 
82
88
  runner = PrometheusExporter::Server::Runner.new(options)
83
89
 
84
- puts "#{Time.now} Starting prometheus exporter on port #{runner.port}"
90
+ puts "#{Time.now} Starting prometheus exporter on #{runner.bind}:#{runner.port}"
85
91
  runner.start
86
92
  sleep
87
93
  end
@@ -7,6 +7,7 @@ require "thread"
7
7
  module PrometheusExporter
8
8
  # per: https://github.com/prometheus/prometheus/wiki/Default-port-allocations
9
9
  DEFAULT_PORT = 9394
10
+ DEFAULT_BIND_ADDRESS = 'localhost'
10
11
  DEFAULT_PREFIX = 'ruby_'
11
12
  DEFAULT_TIMEOUT = 2
12
13
 
@@ -19,6 +20,17 @@ module PrometheusExporter
19
20
  end
20
21
  end
21
22
 
23
+ def self.hostname
24
+ @hostname ||=
25
+ begin
26
+ require 'socket'
27
+ Socket.gethostname
28
+ rescue => e
29
+ STDERR.puts "Unable to lookup hostname #{e}"
30
+ "unknown-host"
31
+ end
32
+ end
33
+
22
34
  def self.detect_json_serializer(preferred)
23
35
  if preferred.nil?
24
36
  preferred = :oj if has_oj?
@@ -9,3 +9,4 @@ require_relative "instrumentation/puma"
9
9
  require_relative "instrumentation/hutch"
10
10
  require_relative "instrumentation/unicorn"
11
11
  require_relative "instrumentation/active_record"
12
+ require_relative "instrumentation/shoryuken"
@@ -51,17 +51,6 @@ module PrometheusExporter::Instrumentation
51
51
  def initialize(metric_labels, config_labels)
52
52
  @metric_labels = metric_labels
53
53
  @config_labels = config_labels
54
- @hostname = nil
55
- end
56
-
57
- def hostname
58
- @hostname ||=
59
- begin
60
- `hostname`.strip
61
- rescue => e
62
- STDERR.puts "Unable to lookup hostname #{e}"
63
- "unknown-host"
64
- end
65
54
  end
66
55
 
67
56
  def collect
@@ -87,7 +76,7 @@ module PrometheusExporter::Instrumentation
87
76
  metric = {
88
77
  pid: pid,
89
78
  type: "active_record",
90
- hostname: hostname,
79
+ hostname: ::PrometheusExporter.hostname,
91
80
  metric_labels: labels
92
81
  }
93
82
  metric.merge!(pool.stat)
@@ -42,24 +42,13 @@ module PrometheusExporter::Instrumentation
42
42
 
43
43
  def initialize(metric_labels)
44
44
  @metric_labels = metric_labels
45
- @hostname = nil
46
- end
47
-
48
- def hostname
49
- @hostname ||=
50
- begin
51
- `hostname`.strip
52
- rescue => e
53
- STDERR.puts "Unable to lookup hostname #{e}"
54
- "unknown-host"
55
- end
56
45
  end
57
46
 
58
47
  def collect
59
48
  metric = {}
60
49
  metric[:type] = "process"
61
50
  metric[:metric_labels] = @metric_labels
62
- metric[:hostname] = hostname
51
+ metric[:hostname] = ::PrometheusExporter.hostname
63
52
  collect_gc_stats(metric)
64
53
  collect_v8_stats(metric)
65
54
  collect_process_stats(metric)
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrometheusExporter::Instrumentation
4
+ class Shoryuken
5
+
6
+ def initialize(client: nil)
7
+ @client = client || PrometheusExporter::Client.default
8
+ end
9
+
10
+ def call(worker, queue, msg, body)
11
+ success = false
12
+ start = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
13
+ result = yield
14
+ success = true
15
+ result
16
+ rescue ::Shoryuken::Shutdown => e
17
+ shutdown = true
18
+ raise e
19
+ ensure
20
+ duration = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - start
21
+ @client.send_json(
22
+ type: "shoryuken",
23
+ queue: queue,
24
+ name: worker.class.name,
25
+ success: success,
26
+ shutdown: shutdown,
27
+ duration: duration
28
+ )
29
+ end
30
+ end
31
+ end
@@ -14,3 +14,4 @@ require_relative "server/puma_collector"
14
14
  require_relative "server/hutch_collector"
15
15
  require_relative "server/unicorn_collector"
16
16
  require_relative "server/active_record_collector"
17
+ require_relative "server/shoryuken_collector"
@@ -18,6 +18,7 @@ module PrometheusExporter::Server
18
18
  register_collector(HutchCollector.new)
19
19
  register_collector(UnicornCollector.new)
20
20
  register_collector(ActiveRecordCollector.new)
21
+ register_collector(ShoryukenCollector.new)
21
22
  end
22
23
 
23
24
  def register_collector(collector)
@@ -32,69 +32,46 @@ module PrometheusExporter::Server
32
32
  )
33
33
  end
34
34
 
35
- server = server_class.new port: port, collector: collector, timeout: timeout, verbose: verbose
35
+ server = server_class.new port: port, bind: bind, collector: collector, timeout: timeout, verbose: verbose
36
36
  server.start
37
37
  end
38
38
 
39
- def prefix=(prefix)
40
- @prefix = prefix
41
- end
39
+ attr_accessor :unicorn_listen_address, :unicorn_pid_file
40
+ attr_writer :prefix, :port, :bind, :collector_class, :type_collectors, :timeout, :verbose, :server_class
42
41
 
43
42
  def prefix
44
43
  @prefix || PrometheusExporter::DEFAULT_PREFIX
45
44
  end
46
45
 
47
- def port=(port)
48
- @port = port
49
- end
50
-
51
46
  def port
52
47
  @port || PrometheusExporter::DEFAULT_PORT
53
48
  end
54
49
 
55
- def collector_class=(collector_class)
56
- @collector_class = collector_class
50
+ def bind
51
+ @bind || PrometheusExporter::DEFAULT_BIND_ADDRESS
57
52
  end
58
53
 
59
54
  def collector_class
60
55
  @collector_class || PrometheusExporter::Server::Collector
61
56
  end
62
57
 
63
- def type_collectors=(type_collectors)
64
- @type_collectors = type_collectors
65
- end
66
-
67
58
  def type_collectors
68
59
  @type_collectors || []
69
60
  end
70
61
 
71
- def timeout=(timeout)
72
- @timeout = timeout
73
- end
74
-
75
62
  def timeout
76
63
  @timeout || PrometheusExporter::DEFAULT_TIMEOUT
77
64
  end
78
65
 
79
- def verbose=(verbose)
80
- @verbose = verbose
81
- end
82
-
83
66
  def verbose
84
67
  return @verbose if defined? @verbose
85
68
  false
86
69
  end
87
70
 
88
- def server_class=(server_class)
89
- @server_class = server_class
90
- end
91
-
92
71
  def server_class
93
72
  @server_class || PrometheusExporter::Server::WebServer
94
73
  end
95
74
 
96
- attr_accessor :unicorn_listen_address, :unicorn_pid_file
97
-
98
75
  def collector
99
76
  @_collector ||= collector_class.new
100
77
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrometheusExporter::Server
4
+ class ShoryukenCollector < TypeCollector
5
+
6
+ def type
7
+ "shoryuken"
8
+ end
9
+
10
+ def collect(obj)
11
+ default_labels = { job_name: obj['name'] , queue_name: obj['queue'] }
12
+ custom_labels = obj['custom_labels']
13
+ labels = custom_labels.nil? ? default_labels : default_labels.merge(custom_labels)
14
+
15
+ ensure_shoryuken_metrics
16
+ @shoryuken_job_duration_seconds.observe(obj["duration"], labels)
17
+ @shoryuken_jobs_total.observe(1, labels)
18
+ @shoryuken_restarted_jobs_total.observe(1, labels) if obj["shutdown"]
19
+ @shoryuken_failed_jobs_total.observe(1, labels) if !obj["success"] && !obj["shutdown"]
20
+ end
21
+
22
+ def metrics
23
+ if @shoryuken_jobs_total
24
+ [
25
+ @shoryuken_job_duration_seconds,
26
+ @shoryuken_jobs_total,
27
+ @shoryuken_restarted_jobs_total,
28
+ @shoryuken_failed_jobs_total,
29
+ ]
30
+ else
31
+ []
32
+ end
33
+ end
34
+
35
+ protected
36
+
37
+ def ensure_shoryuken_metrics
38
+ if !@shoryuken_jobs_total
39
+
40
+ @shoryuken_job_duration_seconds =
41
+ PrometheusExporter::Metric::Counter.new(
42
+ "shoryuken_job_duration_seconds", "Total time spent in shoryuken jobs.")
43
+
44
+ @shoryuken_jobs_total =
45
+ PrometheusExporter::Metric::Counter.new(
46
+ "shoryuken_jobs_total", "Total number of shoryuken jobs executed.")
47
+
48
+ @shoryuken_restarted_jobs_total =
49
+ PrometheusExporter::Metric::Counter.new(
50
+ "shoryuken_restarted_jobs_total", "Total number of shoryuken jobs that we restarted because of a shoryuken shutdown.")
51
+
52
+ @shoryuken_failed_jobs_total =
53
+ PrometheusExporter::Metric::Counter.new(
54
+ "shoryuken_failed_jobs_total", "Total number of failed shoryuken jobs.")
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -9,7 +9,7 @@ module PrometheusExporter::Server
9
9
  class WebServer
10
10
  attr_reader :collector
11
11
 
12
- def initialize(port: , collector: nil, timeout: PrometheusExporter::DEFAULT_TIMEOUT, verbose: false)
12
+ def initialize(port: , bind: nil, collector: nil, timeout: PrometheusExporter::DEFAULT_TIMEOUT, verbose: false)
13
13
 
14
14
  @verbose = verbose
15
15
 
@@ -38,6 +38,7 @@ module PrometheusExporter::Server
38
38
 
39
39
  @server = WEBrick::HTTPServer.new(
40
40
  Port: port,
41
+ BindAddress: bind,
41
42
  Logger: logger,
42
43
  AccessLog: access_log,
43
44
  )
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrometheusExporter
4
- VERSION = "0.4.17"
4
+ VERSION = '0.5.0'
5
5
  end
@@ -5,22 +5,24 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require "prometheus_exporter/version"
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = "prometheus_exporter"
9
- spec.version = PrometheusExporter::VERSION
10
- spec.authors = ["Sam Saffron"]
11
- spec.email = ["sam.saffron@gmail.com"]
8
+ spec.name = "prometheus_exporter"
9
+ spec.version = PrometheusExporter::VERSION
10
+ spec.authors = ["Sam Saffron"]
11
+ spec.email = ["sam.saffron@gmail.com"]
12
12
 
13
- spec.summary = %q{Prometheus Exporter}
14
- spec.description = %q{Prometheus metric collector and exporter for Ruby}
15
- spec.homepage = "https://github.com/discourse/prometheus_exporter"
16
- spec.license = "MIT"
13
+ spec.summary = %q{Prometheus Exporter}
14
+ spec.description = %q{Prometheus metric collector and exporter for Ruby}
15
+ spec.homepage = "https://github.com/discourse/prometheus_exporter"
16
+ spec.license = "MIT"
17
17
 
18
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ spec.post_install_message = "prometheus_exporter will only bind to localhost by default as of v0.5"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
21
  f.match(%r{^(test|spec|features|bin)/})
20
22
  end
21
- spec.bindir = "bin"
22
- spec.executables = ["prometheus_exporter"]
23
- spec.require_paths = ["lib"]
23
+ spec.bindir = "bin"
24
+ spec.executables = ["prometheus_exporter"]
25
+ spec.require_paths = ["lib"]
24
26
 
25
27
  spec.add_development_dependency "rubocop", ">= 0.69"
26
28
  spec.add_development_dependency "bundler", "> 1.16"
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.4.17
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-13 00:00:00.000000000 Z
11
+ date: 2020-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -194,6 +194,7 @@ files:
194
194
  - lib/prometheus_exporter/instrumentation/method_profiler.rb
195
195
  - lib/prometheus_exporter/instrumentation/process.rb
196
196
  - lib/prometheus_exporter/instrumentation/puma.rb
197
+ - lib/prometheus_exporter/instrumentation/shoryuken.rb
197
198
  - lib/prometheus_exporter/instrumentation/sidekiq.rb
198
199
  - lib/prometheus_exporter/instrumentation/unicorn.rb
199
200
  - lib/prometheus_exporter/metric.rb
@@ -212,6 +213,7 @@ files:
212
213
  - lib/prometheus_exporter/server/process_collector.rb
213
214
  - lib/prometheus_exporter/server/puma_collector.rb
214
215
  - lib/prometheus_exporter/server/runner.rb
216
+ - lib/prometheus_exporter/server/shoryuken_collector.rb
215
217
  - lib/prometheus_exporter/server/sidekiq_collector.rb
216
218
  - lib/prometheus_exporter/server/type_collector.rb
217
219
  - lib/prometheus_exporter/server/unicorn_collector.rb
@@ -223,7 +225,8 @@ homepage: https://github.com/discourse/prometheus_exporter
223
225
  licenses:
224
226
  - MIT
225
227
  metadata: {}
226
- post_install_message:
228
+ post_install_message: prometheus_exporter will only bind to localhost by default as
229
+ of v0.5
227
230
  rdoc_options: []
228
231
  require_paths:
229
232
  - lib