prometheus_exporter 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 884ad6656dc8d2b784711db6e057cf9743cc93a4bb7d9bc978b06e90441978a1
4
- data.tar.gz: 34fbcbba98564562c49ea99dcffa95403224d6c85f372686426bed005d5a64e2
3
+ metadata.gz: 7725cb2b5d8846c874cd69d2ce92ca7a7fd2859ce9e6babe8cc86e96db9e3f2b
4
+ data.tar.gz: c08f9d1a4b18733c9a1c8882453bc40ffb7347ac5a71ccc972500334245aecba
5
5
  SHA512:
6
- metadata.gz: 243a116fd665dea9bb6b9ed2d350a07a3819b512be4320993caa4b3a1038987c9232b325ff605f9495b75c33626dab2a0ba56d7fd6b0f3119d23156086391c72
7
- data.tar.gz: 26630637bbcbfcd92d5c3ec3ccef0ffe9e88b1d8822e2df7c1e76aef9c0ae2bae730e4f6125dd9d169679cb8336f03e6129f0eeb7f2f6ad7e0aa6d3ec886c8aa
6
+ metadata.gz: 436ad9dcd8248147fb13ba1f0fc3d2e0b1badc113c41bc7ead07c560f984f32b7caa72fd4cfa1162209b525319574cfb962dff9dd092c2557fca39df2fbe1a8c
7
+ data.tar.gz: 9365bea75c02bc742514058cd7d66c077a8b0d49ce941a5067887cacd6a051ca28f86870c4456579f16101e98ea4d70733c08e8f9924ff8dead52be4b2c01d91
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ 0.3.4 - 02-10-2018
2
+
3
+ - Fix: custom collector via CLI was not working correctly
4
+
1
5
  0.3.3
2
6
 
3
7
  - Feature: Add more metrics to delayed job collector
data/README.md CHANGED
@@ -1,8 +1,32 @@
1
1
  # Prometheus Exporter
2
2
 
