prometheus-client 0.7.1 → 0.8.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
- SHA1:
3
- metadata.gz: 4982abb8d54bb0d71b55f1820ab738239646a2c2
4
- data.tar.gz: 6535ba6438d7a0dc66fdec16ff5cce28d7bf90c3
2
+ SHA256:
3
+ metadata.gz: e787d59357d442dc552623f434f3dd3d6ea9a842c249f96e8e3a9a9bed0bc9df
4
+ data.tar.gz: 2c53a0fcee4b3d1a6dc652c70c7cd3509833a6916368a33e20455d4b2b30a053
5
5
  SHA512:
6
- metadata.gz: 5361cb3d81d33e73ab5a8a51285144f4a066a49e2c21fe74b485eaacb21147a92d1415a38177e465e6a6dcfe25164c5929d5da19738f4c9a3c0f793625a57d52
7
- data.tar.gz: 11bf06c99b2c2618cfaaa0e4c4ddc19092d86252d6bb345c20392c0b17cfbba6c777f6e04445d82b5c3608057bcdf11760e3b4b28335ddb1ae69d69344e587e6
6
+ metadata.gz: b0abb64e501ba4e5d8e6e02e18e5d87ac22052d0f89fbca38c5baccc86b2dfc4a85a3d8a93c6bbe80b9ab9f1f06fadf8306cefc4d395414b3497f75e26128919
7
+ data.tar.gz: 816e8b3cb74368dfa5fc00db630d0a7b39830634459c174a72f268f546dc904fe8b86540435f1a78e65d51c6eb5d0d1f31e60d4d7f3a2d6745e3d665c498dddc
data/README.md CHANGED
@@ -48,7 +48,7 @@ require 'rack'
48
48
  require 'prometheus/middleware/collector'
49
49
  require 'prometheus/middleware/exporter'
50
50
 
51
- use Rack::Deflater, if: ->(_, _, _, body) { body.any? && body[0].length > 512 }
51
+ use Rack::Deflater
52
52
  use Prometheus::Middleware::Collector
53
53
  use Prometheus::Middleware::Exporter
54
54
 
@@ -66,29 +66,30 @@ integrated [example application](examples/rack/README.md).
66
66
  The Ruby client can also be used to push its collected metrics to a
67
67
  [Pushgateway][8]. This comes in handy with batch jobs or in other scenarios
68
68
  where it's not possible or feasible to let a Prometheus server scrape a Ruby
69
- process.
69
+ process. TLS and basic access authentication are supported.
70
+
71
+ **Attention**: The implementation still uses the legacy API of the pushgateway.
70
72
 
71
73
  ```ruby
72
74
  require 'prometheus/client'
73
75
  require 'prometheus/client/push'
74
76
 
75
- prometheus = Prometheus::Client.registry
77
+ registry = Prometheus::Client.registry
76
78
  # ... register some metrics, set/increment/observe/etc. their values
77
79
 
78
80
  # push the registry state to the default gateway
79
- Prometheus::Client::Push.new('my-batch-job').add(prometheus)
81
+ Prometheus::Client::Push.new('my-batch-job').add(registry)
80
82
 
81
- # optional: specify the instance name (instead of IP) and gateway
82
- Prometheus::Client::Push.new(
83
- 'my-job', 'instance-name', 'http://example.domain:1234').add(prometheus)
83
+ # optional: specify the instance name (instead of IP) and gateway.
84
+ Prometheus::Client::Push.new('my-batch-job', 'foobar', 'https://example.domain:1234').add(registry)
84
85
 
85
86
  # If you want to replace any previously pushed metrics for a given instance,
86
87
  # use the #replace method.
87
- Prometheus::Client::Push.new('my-batch-job', 'instance').replace(prometheus)
88
+ Prometheus::Client::Push.new('my-batch-job').replace(registry)
88
89
 
89
90
  # If you want to delete all previously pushed metrics for a given instance,
90
91
  # use the #delete method.
91
- Prometheus::Client::Push.new('my-batch-job', 'instance').delete
92
+ Prometheus::Client::Push.new('my-batch-job').delete
92
93
  ```
93
94
 
94
95
  ## Metrics
@@ -127,6 +128,14 @@ gauge.set({ room: 'kitchen' }, 21.534)
127
128
  # retrieve the current value for a given label set
