fluent-plugin-prometheus 1.8.4 → 2.0.2

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: c268ed901a0c48ea1885ce64b621c3abc79983a95696180236156b7844029a4d
4
- data.tar.gz: ac9aea40b3eab787f14ba1e402732898ab2cf355a3836d252b85867100914a93
3
+ metadata.gz: 949d2ec196fae78bdfcbbfeae20d718e7a3a34a6ceba9ba665d1a7d40326d529
4
+ data.tar.gz: c1adf9a63565a38141247034157f84aadb85336e5add24ca6d99c126cd8e01d7
5
5
  SHA512:
6
- metadata.gz: 8bead7bf6d8534398ef24706348ae55d6437e3b898d89e6edb9981c6311d92be2e6d25f841a6bbf6be973a870966ff1296f3f4fb5314be62d06b900668f51b85
7
- data.tar.gz: 8e9d8a48bdb3a3ba73626c01acda706a8af9f6dc309a1c005a240eb3cf051ef50ffe3b0012e966765ba8ffec415b2d2fd4a24852938c7fad84882ee842a96899
6
+ metadata.gz: 7199fc669d4c389fa5638615d16a4fdb29a27cc959b60c3ec6e3031328a9cb052bb6169733c73e66f659ec929aa3faffd8869187dc70f6eff361263b3304ecb0
7
+ data.tar.gz: acfbe23681c5bf801ae10c41a265dfb358b05516b79d0e2944317469b0b4be8aad5b1fbda246d9e4caa0e75f473428046015232c0900689ccb629a3b7c5b72a8
@@ -0,0 +1,32 @@
1
+ name: linux
2
+ on:
3
+ - push
4
+ - pull_request
5
+ jobs:
6
+ build:
7
+ runs-on: ${{ matrix.os }}
8
+ continue-on-error: ${{ matrix.experimental }}
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ ruby: [ '2.5', '2.6', '2.7', '3.0' ]
13
+ os:
14
+ - ubuntu-latest
15
+ experimental: [false]
16
+ include:
17
+ - ruby: head
18
+ os: ubuntu-latest
19
+ experimental: true
20
+ name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
21
+ steps:
22
+ - uses: actions/checkout@v2
23
+ - uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby }}
26
+ - name: unit testing
27
+ env:
28
+ CI: true
29
+ run: |
30
+ gem install bundler rake
31
+ bundle install --jobs 4 --retry 3
32
+ bundle exec rake spec
data/ChangeLog CHANGED
@@ -1,3 +1,19 @@
1
+ Release 2.0.2 - 2021/08/02
2
+
3
+ * in_prometheus_output_monitor: Follow Fluentd's core metrics mechanism
4
+
5
+ Release 2.0.1 - 2021/04/08
6
+
7
+ * out_prometheus: Allow for lookup by symbol as well as string
8
+
9
+ Release 2.0.0 - 2021/02/18
10
+
11
+ * Update prometheus-client dependency to 2.1.0 or later
12
+
13
+ Release 1.8.5 - 2020/11/24
14
+
15
+ * in_prometheus_monitor: Support USR2 reload
16
+
1
17
  Release 1.8.4 - 2020/09/24
2
18
 
3
19
  * in_prometheus_output_monitor: Add gauge_all parameter
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "fluent-plugin-prometheus"
3
- spec.version = "1.8.4"
3
+ spec.version = "2.0.2"
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.}
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
  spec.require_paths = ["lib"]
15
15
 
16
16
  spec.add_dependency "fluentd", ">= 1.9.1", "< 2"
17
- spec.add_dependency "prometheus-client", "< 0.10"
17
+ spec.add_dependency "prometheus-client", ">= 2.1.0"
18
18
  spec.add_development_dependency "bundler"
19
19
  spec.add_development_dependency "rake"
20
20
  spec.add_development_dependency "rspec"
@@ -46,19 +46,19 @@ module Fluent::Plugin
46
46
  def start
47
47
  super
48
48
 