3
- Prometheus Exporter allows you to aggregate custom metrics from multiple processes and export to Prometheus.
3
+ Prometheus Exporter allows you to aggregate custom metrics from multiple processes and export to Prometheus. It provides a very flexible framework for handling Prometheus metrics and can operate in a single and multiprocess mode.
4
+
5
+ To learn more see [Instrumenting Rails with Prometheus](https://samsaffron.com/archive/2018/02/02/instrumenting-rails-with-prometheus) (it has pretty pictures!)
6
+
7
+ * [Requirements](#requirements)
8
+ * [Installation](#installation)
9
+ * [Usage](#usage)
10
+ * [Single process mode](#single-process-mode)
11
+ * [Multi process mode](#multi-process-mode)
12
+ * [Rails integration](#rails-integration)
13
+ * [Per-process stats](#per-process-stats)
14
+ * [Sidekiq metrics](#sidekiq-metrics)
15
+ * [Delayed Job plugin](#delayed-job-plugin)
16
+ * [Custom type collectors](#custom-type-collectors)
17
+ * [Multi process mode with custom collector](#multi-process-mode-with-custom-collector)
18
+ * [GraphQL support](#graphql-support)
19
+ * [Metrics default prefix / labels](#metrics-default-prefix--labels)
20
+ * [Client default labels](#client-default-labels)
21
+ * [Transport concerns](#transport-concerns)
22
+ * [JSON generation and parsing](#json-generation-and-parsing)
23
+ * [Contributing](#contributing)
24
+ * [License](#license)
25
+ * [Code of Conduct](#code-of-conduct)
26
+
27
+ ## Requirements
4
28
 
5
- It provides a very flexible framework for handling Prometheus metrics and can operate in a single and multiprocess mode.
29
+ Minimum Ruby of version 2.3.0 is required, Ruby 2.2.0 is EOL as of 2018-03-31
6
30
 
7
31
  ## Installation
8
32
 
@@ -20,19 +44,11 @@ Or install it yourself as:
20
44
 
21
45
  $ gem install prometheus_exporter
22
46
 
23
- ## Ruby Version
24
-
25
- Minimum Ruby of version 2.3.0 is required, Ruby 2.2.0 is EOL as of 2018-03-31
26
-
27
- ## Can I have some pretty pictures please?
28
-
29
- Sure, check out: [Instrumenting Rails with Prometheus](https://samsaffron.com/archive/2018/02/02/instrumenting-rails-with-prometheus)
30
-
31
47
  ## Usage
32
48
 
33
49
  ### Single process mode
34
50
 
35
- Simplest way of consuming Prometheus exporter is in a single process mode, to do so:
51
+ Simplest way of consuming Prometheus exporter is in a single process mode.
36
52
 
37
53
  ```ruby
38
54
  require 'prometheus_exporter/server'
@@ -65,19 +81,17 @@ summary.observe(0.12)
65
81
 
66
82
  ### Multi process mode
67
83
 
68
- In some cases, for example unicorn or puma clusters you may want to aggregate metrics across multiple processes.
84
+ In some cases (for example, unicorn or puma clusters) you may want to aggregate metrics across multiple processes.
69
85
 
70
- Simplest way to acheive this is use the built-in collector.
86
+ Simplest way to achieve this is to use the built-in collector.
71
87
 
72
- First, run an exporter on your desired port, we use the default port of 9394:
88
+ First, run an exporter on your desired port (we use the default port of 9394):
73
89
 
74
90
  ```
75
- # prometheus_exporter
91
+ $ prometheus_exporter
76
92
  ```
77
93
 
78
- At this point an exporter is running on port 9394
79
-
80
- In your application:
94
+ And in your application:
81
95
 
82
96
  ```ruby
83
97
  require 'prometheus_exporter/client'
@@ -92,8 +106,8 @@ gauge.observe(99, day: "friday")
92
106
 
93
107
  Then you will get the metrics:
94
108
 
95
- ```bash
96
- % curl localhost:9394/metrics
109
+ ```
110
+ $ curl localhost:9394/metrics
97
111
  # HELP collector_working Is the master process collector able to collect metrics
98
112
  # TYPE collector_working gauge
99
113
  collector_working 1
@@ -105,20 +119,18 @@ awesome 10
105
119
 
106
120
  ```
107
121
 
108
- ### Easy integration into Rails
122
+ ### Rails integration
109
123
 
110
- You can easily integrate into any Rack application:
124
+ You can easily integrate into any Rack application.
111
125
 
112
126
  In your Gemfile:
113
127
 
114
- ```
128
+ ```ruby
115
129
  gem 'prometheus_exporter'
116
130
  ```
117
131
 
118
-
132
+ In an initializer:
119
133
  ```ruby
120
- # in an initializer
121
-
122
134
  unless Rails.env == "test"
123
135
  require 'prometheus_exporter/middleware'
124
136
 
@@ -127,7 +139,15 @@ unless Rails.env == "test"
127
139
  end
128
140
  ```
129
141
 
130
- You may also be interested in per-process stats, this collects memory and GC stats
142
+ Ensure you run the exporter in a monitored background process:
143
+
144
+ ```
145
+ $ bundle exec prometheus_exporter
146
+ ```
147
+
148
+ #### Per-process stats
149
+
150
+ You may also be interested in per-process stats. This collects memory and GC stats:
131
151
 
132
152
  ```ruby
133
153
  # in an initializer
@@ -146,6 +166,8 @@ end
146
166
 
147
167
  ```
148
168
 
169
+ #### Sidekiq metrics
170
+
149
171
  Including Sidekiq metrics (how many jobs ran? how many failed? how long did they take?)
150
172
 
151
173
  ```ruby
@@ -157,7 +179,7 @@ Sidekiq.configure_server do |config|
157
179
  end
158
180
  ```
159
181
 
160
- To monitor Sidekiq process info
182
+ To monitor Sidekiq process info:
161
183
 
162
184
  ```ruby
163
185
  Sidekiq.configure_server do |config|
@@ -168,25 +190,20 @@ Sidekiq.configure_server do |config|
168
190
  end
169
191
  ```
170
192
 
171
- It also comes with a DelayedJob plugin.
193
+ #### Delayed Job plugin
194
+
195
+ In an initializer:
172
196
 
173
197
  ```ruby
174
- # in an initializer
175
198
  unless Rails.env == "test"
176
199
  require 'prometheus_exporter/instrumentation'
177
200
  PrometheusExporter::Instrumentation::DelayedJob.register_plugin
178
201
  end
179
202
  ```
180
203
 
181
- Ensure you run the exporter in a monitored background process via
182
-
183
- ```
184
- % bundle exec prometheus_exporter
185
- ```
186
-
187
204
  #### Instrumenting Request Queueing Time
188
205
 
189
- Request Queueing is defined as the time it takes for a request to reach your application (instrumented by this `prometheus_exporter`) from farther upstream (as your load balancer). A high queueing time usually means that your backend cannot handle all the incoming requests in time, so they queue up (= you should see if you need to add more capacity)
206
+ Request Queueing is defined as the time it takes for a request to reach your application (instrumented by this `prometheus_exporter`) from farther upstream (as your load balancer). A high queueing time usually means that your backend cannot handle all the incoming requests in time, so they queue up (= you should see if you need to add more capacity).
190
207
 
191
208
  As this metric starts before `prometheus_exporter` can handle the request, you must add a specific HTTP header as early in your infrastructure as possible (we recommend your load balancer or reverse proxy).
192
209
 
@@ -196,7 +213,7 @@ Hint: we aim to be API-compatible with the big APM solutions, so if you've got r
196
213
 
197
214
  ### Custom type collectors
198
215
 
199
- In some cases you may have custom metrics you want to ship the collector in a batch, in this case you may still be interested in the base collector behavior but would like to add your own special messages.
216
+ In some cases you may have custom metrics you want to ship the collector in a batch. In this case you may still be interested in the base collector behavior, but would like to add your own special messages.
200
217
 
201
218
  ```ruby
202
219
  # person_collector.rb
@@ -226,7 +243,7 @@ end
226
243
 
227
244
  Shipping metrics then is done via:
228
245
 
229
- ```
246
+ ```ruby
230
247
  PrometheusExporter::Client.default.send_json(type: "person", age: 40)
231
248
  ```
232
249
 
@@ -234,15 +251,14 @@ To load the custom collector run:
234
251
 
235
252
 
236
253
  ```
237
- bundle exec prometheus_exporter -a person_collector.rb
238
-
254
+ $ bundle exec prometheus_exporter -a person_collector.rb
239
255
  ```
240
256
 
241
257
  #### Global metrics in a custom type collector
242
258
 
243
- Custom type collectors are the ideal place to collect global metrics, such as user/article counts and connection counts. The custom type collector runs in the collector which usually runs in the prometheus exporter process.
259
+ Custom type collectors are the ideal place to collect global metrics, such as user/article counts and connection counts. The custom type collector runs in the collector, which usually runs in the prometheus exporter process.
244
260
 
245
- Out-of-the-box we try to keep the prometheus exporter as lean as possible, we do not load all the Rails dependencies so you will not have access to your models. You can always ensure it is loaded in your custom type collector with:
261
+ Out-of-the-box we try to keep the prometheus exporter as lean as possible. We do not load all Rails dependencies, so you won't have access to your models. You can always ensure it is loaded in your custom type collector with:
246
262
 
247
263
  ```ruby
248
264
  unless defined? Rails
@@ -260,8 +276,7 @@ def metrics
260
276
  end
261
277
  ```
262
278
 
263
- The metrics endpoint is called whenever prometheus calls the `/metrics` HTTP endpoint, it may make sense to introduce some caching so database calls are only performed once every N seconds. [lru_redux](https://github.com/SamSaffron/lru_redux) is the perfect gem for that kind of job as you can `LruRedux::TTL::Cache` which will automatically expire after N seconds.
264
-
279
+ The metrics endpoint is called whenever prometheus calls the `/metrics` HTTP endpoint, so it may make sense to introduce some type of caching. [lru_redux](https://github.com/SamSaffron/lru_redux) is the perfect gem for this job: you can use `LruRedux::TTL::Cache`, which will expire automatically after N seconds, thus saving multiple database queries.
265
280
 
266
281
  ### Multi process mode with custom collector
267
282
 
@@ -269,7 +284,7 @@ You can opt for custom collector logic in a multi process environment.
269
284
 
270
285
  This allows you to completely replace the collector logic.
271
286
 
272
- First, define a custom collector, it is critical you inherit off `PrometheusExporter::Server::Collector`, also it is critical you have custom implementations for #process and #prometheus_metrics_text
287
+ First, define a custom collector. It is important that you inherit off `PrometheusExporter::Server::CollectorBase` and have custom implementations for `#process` and `#prometheus_metrics_text` methods.
273
288
 
274
289
  ```ruby
275
290
  class MyCustomCollector < PrometheusExporter::Server::CollectorBase
@@ -302,11 +317,11 @@ end
302
317
 
303
318
  Next, launch the exporter process:
304
319
 
305
- ```bash
306
- % bin/prometheus_exporter --collector examples/custom_collector.rb
320
+ ```
321
+ $ bin/prometheus_exporter --collector examples/custom_collector.rb
307
322
  ```
308
323
 
309
- In your application ship it the metrics you want:
324
+ In your application send metrics you want:
310
325
 
311
326
  ```ruby
312
327
  require 'prometheus_exporter/client'
@@ -319,7 +334,7 @@ client.send_json(thing2: 12)
319
334
  Now your exporter will echo the metrics:
320
335
 
321
336
  ```
322
- % curl localhost:12345/metrics
337
+ $ curl localhost:12345/metrics
323
338
  # HELP collector_working Is the master process collector able to collect metrics
324
339
  # TYPE collector_working gauge
325
340
  collector_working 1
@@ -335,15 +350,13 @@ thing2 12
335
350
 
336
351
  ### GraphQL support
337
352
 
338
- GraphQL execution metrics are [supported](https://github.com/rmosolgo/graphql-ruby/blob/master/guides/queries/tracing.md#prometheus) and can be collected via the GraphQL
339
- collector, included in [graphql-ruby](https://github.com/rmosolgo/graphql-ruby)
340
-
353
+ GraphQL execution metrics are [supported](https://github.com/rmosolgo/graphql-ruby/blob/master/guides/queries/tracing.md#prometheus) and can be collected via the GraphQL collector, included in [graphql-ruby](https://github.com/rmosolgo/graphql-ruby).
341
354
 
342
355
  ### Metrics default prefix / labels
343
356
 
344
- _This only works in single process mode_
357
+ _This only works in single process mode._
345
358
 
346
- You can specify default prefix or labels for metrics, for example:
359
+ You can specify default prefix or labels for metrics. For example:
347
360
 
348
361
  ```ruby
349
362
  # Specify prefix for metric names
@@ -369,7 +382,7 @@ ruby_web_requests{hostname="app-server-01"} 1
369
382
 
370
383
  ### Client default labels
371
384
 
372
- You can specify a default label for the instrumentation metrics sent by an specific client, for example:
385
+ You can specify a default label for instrumentation metrics sent by a specific client. For example:
373
386
 
374
387
  ```ruby
375
388
  # Specify on intializing PrometheusExporter::Client
@@ -389,15 +402,15 @@ http_requests_total{service="app-server-01",app_name="app-01"} 1
389
402
 
390
403
  ## Transport concerns
391
404
 
392
- Prometheus Exporter handles transport using a simple HTTP protocol. In multi process mode we avoid needing a large number of HTTP request by using chunked encoding to send metrics. This means that a single HTTP channel can deliver 100s or even 1000s of metrics over a single HTTP session to the `/send-metrics` endpoint. All calls to `send` and `send_json` on the PrometheusExporter::Client class are **non-blocking** and batched.
405
+ Prometheus Exporter handles transport using a simple HTTP protocol. In multi process mode we avoid needing a large number of HTTP request by using chunked encoding to send metrics. This means that a single HTTP channel can deliver 100s or even 1000s of metrics over a single HTTP session to the `/send-metrics` endpoint. All calls to `send` and `send_json` on the `PrometheusExporter::Client` class are **non-blocking** and batched.
393
406
 
394
- The `/bench` directory has simple benchmark it is able to send through 10k messages in 500ms.
407
+ The `/bench` directory has simple benchmark, which is able to send through 10k messages in 500ms.
395
408
 
396
409
  ## JSON generation and parsing
397
410
 
398
- The `PrometheusExporter::Client` class has the method `#send-json`. This method, by default, will call `JSON.dump` on the Object it recieves. You may opt in for `oj` mode where it can use the faster `Oj.dump(obj, mode: :compat)` for JSON serialization. But be warned that if you have custom objects that implement own `to_json` methods this may not work as expected. You can opt for oj serialization with `json_serializer: :oj`
411
+ The `PrometheusExporter::Client` class has the method `#send-json`. This method, by default, will call `JSON.dump` on the Object it recieves. You may opt in for `oj` mode where it can use the faster `Oj.dump(obj, mode: :compat)` for JSON serialization. But be warned that if you have custom objects that implement own `to_json` methods this may not work as expected. You can opt for oj serialization with `json_serializer: :oj`.
399
412
 
400
- The `PrometheusExporter::Server::Collector` parses your JSON, by default it will use the faster Oj deserializer if availabe. This happens cause it only expects a simple Hash out of the box. You can opt in for the default JSON deserializer with `json_serializer: :json`
413
+ When `PrometheusExporter::Server::Collector` parses your JSON, by default it will use the faster Oj deserializer if available. This happens cause it only expects a simple Hash out of the box. You can opt in for the default JSON deserializer with `json_serializer: :json`.
401
414
 
402
415
  ## Contributing
403
416
 
@@ -409,4 +422,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
409
422
 
410
423
  ## Code of Conduct
411
424
 
412
- Everyone interacting in the PrometheusExporter project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/SamSaffron/prometheus_exporter/blob/master/CODE_OF_CONDUCT.md).
425
+ Everyone interacting in the PrometheusExporter project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/discourse/prometheus_exporter/blob/master/CODE_OF_CONDUCT.md).
@@ -48,6 +48,7 @@ def run
48
48
  ObjectSpace.each_object(Class) do |klass|
49
49
  if klass < base_klass && klass != base_klass
50
50
  options[:collector_class] = klass
51
+ found = true
51
52
  end
52
53
  end
53
54
 
@@ -13,15 +13,30 @@ class PrometheusExporter::Client
13
13
  @type = type
14
14
  end
15
15
 
16
- def observe(value = 1, keys = nil)
17
- @client.send_json(
16
+ def standard_values(value, keys, prometheus_exporter_action = nil)
17
+ values = {
18
18
  type: @type,
19
19
  help: @help,
20
20
  name: @name,
21
21
  keys: keys,
22
22
  value: value
23
- )
23
+ }
24
+ values[:prometheus_exporter_action] = prometheus_exporter_action if prometheus_exporter_action
25
+ values
24
26
  end
27
+
28
+ def observe(value = 1, keys = nil)
29
+ @client.send_json(standard_values(value, keys))
30
+ end
31
+
32
+ def increment(keys = nil, value = 1)
33
+ @client.send_json(standard_values(value, keys, :increment))
34
+ end
35
+
36
+ def decrement(keys = nil, value = 1)
37
+ @client.send_json(standard_values(value, keys, :decrement))
38
+ end
39
+
25
40
  end
26
41
 
27
42
  def self.default
@@ -22,5 +22,15 @@ module PrometheusExporter::Metric
22
22
  def observe(value, labels = {})
23
23
  @data[labels] = value
24
24
  end
25
+
26
+ def increment(labels = {}, value = 1)
27
+ @data[labels] ||= 0
28
+ @data[labels] += value
29
+ end
30
+
31
+ def decrement(labels = {}, value = 1)
32
+ @data[labels] ||= 0
33
+ @data[labels] -= value
34
+ end
25
35
  end
26
36
  end
@@ -46,7 +46,14 @@ module PrometheusExporter::Server
46
46
  if !metric
47
47
  metric = register_metric_unsafe(obj)
48
48
  end
49
- metric.observe(obj["value"], obj["keys"])
49
+ case obj["prometheus_exporter_action"]
50
+ when 'increment'
51
+ metric.increment(obj["keys"], obj["value"])
52
+ when 'decrement'
53
+ metric.decrement(obj["keys"], obj["value"])
54
+ else
55
+ metric.observe(obj["value"], obj["keys"])
56
+ end
50
57
  end
51
58
  end
52
59
  end
@@ -1,3 +1,3 @@
1
1
  module PrometheusExporter
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.4"
3
3
  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: 0.3.3
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-27 00:00:00.000000000 Z
11
+ date: 2018-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler