fluent-plugin-prometheus 2.0.3 → 2.1.0

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: 21b4b3d81d41fadb057a133293f2629b39961faaadcb7caebbd885c10ed344d1
4
- data.tar.gz: dbd8aa719306aa164f373c781f568b82bee27fc44bfc88e86c4ea5d31c5ce545
3
+ metadata.gz: 366793cd93075c7e1d63cb2641d2654f5eef5304aaa1293bb9e1dabed7d93e2f
4
+ data.tar.gz: 4db5c9fc80dcf10b013239bfdb6e098b53bf26c34a135f944850c70d2a36b7d9
5
5
  SHA512:
6
- metadata.gz: ca73efb455416a5e7c022793c17ae088cd685f5751e3497a501f9af880a5f9e970dd838c939d3b61e9145c92e2a0d3acff3d61fbde35a88c7f29e52b148de5c4
7
- data.tar.gz: 9feaab5d5b45e6e9cb1bd48ea3bc47381db6c9cc806e4782fab18df21b093f4034ca8215202e32f64cd776ea695a385f195b3b02ab22679e8b3c01b97b2bd27c
6
+ metadata.gz: 47de7cabc21f0365b8629714dbd7044e95346d5fb9ce13f7c830a8aeab66bd078769792e6af2ddf52bfc41be3b052f1f1ef912dc71d34c3db0dc94b283832238
7
+ data.tar.gz: 00c98825475166ae5f53e6bd85081766a38aa12b5ecddf079e0f1efcbb0eb729deacf996ee975893897aa2aeca84e35a741d23c2bf7e1f602c75876e08d317ee
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: 'github-actions'
4
+ directory: '/'
5
+ schedule:
6
+ interval: 'weekly'
@@ -11,17 +11,13 @@ jobs:
11
11
  strategy:
12
12
  fail-fast: false
13
13
  matrix:
14
- ruby: [ '3.1', '3.0', '2.7', '2.6' ]
14
+ ruby: [ '3.2', '3.1', '3.0', '2.7' ]
15
15
  os:
16
16
  - ubuntu-latest
17
17
  experimental: [false]
18
- include:
19
- - ruby: head
20
- os: ubuntu-latest
21
- experimental: true
22
18
  name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
23
19
  steps:
24
- - uses: actions/checkout@v2
20
+ - uses: actions/checkout@v3
25
21
  - uses: ruby/setup-ruby@v1
26
22
  with:
27
23
  ruby-version: ${{ matrix.ruby }}
data/ChangeLog CHANGED
@@ -1,3 +1,8 @@
1
+ Release 2.1.0 - 2023/06/15
2
+
3
+ * Add `initialized` and `initlabels` parameters to `<metric>` element
4
+ * in_prometheus_tail_monitor: Add file open/closed/rotation metrics
5
+
1
6
  Release 2.0.3 - 2022/05/06
2
7
 
3
8
  * in_prometheus_output_monitor: Fix a bug where output_status_num_errors metric is missing
data/README.md CHANGED
@@ -162,10 +162,11 @@ This plugin uses internal class of Fluentd, so it's easy to break.
162
162
 
163
163
  #### Exposed metrics
164
164
 
165
- - `fluentd_tail_file_position`
166
- - Current bytes which plugin reads from the file
167
- - `fluentd_tail_file_inode`
168
- - inode of the file
165
+ - `fluentd_tail_file_position`: Current bytes which plugin reads from the file
166
+ - `fluentd_tail_file_inode`: inode of the file
167
+ - `fluentd_tail_file_closed`: Number of closed files
168
+ - `fluentd_tail_file_opened`: Number of opened files
169
+ - `fluentd_tail_file_rotated`: Number of rotated files
169
170
 
170
171
  Default labels:
171
172
 
@@ -286,7 +287,9 @@ For details of each metric type, see [Prometheus documentation](http://prometheu
286
287
  - `type`: metric type (required)
287
288
  - `desc`: description of this metric (required)
288
289
  - `key`: key name of record for instrumentation (**optional**)
290
+ - `initialized`: boolean controlling initilization of metric (**optional**). See [Metric initialization](#metric-initialization)
289
291
  - `<labels>`: additional labels for this metric (optional). See [Labels](#labels)
292
+ - `<initlabels>`: labels to use for initialization of ReccordAccessors/Placeholder labels (**optional**). See [Metric initialization](#metric-initialization)
290
293
 
291
294
  If key is empty, the metric values is treated as 1, so the counter increments by 1 on each record regardless of contents of the record.
292
295
 
@@ -310,7 +313,9 @@ If key is empty, the metric values is treated as 1, so the counter increments by
310
313
  - `type`: metric type (required)
311
314
  - `desc`: description of metric (required)
312
315
  - `key`: key name of record for instrumentation (required)
316
+ - `initialized`: boolean controlling initilization of metric (**optional**). See [Metric initialization](#metric-initialization)
313
317
  - `<labels>`: additional labels for this metric (optional). See [Labels](#labels)
318
+ - `<initlabels>`: labels to use for initialization of ReccordAccessors/Placeholder labels (**optional**). See [Metric initialization](#metric-initialization)
314
319
 
315
320
  ### summary type
316
321
 
@@ -332,7 +337,9 @@ If key is empty, the metric values is treated as 1, so the counter increments by
332
337
  - `type`: metric type (required)
333
338
  - `desc`: description of metric (required)
334
339
  - `key`: key name of record for instrumentation (required)
340
+ - `initialized`: boolean controlling initilization of metric (**optional**). See [Metric initialization](#metric-initialization)
335
341
  - `<labels>`: additional labels for this metric (optional). See [Labels](#labels)
342
+ - `<initlabels>`: labels to use for initialization of ReccordAccessors/Placeholder labels (**optional**). See [Metric initialization](#metric-initialization)
336
343
 
337
344
  ### histogram type
338
345
 
@@ -355,8 +362,10 @@ If key is empty, the metric values is treated as 1, so the counter increments by
355
362
  - `type`: metric type (required)
356
363
  - `desc`: description of metric (required)
357
364
  - `key`: key name of record for instrumentation (required)
365
+ - `initialized`: boolean controlling initilization of metric (**optional**). See [Metric initialization](#metric-initialization)
358
366
  - `buckets`: buckets of record for instrumentation (optional)
359
367
  - `<labels>`: additional labels for this metric (optional). See [Labels](#labels)
368
+ - `<initlabels>`: labels to use for initialization of ReccordAccessors/Placeholder labels (**optional**). See [Metric initialization](#metric-initialization)
360
369
 
361
370
  ## Labels
362
371
 
@@ -395,6 +404,53 @@ Reserved placeholders are:
395
404
  - where `tagsize` is the size of tag which is splitted with `.` (when tag is `1.2.3`, then `tagsize` is 3)
396
405
  - only available in Prometheus output/filter plugin
397
406
 
407
+ ### Metric initialization
408
+
409
+ You can configure if a metric should be initialized to its zero value before receiving any event. To do so you just need to specify `initialized true`.
410
+
411
+ ```
412
+ <metric>
413
+ name message_bar_counter
414
+ type counter
415
+ desc The total number of bar in message.
416
+ key bar
417
+ initialized true
418
+ <labels>
419
+ foo bar
420
+ </labels>
421
+ </metric>
422
+ ```
423
+
424
+ If your labels contains ReccordAccessors or Placeholders, you must use `<initlabels>` to specify the values your ReccordAccessors/Placeholders will take. This feature is useful only if your Placeholders/ReccordAccessors contain deterministic values. Initialization will create as many zero value metrics as `<initlabels>` blocks you defined.
425
+ Potential reserved placeholders `${hostname}` and `${worker_id}`, as well as static labels, are automatically added and should not be specified in `<initlabels>` configuration.
426
+
427
+ ```
428
+ <metric>
429
+ name message_bar_counter
430
+ type counter
431
+ desc The total number of bar in message.
432
+ key bar
433
+ initialized true
434
+ <labels>
435
+ key $.foo
436
+ tag ${tag}
437
+ foo bar
438
+ worker_id ${worker_id}
439
+ </labels>
440
+ <initlabels>
441
+ key foo1
442
+ tag tag1
443
+ </initlabels>
444
+ <initlabels>
445
+ key foo2
446
+ tag tag2
447
+ </initlabels>
448
+ </metric>
449
+ <labels>
450
+ hostname ${hostname}
451
+ </labels>
452
+ ```
453
+
398
454
  ### top-level labels and labels inside metric
399
455
 
400
456
  Prometheus output/filter plugin can have multiple metric section. Top-level labels section specifies labels for all metrics. Labels section inside metric section specifies labels for the metric. Both are specified, labels are merged.
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "fluent-plugin-prometheus"
3
- spec.version = "2.0.3"
3
+ spec.version = "2.1.0"
4
4
  spec.authors = ["Masahiro Sano"]
5
5
  spec.email = ["sabottenda@gmail.com"]
6
6
  spec.summary = %q{A fluent plugin that collects metrics and exposes for Prometheus.}
@@ -51,6 +51,15 @@ module Fluent::Plugin
51
51
  inode: get_gauge(
52
52
  :fluentd_tail_file_inode,
53
53
  'Current inode of file.'),
54
+ closed_file_metrics: get_gauge(
55
+ :fluentd_tail_file_closed,
56
+ 'Number of files closed.'),
57
+ opened_file_metrics: get_gauge(
58
+ :fluentd_tail_file_opened,
59
+ 'Number of files opened.'),
60
+ rotated_file_metrics: get_gauge(
61
+ :fluentd_tail_file_rotated,
62
+ 'Number of files rotated.'),
54
63
  }
55
64
  timer_execute(:in_prometheus_tail_monitor, @interval, &method(:update_monitor_info))
56
65
  end
@@ -72,9 +81,15 @@ module Fluent::Plugin
72
81
  # Access to internal variable of internal class...
73
82
  # Very fragile implementation
74
83
  pe = watcher.instance_variable_get(:@pe)
84
+ monitor_info = watcher.instance_variable_get(:@metrics)
75
85
  label = labels(info, watcher.path)
76
86
  @metrics[:inode].set(pe.read_inode, labels: label)
77
87
  @metrics[:position].set(pe.read_pos, labels: label)
88
+ unless monitor_info.nil?
89
+ @metrics[:closed_file_metrics].set(monitor_info.closed.get, labels: label)
90
+ @metrics[:opened_file_metrics].set(monitor_info.opened.get, labels: label)
91
+ @metrics[:rotated_file_metrics].set(monitor_info.rotated.get, labels: label)
92
+ end
78
93
  end
79
94
  end
80
95
  end
@@ -56,6 +56,69 @@ module Fluent
56
56
  base_labels
57
57
  end
58
58
 
59
+ def self.parse_initlabels_elements(conf, base_labels)
60
+ base_initlabels = []
61
+
62
+ # We first treat the special case of RecordAccessors and Placeholders labels if any declared
63
+ conf.elements.select { |e| e.name == 'initlabels' }.each { |block|
64
+ initlabels = {}
65
+
66
+ block.each do |key, value|
67
+ if not base_labels.has_key? key.to_sym
68
+ raise ConfigError, "Key #{key} in <initlabels> is non existent in <labels> for metric #{conf['name']}"
69
+ end
70
+
71
+ if value.start_with?('$.') || value.start_with?('$[') || value.start_with?('${')
72
+ raise ConfigError, "Cannot use RecordAccessor or placeholder #{value} (key #{key}) in a <initlabels> in metric #{conf['name']}"
73
+ end
74
+
75
+ base_label_value = base_labels[key.to_sym]
76
+
77
+ if !(base_label_value.class == Fluent::PluginHelper::RecordAccessor::Accessor) && ! (base_label_value.start_with?('${') )
78
+ raise ConfigError, "Cannot set <initlabels> on non RecordAccessor/Placeholder key #{key} (value #{value}) in metric #{conf['name']}"
79
+ end
80
+
81
+ if base_label_value == '${worker_id}' || base_label_value == '${hostname}'
82
+ raise ConfigError, "Cannot set <initlabels> on reserved placeholder #{base_label_value} for key #{key} in metric #{conf['name']}"
83
+ end
84
+
85
+ initlabels[key.to_sym] = value
86
+ end
87
+
88
+ # Now adding all labels that are not RecordAccessor nor Placeholder labels as is
89
+ base_labels.each do |key, value|
90
+ if base_labels[key.to_sym].class != Fluent::PluginHelper::RecordAccessor::Accessor
91
+ if value == '${worker_id}'
92
+ # We retrieve fluentd_worker_id this way to not overcomplicate the code
93
+ initlabels[key.to_sym] = (ENV['SERVERENGINE_WORKER_ID'] || 0).to_i
94
+ elsif value == '${hostname}'
95
+ initlabels[key.to_sym] = Socket.gethostname
96
+ elsif !(value.start_with?('${'))
97
+ initlabels[key.to_sym] = value
98
+ end
99
+ end
100
+ end
101
+
102
+ base_initlabels << initlabels
103
+ }
104
+
105
+ # Testing for RecordAccessor/Placeholder labels missing a declaration in <initlabels> blocks
106
+ base_labels.each do |key, value|
107
+ if value.class == Fluent::PluginHelper::RecordAccessor::Accessor || value.start_with?('${')
108
+ if not base_initlabels.map(&:keys).flatten.include? (key.to_sym)
109
+ raise ConfigError, "RecordAccessor/Placeholder key #{key} with value #{value} has not been set in a <initlabels> for initialized metric #{conf['name']}"
110
+ end
111
+ end
112
+ end
113
+
114
+ if base_initlabels.length == 0
115
+ # There were no RecordAccessor nor Placeholder labels, we blunty retrieve the static base_labels
116
+ base_initlabels << base_labels
117
+ end
118
+
119
+ base_initlabels
120
+ end
121
+
59
122
  def self.parse_metrics_elements(conf, registry, labels = {})
60
123
  metrics = []
61
124
  conf.elements.select { |element|
@@ -162,9 +225,27 @@ module Fluent
162
225
  @name = element['name']
163
226
  @key = element['key']
164
227
  @desc = element['desc']
165
-
228
+ element['initialized'].nil? ? @initialized = false : @initialized = element['initialized'] == 'true'
229
+
166
230
  @base_labels = Fluent::Plugin::Prometheus.parse_labels_elements(element)
167
231
  @base_labels = labels.merge(@base_labels)
232
+
233
+ if @initialized
234
+ @base_initlabels = Fluent::Plugin::Prometheus.parse_initlabels_elements(element, @base_labels)
235
+ end
236
+ end
237
+
238
+ def self.init_label_set(metric, base_initlabels, base_labels)
239
+ base_initlabels.each { |initlabels|
240
+ # Should never happen, but handy test should code evolution break current implementation
241
+ if initlabels.keys.sort != base_labels.keys.sort
242
+ raise ConfigError, "initlabels for metric #{metric.name} must have the same signature than labels " \
243
+ "(initlabels given: #{initlabels.keys} vs." \
244
+ " expected from labels: #{base_labels.keys})"
245
+ end
246
+
247
+ metric.init_label_set(initlabels)
248
+ }
168
249
  end
169
250
 
170
251
  def labels(record, expander)
@@ -206,6 +287,10 @@ module Fluent
206
287
  rescue ::Prometheus::Client::Registry::AlreadyRegisteredError
207
288
  @gauge = Fluent::Plugin::Prometheus::Metric.get(registry, element['name'].to_sym, :gauge, element['desc'])
208
289
  end
290
+
291
+ if @initialized
292
+ Fluent::Plugin::Prometheus::Metric.init_label_set(@gauge, @base_initlabels, @base_labels)
293
+ end
209
294
  end
210
295
 
211
296
  def instrument(record, expander)
@@ -228,6 +313,10 @@ module Fluent
228
313
  rescue ::Prometheus::Client::Registry::AlreadyRegisteredError
229
314
  @counter = Fluent::Plugin::Prometheus::Metric.get(registry, element['name'].to_sym, :counter, element['desc'])
230
315
  end
316
+
317
+ if @initialized
318
+ Fluent::Plugin::Prometheus::Metric.init_label_set(@counter, @base_initlabels, @base_labels)
319
+ end
231
320
  end
232
321
 
233
322
  def instrument(record, expander)
@@ -259,6 +348,10 @@ module Fluent
259
348
  rescue ::Prometheus::Client::Registry::AlreadyRegisteredError
260
349
  @summary = Fluent::Plugin::Prometheus::Metric.get(registry, element['name'].to_sym, :summary, element['desc'])
261
350
  end
351
+
352
+ if @initialized
353
+ Fluent::Plugin::Prometheus::Metric.init_label_set(@summary, @base_initlabels, @base_labels)
354
+ end
262
355
  end
263
356
 
264
357
  def instrument(record, expander)
@@ -292,6 +385,10 @@ module Fluent
292
385
  rescue ::Prometheus::Client::Registry::AlreadyRegisteredError
293
386
  @histogram = Fluent::Plugin::Prometheus::Metric.get(registry, element['name'].to_sym, :histogram, element['desc'])
294
387
  end
388
+
389
+ if @initialized
390
+ Fluent::Plugin::Prometheus::Metric.init_label_set(@histogram, @base_initlabels, @base_labels)
391
+ end
295
392
  end
296
393
 
297
394
  def instrument(record, expander)
@@ -202,7 +202,7 @@ describe Fluent::Plugin::PrometheusInput do
202
202
  describe '#run_multi_workers' do
203
203
  context '/metrics' do
204
204
  Fluent::SystemConfig.overwrite_system_config('workers' => 4) do
205
- let(:config) { CONFIG + %[
205
+ let(:config) { FULL_CONFIG + %[
206
206
  port #{port - 2}
207
207
  ] }
208
208
 
@@ -16,6 +16,10 @@ describe Fluent::Plugin::PrometheusOutput do
16
16
  it_behaves_like 'output configuration'
17
17
  end
18
18
 
19
+ describe '#testinitlabels' do
20
+ it_behaves_like 'initalized metrics'
21
+ end
22
+
19
23
  describe '#run' do
20
24
  let(:message) { {"foo" => 100, "bar" => 100, "baz" => 100, "qux" => 10} }
21
25
 
@@ -27,6 +27,7 @@ FULL_CONFIG = BASE_CONFIG + %[
27
27
  type gauge
28
28
  desc Something bar.
29
29
  key bar
30
+ initialized true
30
31
  <labels>
31
32
  key foo2
32
33
  </labels>
@@ -36,6 +37,7 @@ FULL_CONFIG = BASE_CONFIG + %[
36
37
  type summary
37
38
  desc Something baz.
38
39
  key baz
40
+ initialized true
39
41
  <labels>
40
42
  key foo3
41
43
  </labels>
@@ -46,6 +48,7 @@ FULL_CONFIG = BASE_CONFIG + %[
46
48
  desc Something qux.
47
49
  key qux
48
50
  buckets 0.1, 1, 5, 10
51
+ initialized true
49
52
  <labels>
50
53
  key foo4
51
54
  </labels>
@@ -62,12 +65,32 @@ FULL_CONFIG = BASE_CONFIG + %[
62
65
  <metric>
63
66
  name full_accessor2
64
67
  type counter
65
- desc Something with accessor.
68
+ desc Something with accessor
66
69
  key $.foo
70
+ initialized true
67
71
  <labels>
68
72
  key foo6
69
73
  </labels>
70
74
  </metric>
75
+ <metric>
76
+ name full_accessor3
77
+ type counter
78
+ desc Something with accessor and several initialized metrics
79
+ initialized true
80
+ <labels>
81
+ key $.foo
82
+ key2 $.foo2
83
+ key3 footix
84
+ </labels>
85
+ <initlabels>
86
+ key foo6
87
+ key2 foo7
88
+ </initlabels>
89
+ <initlabels>
90
+ key foo8
91
+ key2 foo9
92
+ </initlabels>
93
+ </metric>
71
94
  <labels>
72
95
  test_key test_value
73
96
  </labels>
@@ -79,13 +102,20 @@ PLACEHOLDER_CONFIG = BASE_CONFIG + %[
79
102
  type counter
80
103
  desc Something foo.
81
104
  key foo
105
+ initialized true
82
106
  <labels>
83
107
  foo ${foo}
108
+ foo2 foo2
84
109
  </labels>
110
+ <initlabels>
111
+ tag tag
112
+ foo foo
113
+ </initlabels>
85
114
  </metric>
86
115
  <labels>
87
116
  tag ${tag}
88
117
  hostname ${hostname}
118
+ workerid ${worker_id}
89
119
  </labels>
90
120
  ]
91
121
 
@@ -150,6 +180,111 @@ shared_examples_for 'output configuration' do
150
180
  end
151
181
  it { expect { driver }.to raise_error(Fluent::ConfigError) }
152
182
  end
183
+
184
+
185
+ context 'with missing <initlabels>' do
186
+ let(:config) do
187
+ BASE_CONFIG + %[
188
+ <metric>
189
+ name simple_foo
190
+ type counter
191
+ desc Something foo but incorrect
192
+ key foo
193
+ initialized true
194
+ <labels>
195
+ key $.accessor
196
+ </labels>
197
+ </metric>
198
+ ]
199
+ end
200
+ it { expect { driver }.to raise_error(Fluent::ConfigError) }
201
+ end
202
+
203
+ context 'with RecordAccessor set in <initlabels>' do
204
+ let(:config) do
205
+ BASE_CONFIG + %[
206
+ <metric>
207
+ name simple_foo
208
+ type counter
209
+ desc Something foo but incorrect
210
+ key foo
211
+ initialized true
212
+ <labels>
213
+ key $.accessor
214
+ </labels>
215
+ <initlabels>
216
+ key $.accessor2
217
+ <initlabels>
218
+ </metric>
219
+ ]
220
+ end
221
+ it { expect { driver }.to raise_error(Fluent::ConfigError) }
222
+ end
223
+
224
+ context 'with PlaceHolder set in <initlabels>' do
225
+ let(:config) do
226
+ BASE_CONFIG + %[
227
+ <metric>
228
+ name simple_foo
229
+ type counter
230
+ desc Something foo but incorrect
231
+ key foo
232
+ initialized true
233
+ <labels>
234
+ key ${foo}
235
+ </labels>
236
+ <initlabels>
237
+ key ${foo}
238
+ <initlabels>
239
+ </metric>
240
+ ]
241
+ end
242
+ it { expect { driver }.to raise_error(Fluent::ConfigError) }
243
+ end
244
+
245
+ context 'with non RecordAccessor label set in <initlabels>' do
246
+ let(:config) do
247
+ BASE_CONFIG + %[
248
+ <metric>
249
+ name simple_foo
250
+ type counter
251
+ desc Something foo but incorrect
252
+ key foo
253
+ initialized true
254
+ <labels>
255
+ key $.accessor
256
+ key2 foo2
257
+ </labels>
258
+ <initlabels>
259
+ key foo
260
+ key2 foo2
261
+ <initlabels>
262
+ </metric>
263
+ ]
264
+ end
265
+ it { expect { driver }.to raise_error(Fluent::ConfigError) }
266
+ end
267
+
268
+ context 'with non-matching label keys set in <initlabels>' do
269
+ let(:config) do
270
+ BASE_CONFIG + %[
271
+ <metric>
272
+ name simple_foo
273
+ type counter
274
+ desc Something foo but incorrect
275
+ key foo
276
+ initialized true
277
+ <labels>
278
+ key $.accessor
279
+ </labels>
280
+ <initlabels>
281
+ key2 foo
282
+ <initlabels>
283
+ </metric>
284
+ ]
285
+ end
286
+ it { expect { driver }.to raise_error(Fluent::ConfigError) }
287
+ end
153
288
  end
154
289
 
155
290
  shared_examples_for 'instruments record' do
@@ -165,14 +300,16 @@ shared_examples_for 'instruments record' do
165
300
  let(:histogram) { registry.get(:full_qux) }
166
301
  let(:summary_with_accessor) { registry.get(:full_accessor1) }
167
302
  let(:counter_with_accessor) { registry.get(:full_accessor2) }
303
+ let(:counter_with_two_accessors) { registry.get(:full_accessor3) }
168
304
 
169
305
  it 'adds all metrics' do
170
- expect(registry.metrics.map(&:name)).to eq(%i[full_foo full_bar full_baz full_qux full_accessor1 full_accessor2])
306
+ expect(registry.metrics.map(&:name)).to eq(%i[full_foo full_bar full_baz full_qux full_accessor1 full_accessor2 full_accessor3])
171
307
  expect(counter).to be_kind_of(::Prometheus::Client::Metric)
172
308
  expect(gauge).to be_kind_of(::Prometheus::Client::Metric)
173
309
  expect(summary).to be_kind_of(::Prometheus::Client::Metric)
174
310
  expect(summary_with_accessor).to be_kind_of(::Prometheus::Client::Metric)
175
311
  expect(counter_with_accessor).to be_kind_of(::Prometheus::Client::Metric)
312
+ expect(counter_with_two_accessors).to be_kind_of(::Prometheus::Client::Metric)
176
313
  expect(histogram).to be_kind_of(::Prometheus::Client::Metric)
177
314
  end
178
315
 
@@ -180,6 +317,7 @@ shared_examples_for 'instruments record' do
180
317
  expect(counter.type).to eq(:counter)
181
318
  expect(counter.get(labels: {test_key: 'test_value', key: 'foo1'})).to be_kind_of(Numeric)
182
319
  expect(counter_with_accessor.get(labels: {test_key: 'test_value', key: 'foo6'})).to be_kind_of(Numeric)
320
+ expect(counter_with_two_accessors.get(labels: {test_key: 'test_value', key: 'foo6', key2: 'foo7', key3: 'footix'})).to be_kind_of(Numeric)
183
321
  end
184
322
 
185
323
  it 'instruments gauge metric' do
@@ -246,3 +384,66 @@ shared_examples_for 'instruments record' do
246
384
  end
247
385
  end
248
386
  end
387
+
388
+ shared_examples_for 'initalized metrics' do
389
+ before do
390
+ driver.run(default_tag: tag)
391
+ end
392
+
393
+ context 'full config' do
394
+ let(:config) { FULL_CONFIG }
395
+ let(:counter) { registry.get(:full_foo) }
396
+ let(:gauge) { registry.get(:full_bar) }
397
+ let(:summary) { registry.get(:full_baz) }
398
+ let(:histogram) { registry.get(:full_qux) }
399
+ let(:summary_with_accessor) { registry.get(:full_accessor1) }
400
+ let(:counter_with_accessor) { registry.get(:full_accessor2) }
401
+ let(:counter_with_two_accessors) { registry.get(:full_accessor3) }
402
+
403
+ it 'adds all metrics' do
404
+ expect(registry.metrics.map(&:name)).to eq(%i[full_foo full_bar full_baz full_qux full_accessor1 full_accessor2 full_accessor3])
405
+ expect(counter).to be_kind_of(::Prometheus::Client::Metric)
406
+ expect(gauge).to be_kind_of(::Prometheus::Client::Metric)
407
+ expect(summary).to be_kind_of(::Prometheus::Client::Metric)
408
+ expect(summary_with_accessor).to be_kind_of(::Prometheus::Client::Metric)
409
+ expect(counter_with_accessor).to be_kind_of(::Prometheus::Client::Metric)
410
+ expect(counter_with_two_accessors).to be_kind_of(::Prometheus::Client::Metric)
411
+ expect(histogram).to be_kind_of(::Prometheus::Client::Metric)
412
+ end
413
+
414
+ it 'tests uninitialized metrics' do
415
+ expect(counter.values).to eq({})
416
+ expect(summary_with_accessor.values).to eq({})
417
+ end
418
+
419
+ it 'tests initialized metrics' do
420
+ expect(gauge.values).to eq({{:key=>"foo2", :test_key=>"test_value"}=>0.0})
421
+ expect(summary.values).to eq({:key=>"foo3", :test_key=>"test_value"}=>{"count"=>0.0, "sum"=>0.0})
422
+ expect(histogram.values).to eq({:key=>"foo4", :test_key=>"test_value"} => {"+Inf"=>0.0, "0.1"=>0.0, "1"=>0.0, "10"=>0.0, "5"=>0.0, "sum"=>0.0})
423
+ expect(counter_with_accessor.values).to eq({{:key=>"foo6", :test_key=>"test_value"}=>0.0})
424
+ expect(counter_with_two_accessors.values).to eq({{:key=>"foo6", :key2=>"foo7", :key3=>"footix", :test_key=>"test_value"}=>0.0, {:key=>"foo8", :key2=>"foo9", :key3=>"footix", :test_key=>"test_value"}=>0.0})
425
+ end
426
+ end
427
+
428
+ context 'placeholder config' do
429
+ let(:config) { PLACEHOLDER_CONFIG }
430
+ let(:counter) { registry.get(:placeholder_foo) }
431
+
432
+ it 'expands placeholders with record values' do
433
+ expect(registry.metrics.map(&:name)).to eq([:placeholder_foo])
434
+ expect(counter).to be_kind_of(::Prometheus::Client::Metric)
435
+
436
+ key, _ = counter.values.find {|k,v| v == 0.0 }
437
+ expect(key).to be_kind_of(Hash)
438
+ expect(key[:foo]).to eq("foo")
439
+ expect(key[:foo2]).to eq("foo2")
440
+ expect(key[:hostname]).to be_kind_of(String)
441
+ expect(key[:hostname]).not_to eq("${hostname}")
442
+ expect(key[:hostname]).not_to be_empty
443
+ expect(key[:workerid]).to be_kind_of(String)
444
+ expect(key[:workerid]).not_to eq("${worker_id}")
445
+ expect(key[:workerid]).not_to be_empty
446
+ expect(key[:tag]).to eq("tag")
447
+ end
448
+ end
449
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-prometheus
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Sano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-06 00:00:00.000000000 Z
11
+ date: 2023-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -107,10 +107,10 @@ executables: []
107
107
  extensions: []
108
108
  extra_rdoc_files: []
109
109
  files:
110
+ - ".github/dependabot.yml"
110
111
  - ".github/workflows/linux.yml"
111
112
  - ".gitignore"
112
113
  - ".rspec"
113
- - ".travis.yml"
114
114
  - ChangeLog
115
115
  - Gemfile
116
116
  - LICENSE
data/.travis.yml DELETED
@@ -1,14 +0,0 @@
1
- language: ruby
2
-
3
- rvm:
4
- - "2.4.7"
5
- - "2.5"
6
- - "2.6"
7
-
8
- gemfile:
9
- - Gemfile
10
-
11
- script:
12
- - bundle exec rake spec
13
-
14
- sudo: false