49
- @buffer_newest_timekey = @registry.gauge(
49
+ @buffer_newest_timekey = get_gauge(
50
50
  :fluentd_status_buffer_newest_timekey,
51
51
  'Newest timekey in buffer.')
52
- @buffer_oldest_timekey = @registry.gauge(
52
+ @buffer_oldest_timekey = get_gauge(
53
53
  :fluentd_status_buffer_oldest_timekey,
54
54
  'Oldest timekey in buffer.')
55
- buffer_queue_length = @registry.gauge(
55
+ buffer_queue_length = get_gauge(
56
56
  :fluentd_status_buffer_queue_length,
57
57
  'Current buffer queue length.')
58
- buffer_total_queued_size = @registry.gauge(
58
+ buffer_total_queued_size = get_gauge(
59
59
  :fluentd_status_buffer_total_bytes,
60
60
  'Current total size of queued buffers.')
61
- retry_counts = @registry.gauge(
61
+ retry_counts = get_gauge(
62
62
  :fluentd_status_retry_count,
63
63
  'Current retry counts.')
64
64
 
@@ -76,14 +76,14 @@ module Fluent::Plugin
76
76
 
77
77
  @monitor_info.each do |name, metric|
78
78
  if info[name]
79
- metric.set(label, info[name])
79
+ metric.set(info[name], labels: label)
80
80
  end
81
81
  end
82
82
 
83
83
  timekeys = info["buffer_timekeys"]
84
84
  if timekeys && !timekeys.empty?
85
- @buffer_newest_timekey.set(label, timekeys.max)
86
- @buffer_oldest_timekey.set(label, timekeys.min)
85
+ @buffer_newest_timekey.set(timekeys.max, labels: label)
86
+ @buffer_oldest_timekey.set(timekeys.min, labels: label)
87
87
  end
88
88
  end
89
89
  end
@@ -95,5 +95,13 @@ module Fluent::Plugin
95
95
  type: plugin_info["type"],
96
96
  )
97
97
  end
98
+
99
+ def get_gauge(name, docstring)
100
+ if @registry.exist?(name)
101
+ @registry.get(name)
102
+ else
103
+ @registry.gauge(name, docstring: docstring, labels: @base_labels.keys + [:plugin_id, :plugin_category, :type])
104
+ end
105
+ end
98
106
  end
99
107
  end
@@ -144,7 +144,16 @@ module Fluent::Plugin
144
144
 
145
145
  # output metrics
146
146
  'retry_count' => @metrics[:retry_counts],
147
+ # Needed since Fluentd v1.14 due to metrics extensions.
148
+ 'num_errors' => @metrics[:num_errors],
149
+ 'write_count' => @metrics[:write_count],
150
+ 'emit_count' => @metrics[:emit_count],
151
+ 'emit_records' => @metrics[:emit_records],
152
+ 'rollback_count' => @metrics[:rollback_count],
153
+ 'flush_time_count' => @metrics[:flush_time_count],
154
+ 'slow_flush_count' => @metrics[:slow_flush_count],
147
155
  }
156
+ # No needed for Fluentd v1.14 but leave as-is for backward compatibility.
148
157
  instance_vars_info = {
149
158
  num_errors: @metrics[:num_errors],
150
159
  write_count: @metrics[:write_count],
@@ -161,9 +170,9 @@ module Fluent::Plugin
161
170
  monitor_info.each do |name, metric|
162
171
  if info[name]
163
172
  if metric.is_a?(::Prometheus::Client::Gauge)
164
- metric.set(label, info[name])
173
+ metric.set(info[name], labels: label)
165
174
  elsif metric.is_a?(::Prometheus::Client::Counter)
166
- metric.increment(label, info[name] - metric.get(label))
175
+ metric.increment(by: info[name] - metric.get(labels: label), labels: label)
167
176
  end
168
177
  end
169
178
  end
@@ -172,9 +181,9 @@ module Fluent::Plugin
172
181
  instance_vars_info.each do |name, metric|
173
182
  if info['instance_variables'][name]
174
183
  if metric.is_a?(::Prometheus::Client::Gauge)
175
- metric.set(label, info['instance_variables'][name])
184
+ metric.set(info['instance_variables'][name], labels: label)
176
185
  elsif metric.is_a?(::Prometheus::Client::Counter)
177
- metric.increment(label, info['instance_variables'][name] - metric.get(label))
186
+ metric.increment(by: info['instance_variables'][name] - metric.get(labels: label), labels: label)
178
187
  end
179
188
  end
180
189
  end
@@ -193,7 +202,7 @@ module Fluent::Plugin
193
202
  if next_time && start_time
194
203
  wait = next_time - start_time
195
204
  end
196
- @metrics[:retry_wait].set(label, wait.to_f)
205
+ @metrics[:retry_wait].set(wait.to_f, labels: label)
197
206
  end
198
207
  end
199
208
  end
@@ -209,7 +218,7 @@ module Fluent::Plugin
209
218
  if @registry.exist?(name)
210
219
  @registry.get(name)
211
220
  else
212
- @registry.gauge(name, docstring)
221
+ @registry.gauge(name, docstring: docstring, labels: @base_labels.keys + [:plugin_id, :type])
213
222
  end
214
223
  end
215
224
 
@@ -217,7 +226,7 @@ module Fluent::Plugin
217
226
  if @registry.exist?(name)
218
227
  @registry.get(name)
219
228
  else
220
- @registry.public_send(@gauge_or_counter, name, docstring)
229
+ @registry.public_send(@gauge_or_counter, name, docstring: docstring, labels: @base_labels.keys + [:plugin_id, :type])
221
230
  end
222
231
  end
223
232
  end
@@ -73,8 +73,8 @@ module Fluent::Plugin
73
73
  # Very fragile implementation
74
74
  pe = watcher.instance_variable_get(:@pe)
75
75
  label = labels(info, watcher.path)
76
- @metrics[:inode].set(label, pe.read_inode)
77
- @metrics[:position].set(label, pe.read_pos)
76
+ @metrics[:inode].set(pe.read_inode, labels: label)
77
+ @metrics[:position].set(pe.read_pos, labels: label)
78
78
  end
79
79
  end
80
80
  end
@@ -91,7 +91,7 @@ module Fluent::Plugin
91
91
  if @registry.exist?(name)
92
92
  @registry.get(name)
93
93
  else
94
- @registry.gauge(name, docstring)
94
+ @registry.gauge(name, docstring: docstring, labels: @base_labels.keys + [:plugin_id, :type, :path])
95
95
  end
96
96
  end
97
97
  end
@@ -85,6 +85,18 @@ module Fluent
85
85
  Fluent::Plugin::Prometheus::ExpandBuilder.new(log: log)
86
86
  end
87
87
 
88
+ def stringify_keys(hash_to_stringify)
89
+ # Adapted from: https://www.jvt.me/posts/2019/09/07/ruby-hash-keys-string-symbol/
90
+ hash_to_stringify.map do |k,v|
91
+ value_or_hash = if v.instance_of? Hash
92
+ stringify_keys(v)
93
+ else
94
+ v
95
+ end
96
+ [k.to_s, value_or_hash]
97
+ end.to_h
98
+ end
99
+
88
100
  def configure(conf)
89
101
  super
90
102
  @placeholder_values = {}
@@ -99,6 +111,7 @@ module Fluent
99
111
  'worker_id' => fluentd_worker_id,
100
112
  }
101
113
 
114
+ record = stringify_keys(record)
102
115
  placeholders = record.merge(@placeholder_values[tag])
103
116
  expander = @placeholder_expander_builder.build(placeholders)
104
117
  metrics.each do |metric|
@@ -119,6 +132,7 @@ module Fluent
119
132
  }
120
133
 
121
134
  es.each do |time, record|
135
+ record = stringify_keys(record)
122
136
  placeholders = record.merge(placeholder_values)
123
137
  expander = @placeholder_expander_builder.build(placeholders)
124
138
  metrics.each do |metric|
@@ -188,7 +202,7 @@ module Fluent
188
202
  end
189
203
 
190
204
  begin
191
- @gauge = registry.gauge(element['name'].to_sym, element['desc'])
205
+ @gauge = registry.gauge(element['name'].to_sym, docstring: element['desc'], labels: @base_labels.keys)
192
206
  rescue ::Prometheus::Client::Registry::AlreadyRegisteredError
193
207
  @gauge = Fluent::Plugin::Prometheus::Metric.get(registry, element['name'].to_sym, :gauge, element['desc'])
194
208
  end
@@ -201,7 +215,7 @@ module Fluent
201
215
  value = @key.call(record)
202
216
  end
203
217
  if value
204
- @gauge.set(labels(record, expander), value)
218
+ @gauge.set(value, labels: labels(record, expander))
205
219
  end
206
220
  end
207
221
  end
@@ -210,7 +224,7 @@ module Fluent
210
224
  def initialize(element, registry, labels)
211
225
  super
212
226
  begin
213
- @counter = registry.counter(element['name'].to_sym, element['desc'])
227
+ @counter = registry.counter(element['name'].to_sym, docstring: element['desc'], labels: @base_labels.keys)
214
228
  rescue ::Prometheus::Client::Registry::AlreadyRegisteredError
215
229
  @counter = Fluent::Plugin::Prometheus::Metric.get(registry, element['name'].to_sym, :counter, element['desc'])
216
230
  end
@@ -229,7 +243,7 @@ module Fluent
229
243
  # ignore if record value is nil
230
244
  return if value.nil?
231
245
 
232
- @counter.increment(labels(record, expander), value)
246
+ @counter.increment(by: value, labels: labels(record, expander))
233
247
  end
234
248
  end
235
249
 
@@ -241,7 +255,7 @@ module Fluent
241
255
  end
242
256
 
243
257
  begin
244
- @summary = registry.summary(element['name'].to_sym, element['desc'])
258
+ @summary = registry.summary(element['name'].to_sym, docstring: element['desc'], labels: @base_labels.keys)
245
259
  rescue ::Prometheus::Client::Registry::AlreadyRegisteredError
246
260
  @summary = Fluent::Plugin::Prometheus::Metric.get(registry, element['name'].to_sym, :summary, element['desc'])
247
261
  end
@@ -254,7 +268,7 @@ module Fluent
254
268
  value = @key.call(record)
255
269
  end
256
270
  if value
257
- @summary.observe(labels(record, expander), value)
271
+ @summary.observe(value, labels: labels(record, expander))
258
272
  end
259
273
  end
260
274
  end
@@ -271,9 +285,9 @@ module Fluent
271
285
  buckets = element['buckets'].split(/,/).map(&:strip).map do |e|
272
286
  e[/\A\d+.\d+\Z/] ? e.to_f : e.to_i
273
287
  end
274
- @histogram = registry.histogram(element['name'].to_sym, element['desc'], {}, buckets)
288
+ @histogram = registry.histogram(element['name'].to_sym, docstring: element['desc'], labels: @base_labels.keys, buckets: buckets)
275
289
  else
276
- @histogram = registry.histogram(element['name'].to_sym, element['desc'])
290
+ @histogram = registry.histogram(element['name'].to_sym, docstring: element['desc'], labels: @base_labels.keys)
277
291
  end
278
292
  rescue ::Prometheus::Client::Registry::AlreadyRegisteredError
279
293
  @histogram = Fluent::Plugin::Prometheus::Metric.get(registry, element['name'].to_sym, :histogram, element['desc'])
@@ -287,7 +301,7 @@ module Fluent
287
301
  value = @key.call(record)
288
302
  end
289
303
  if value
290
- @histogram.observe(labels(record, expander), value)
304
+ @histogram.observe(value, labels: labels(record, expander))
291
305
  end
292
306
  end
293
307
  end
@@ -40,4 +40,29 @@ describe Fluent::Plugin::PrometheusOutput do
40
40
 
41
41
  it_behaves_like 'instruments record'
42
42
  end
43
+
44
+ describe '#run with symbolized keys' do
45
+ let(:message) { {:foo => 100, :bar => 100, :baz => 100, :qux => 10} }
46
+
47
+ context 'simple config' do
48
+ let(:config) {
49
+ BASE_CONFIG + %(
50
+ <metric>
51
+ name simple
52
+ type counter
53
+ desc Something foo.
54
+ key foo
55
+ </metric>
56
+ )
57
+ }
58
+
59
+ it 'adds a new counter metric' do
60
+ expect(registry.metrics.map(&:name)).not_to eq([:simple])
61
+ driver.run(default_tag: tag) { driver.feed(event_time, message) }
62
+ expect(registry.metrics.map(&:name)).to eq([:simple])
63
+ end
64
+ end
65
+
66
+ it_behaves_like 'instruments record'
67
+ end
43
68
  end
@@ -178,20 +178,19 @@ shared_examples_for 'instruments record' do
178
178
 
179
179
  it 'instruments counter metric' do
180
180
  expect(counter.type).to eq(:counter)
181
- expect(counter.get({test_key: 'test_value', key: 'foo1'})).to be_kind_of(Numeric)
182
- expect(counter_with_accessor.get({test_key: 'test_value', key: 'foo6'})).to be_kind_of(Numeric)
181
+ expect(counter.get(labels: {test_key: 'test_value', key: 'foo1'})).to be_kind_of(Numeric)
182
+ expect(counter_with_accessor.get(labels: {test_key: 'test_value', key: 'foo6'})).to be_kind_of(Numeric)
183
183
  end
184
184
 
185
185
  it 'instruments gauge metric' do
186
186
  expect(gauge.type).to eq(:gauge)
187
- expect(gauge.get({test_key: 'test_value', key: 'foo2'})).to eq(100)
187
+ expect(gauge.get(labels: {test_key: 'test_value', key: 'foo2'})).to eq(100)
188
188
  end
189
189
 
190
190
  it 'instruments summary metric' do
191
191
  expect(summary.type).to eq(:summary)
192
- expect(summary.get({test_key: 'test_value', key: 'foo3'})).to be_kind_of(Hash)
193
- expect(summary.get({test_key: 'test_value', key: 'foo3'})[0.99]).to eq(100)
194
- expect(summary_with_accessor.get({test_key: 'test_value', key: 'foo5'})[0.99]).to eq(100)
192
+ expect(summary.get(labels: {test_key: 'test_value', key: 'foo3'})).to be_kind_of(Hash)
193
+ expect(summary_with_accessor.get(labels: {test_key: 'test_value', key: 'foo5'})["sum"]).to eq(100)
195
194
  end
196
195
 
197
196
  it 'instruments histogram metric' do
@@ -200,8 +199,8 @@ shared_examples_for 'instruments record' do
200
199
  end
201
200
 
202
201
  expect(histogram.type).to eq(:histogram)
203
- expect(histogram.get({test_key: 'test_value', key: 'foo4'})).to be_kind_of(Hash)
204
- expect(histogram.get({test_key: 'test_value', key: 'foo4'})[10]).to eq(5) # 4 + `es` in before
202
+ expect(histogram.get(labels: {test_key: 'test_value', key: 'foo4'})).to be_kind_of(Hash)
203
+ expect(histogram.get(labels: {test_key: 'test_value', key: 'foo4'})["10"]).to eq(5) # 4 + `es` in before
205
204
  end
206
205
  end
207
206
 
@@ -231,7 +230,7 @@ shared_examples_for 'instruments record' do
231
230
  expect(counter).to be_kind_of(::Prometheus::Client::Metric)
232
231
  key, _ = counter.values.find {|k,v| v == 100 }
233
232
  expect(key).to be_kind_of(Hash)
234
- expect(key[:foo]).to eq(100)
233
+ expect(key[:foo]).to eq("100")
235
234
  end
236
235
  end
237
236
 
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: 1.8.4
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Sano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-24 00:00:00.000000000 Z
11
+ date: 2021-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -34,16 +34,16 @@ dependencies:
34
34
  name: prometheus-client
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "<"
37
+ - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '0.10'
39
+ version: 2.1.0
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - "<"
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '0.10'
46
+ version: 2.1.0
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +107,7 @@ executables: []
107
107
  extensions: []
108
108
  extra_rdoc_files: []
109
109
  files:
110
+ - ".github/workflows/linux.yml"
110
111
  - ".gitignore"
111
112
  - ".rspec"
112
113
  - ".travis.yml"
@@ -158,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
159
  - !ruby/object:Gem::Version
159
160
  version: '0'
160
161
  requirements: []
161
- rubygems_version: 3.0.3
162
+ rubygems_version: 3.2.22
162
163
  signing_key:
163
164
  specification_version: 4
164
165
  summary: A fluent plugin that collects metrics and exposes for Prometheus.