128
129
  gauge.get({ room: 'kitchen' })
129
130
  # => 21.534
131
+
132
+ # increment the value (default is 1)
133
+ gauge.increment({ room: 'kitchen' })
134
+ # => 22.534
135
+
136
+ # decrement the value by a given value
137
+ gauge.decrement({ room: 'kitchen' }, 5)
138
+ # => 17.534
130
139
  ```
131
140
 
132
141
  ### Histogram
@@ -19,6 +19,26 @@ module Prometheus
19
19
 
20
20
  @values[label_set_for(labels)] = value.to_f
21
21
  end
22
+
23
+ # Increments Gauge value by 1 or adds the given value to the Gauge.
24
+ # (The value can be negative, resulting in a decrease of the Gauge.)
25
+ def increment(labels = {}, by = 1)
26
+ label_set = label_set_for(labels)
27
+ synchronize do
28
+ @values[label_set] ||= 0
29
+ @values[label_set] += by
30
+ end
31
+ end
32
+
33
+ # Decrements Gauge value by 1 or subtracts the given value from the Gauge.
34
+ # (The value can be negative, resulting in a increase of the Gauge.)
35
+ def decrement(labels = {}, by = 1)
36
+ label_set = label_set_for(labels)
37
+ synchronize do
38
+ @values[label_set] ||= 0
39
+ @values[label_set] -= by
40
+ end
41
+ end
22
42
  end
23
43
  end
24
44
  end
@@ -1,5 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'thread'
3
4
  require 'net/http'
4
5
  require 'uri'
5
6
 
@@ -15,31 +16,38 @@ module Prometheus
15
16
  DEFAULT_GATEWAY = 'http://localhost:9091'.freeze
16
17
  PATH = '/metrics/jobs/%s'.freeze
17
18
  INSTANCE_PATH = '/metrics/jobs/%s/instances/%s'.freeze
18
- HEADER = { 'Content-Type' => Formats::Text::CONTENT_TYPE }.freeze
19
19
  SUPPORTED_SCHEMES = %w(http https).freeze
20
20
 
21
21
  attr_reader :job, :instance, :gateway, :path
22
22
 
23
23
  def initialize(job, instance = nil, gateway = nil)
24
+ @mutex = Mutex.new
24
25
  @job = job
25
26
  @instance = instance
26
27
  @gateway = gateway || DEFAULT_GATEWAY
27
- @uri = parse(@gateway)
28
28
  @path = build_path(job, instance)
29
+ @uri = parse("#{@gateway}#{@path}")
30
+
29
31
  @http = Net::HTTP.new(@uri.host, @uri.port)
30
- @http.use_ssl = @uri.scheme == 'https'
32
+ @http.use_ssl = (@uri.scheme == 'https')
31
33
  end
32
34
 
33
35
  def add(registry)
34
- request('POST', registry)
36
+ synchronize do
37
+ request(Net::HTTP::Post, registry)
38
+ end
35
39
  end
36
40
 
37
41
  def replace(registry)
38
- request('PUT', registry)
42
+ synchronize do
43
+ request(Net::HTTP::Put, registry)
44
+ end
39
45
  end
40
46
 
41
47
  def delete
42
- @http.send_request('DELETE', path)
48
+ synchronize do
49
+ request(Net::HTTP::Delete)
50
+ end
43
51
  end
44
52
 
45
53
  private
@@ -64,10 +72,17 @@ module Prometheus
64
72
  end
65
73
  end
66
74
 
67
- def request(method, registry)
68
- data = Formats::Text.marshal(registry)
75
+ def request(req_class, registry = nil)
76
+ req = req_class.new(@uri)
77
+ req.content_type = Formats::Text::CONTENT_TYPE
78
+ req.basic_auth(@uri.user, @uri.password) if @uri.user
79
+ req.body = Formats::Text.marshal(registry) if registry
80
+
81
+ @http.request(req)
82
+ end
69
83
 
70
- @http.send_request(method, path, data, HEADER)
84
+ def synchronize
85
+ @mutex.synchronize { yield }
71
86
  end
72
87
  end
73
88
  end
@@ -31,6 +31,12 @@ module Prometheus
31
31
  metric
32
32
  end
33
33
 
34
+ def unregister(name)
35
+ @mutex.synchronize do
36
+ @metrics.delete(name.to_sym)
37
+ end
38
+ end
39
+
34
40
  def counter(name, docstring, base_labels = {})
35
41
  register(Counter.new(name, docstring, base_labels))
36
42
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Prometheus
4
4
  module Client
5
- VERSION = '0.7.1'
5
+ VERSION = '0.8.0'
6
6
  end
7
7
  end
@@ -1,5 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'benchmark'
3
4
  require 'prometheus/client'
4
5
 
5
6
  module Prometheus
@@ -10,6 +11,9 @@ module Prometheus
10
11
  # By default metrics are registered on the global registry. Set the
11
12
  # `:registry` option to use a custom registry.
12
13
  #
14
+ # By default metrics all have the prefix "http_server". Set to something
15
+ # else if you like.
16
+ #
13
17
  # The request counter metric is broken down by code, method and path by
14
18
  # default. Set the `:counter_label_builder` option to use a custom label
15
19
  # builder.
@@ -22,6 +26,7 @@ module Prometheus
22
26
  def initialize(app, options = {})
23
27
  @app = app
24
28
  @registry = options[:registry] || Client.registry
29
+ @metrics_prefix = options[:metrics_prefix] || 'http_server'
25
30
  @counter_lb = options[:counter_label_builder] || COUNTER_LB
26
31
  @duration_lb = options[:duration_label_builder] || DURATION_LB
27
32
 
@@ -35,45 +40,50 @@ module Prometheus
35
40
 
36
41
  protected
37
42
 
43
+ aggregation = lambda do |str|
44
+ str
45
+ .gsub(%r{/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(/|$)}, '/:uuid\\1')
46
+ .gsub(%r{/\d+(/|$)}, '/:id\\1')
47
+ end
48
+
38
49
  COUNTER_LB = proc do |env, code|
39
50
  {
40
51
  code: code,
41
52
  method: env['REQUEST_METHOD'].downcase,
42
- path: env['PATH_INFO'].to_s,
53
+ path: aggregation.call(env['PATH_INFO']),
43
54
  }
44
55
  end
45
56
 
46
57
  DURATION_LB = proc do |env, _|
47
58
  {
48
59
  method: env['REQUEST_METHOD'].downcase,
49
- path: env['PATH_INFO'].to_s,
60
+ path: aggregation.call(env['PATH_INFO']),
50
61
  }
51
62
  end
52
63
 
53
64
  def init_request_metrics
54
65
  @requests = @registry.counter(
55
- :http_server_requests_total,
66
+ :"#{@metrics_prefix}_requests_total",
56
67
  'The total number of HTTP requests handled by the Rack application.',
57
68
  )
58
69
  @durations = @registry.histogram(
59
- :http_server_request_duration_seconds,
70
+ :"#{@metrics_prefix}_request_duration_seconds",
60
71
  'The HTTP response duration of the Rack application.',
61
72
  )
62
73
  end
63
74
 
64
75
  def init_exception_metrics
65
76
  @exceptions = @registry.counter(
66
- :http_server_exceptions_total,
77
+ :"#{@metrics_prefix}_exceptions_total",
67
78
  'The total number of exceptions raised by the Rack application.',
68
79
  )
69
80
  end
70
81
 
71
82
  def trace(env)
72
- start = Time.now
73
- yield.tap do |response|
74
- duration = [(Time.now - start).to_f, 0.0].max
75
- record(env, response.first.to_s, duration)
76
- end
83
+ response = nil
84
+ duration = Benchmark.realtime { response = yield }
85
+ record(env, response.first.to_s, duration)
86
+ return response
77
87
  rescue => exception
78
88
  @exceptions.increment(exception: exception.class.name)
79
89
  raise
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prometheus-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Schmidt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-24 00:00:00.000000000 Z
11
+ date: 2018-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: quantile
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.0
19
+ version: 0.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.0
26
+ version: 0.2.1
27
27
  description:
28
28
  email:
29
29
  - ts@soundcloud.com
@@ -66,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
66
  version: '0'
67
67
  requirements: []
68
68
  rubyforge_project:
69
- rubygems_version: 2.6.11
69
+ rubygems_version: 2.7.6
70
70
  signing_key:
71
71
  specification_version: 4
72
72
  summary: A suite of instrumentation metric primitivesthat can be exposed through a