fluent-plugin-prometheus 1.8.2 → 2.0.1

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: 6be199d6eb3693d4fe35be96961c05475a667ce8a7fe4b344fb6c5f7c269e820
4
- data.tar.gz: 3cb81f50d84773da036d7bafadfa41c05928a7fb062310eeea0eea6546382900
3
+ metadata.gz: 53ce03bc02b89a80dbb46f166e91ad0e4a71011c54dcf1b2999fe5ef24aab7b8
4
+ data.tar.gz: d8a764f2a0ba7ffeb6ae383002aef2705e0a8c7a76550d8647452bfa032edf37
5
5
  SHA512:
6
- metadata.gz: fc05d9f8283546700cc401c771d5444470e806fd4193cc47f661e01fd91bcd402ac2b0aa7fd52f2fa92ff5811f76d19aca378e3ae9919b93de27bca8e0300581
7
- data.tar.gz: e614db8e23a6dad5a0d416b224e49ca1895b641b4b0d41933954d709080344f90cb79bc51869533d0efc43e93422dd401e4b547fa85ea316fa1f13457236933f
6
+ metadata.gz: d4187d6c44ae90bcbcb357efe3b6502c4a62250aa61d77779ded61c80e6be76d04e33a87ade92e9b5e4684d3b7b8d8d89a3eef9d622e9824d4801fc93ee0d6ca
7
+ data.tar.gz: c9a8db411e69763e3759ac7b3b0b9b14bd4eaf64d0c33ac0b97ac33fdcfdae2bf014c1e76de13e4c400251000faf9494e0258eddd8802f052885637003392960
@@ -0,0 +1,26 @@
1
+ name: linux
2
+ on:
3
+ - push
4
+ - pull_request
5
+ jobs:
6
+ build:
7
+ runs-on: ${{ matrix.os }}
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ ruby: [ '2.4', '2.5', '2.6', '2.7' ]
12
+ os:
13
+ - ubuntu-latest
14
+ name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby }}
20
+ - name: unit testing
21
+ env:
22
+ CI: true
23
+ run: |
24
+ gem install bundler rake
25
+ bundle install --jobs 4 --retry 3
26
+ bundle exec rake spec
data/ChangeLog CHANGED
@@ -1,3 +1,23 @@
1
+ Release 2.0.1 - 2021/04/08
2
+
3
+ * out_prometheus: Allow for lookup by symbol as well as string
4
+
5
+ Release 2.0.0 - 2021/02/18
6
+
7
+ * Update prometheus-client dependency to 2.1.0 or later
8
+
9
+ Release 1.8.5 - 2020/11/24
10
+
11
+ * in_prometheus_monitor: Support USR2 reload
12
+
13
+ Release 1.8.4 - 2020/09/24
14
+
15
+ * in_prometheus_output_monitor: Add gauge_all parameter
16
+
17
+ Release 1.8.3 - 2020/08/24
18
+
19
+ * Fix resourcr leak in async-http based server
20
+
1
21
  Release 1.8.2 - 2020/07/17
2
22
 
3
23
  * in_prometheus_output_monitor/in_prometheus_tail_monitor: Support USR2 reload
data/README.md CHANGED
@@ -152,6 +152,7 @@ More configuration parameters:
152
152
 
153
153
  - `<labels>`: additional labels for this metric (optional). See [Labels](#labels)
154
154
  - `interval`: interval to update monitor_agent information in seconds (default: 5)
155
+ - `gauge_all`: Specify metric type. If `true`, use `gauge` type. If `false`, use `counter` type. Since v2, this parameter will be removed and use `counter` type.
155
156
 
156
157
  ### prometheus_tail_monitor input plugin
157
158
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "fluent-plugin-prometheus"
3
- spec.version = "1.8.2"
3
+ spec.version = "2.0.1"
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"
@@ -13,8 +13,9 @@ module Fluent::Plugin
13
13
  Async::HTTP::Endpoint.parse("http://#{host}:#{port}")
14
14
  end
15
15
 
16
- client = Async::HTTP::Client.new(endpoint)
17
- yield(AsyncHttpWrapper.new(client))
16
+ Async::HTTP::Client.open(endpoint) do |client|
17
+ yield(AsyncHttpWrapper.new(client))
18
+ end
18
19
  end
19
20
 
20
21
  Response = Struct.new(:code, :body, :headers)
@@ -38,7 +39,7 @@ module Fluent::Plugin
38
39
  raise error
39
40
  end
40
41
 
41
- Response.new(response.status.to_s, response.body.read, response.headers)
42
+ Response.new(response.status.to_s, response.read || '', response.headers)
42
43
  end
43
44
  end
44
45
  end
@@ -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
@@ -10,6 +10,7 @@ module Fluent::Plugin
10
10
  helpers :timer
11
11
 
12
12
  config_param :interval, :time, default: 5
13
+ config_param :gauge_all, :bool, default: true
13
14
  attr_reader :registry
14
15
 
15
16
  MONITOR_IVARS = [
@@ -54,6 +55,8 @@ module Fluent::Plugin
54
55
  end
55
56
 
56
57
  @monitor_agent = Fluent::Plugin::MonitorAgentInput.new
58
+
59
+ @gauge_or_counter = @gauge_all ? :gauge : :counter
57
60
  end
58
61
 
59
62
  def start
@@ -87,28 +90,28 @@ module Fluent::Plugin
87
90
  'Oldest timekey in buffer.'),
88
91
 
89
92
  # Output metrics
90
- retry_counts: get_gauge(
93
+ retry_counts: get_gauge_or_counter(
91
94
  :fluentd_output_status_retry_count,
92
95
  'Current retry counts.'),
93
- num_errors: get_gauge(
96
+ num_errors: get_gauge_or_counter(
94
97
  :fluentd_output_status_num_errors,
95
98
  'Current number of errors.'),
96
- emit_count: get_gauge(
99
+ emit_count: get_gauge_or_counter(
97
100
  :fluentd_output_status_emit_count,
98
101
  'Current emit counts.'),
99
- emit_records: get_gauge(
102
+ emit_records: get_gauge_or_counter(
100
103
  :fluentd_output_status_emit_records,
101
104
  'Current emit records.'),
102
- write_count: get_gauge(
105
+ write_count: get_gauge_or_counter(
103
106
  :fluentd_output_status_write_count,
104
107
  'Current write counts.'),
105
108
  rollback_count: get_gauge(
106
109
  :fluentd_output_status_rollback_count,
107
110
  'Current rollback counts.'),
108
- flush_time_count: get_gauge(
111
+ flush_time_count: get_gauge_or_counter(
109
112
  :fluentd_output_status_flush_time_count,
110
113
  'Total flush time.'),
111
- slow_flush_count: get_gauge(
114
+ slow_flush_count: get_gauge_or_counter(
112
115
  :fluentd_output_status_slow_flush_count,
113
116
  'Current slow flush counts.'),
114
117
  retry_wait: get_gauge(
@@ -157,14 +160,22 @@ module Fluent::Plugin
157
160
 
158
161
  monitor_info.each do |name, metric|
159
162
  if info[name]
160
- metric.set(label, info[name])
163
+ if metric.is_a?(::Prometheus::Client::Gauge)
164
+ metric.set(info[name], labels: label)
165
+ elsif metric.is_a?(::Prometheus::Client::Counter)
166
+ metric.increment(by: info[name] - metric.get(labels: label), labels: label)
167
+ end
161
168
  end
162
169
  end
163
170
 
164
171
  if info['instance_variables']
165
172
  instance_vars_info.each do |name, metric|
166
173
  if info['instance_variables'][name]
167
- metric.set(label, info['instance_variables'][name])
174
+ if metric.is_a?(::Prometheus::Client::Gauge)
175
+ metric.set(info['instance_variables'][name], labels: label)
176
+ elsif metric.is_a?(::Prometheus::Client::Counter)
177
+ metric.increment(by: info['instance_variables'][name] - metric.get(labels: label), labels: label)
178
+ end
168
179
  end
169
180
  end
170
181
  end
@@ -182,7 +193,7 @@ module Fluent::Plugin
182
193
  if next_time && start_time
183
194
  wait = next_time - start_time
184
195
  end
185
- @metrics[:retry_wait].set(label, wait.to_f)
196
+ @metrics[:retry_wait].set(wait.to_f, labels: label)
186
197
  end
187
198
  end
188
199
  end
@@ -198,7 +209,15 @@ module Fluent::Plugin
198
209
  if @registry.exist?(name)
199
210
  @registry.get(name)
200
211
  else
201
- @registry.gauge(name, docstring)
212
+ @registry.gauge(name, docstring: docstring, labels: @base_labels.keys + [:plugin_id, :type])
213
+ end
214
+ end
215
+
216
+ def get_gauge_or_counter(name, docstring)
217
+ if @registry.exist?(name)
218
+ @registry.get(name)
219
+ else
220
+ @registry.public_send(@gauge_or_counter, name, docstring: docstring, labels: @base_labels.keys + [:plugin_id, :type])
202
221
  end
203
222
  end
204
223
  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.2
4
+ version: 2.0.1
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-07-17 00:00:00.000000000 Z
11
+ date: 2021-04-09 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.1.2
162
163
  signing_key:
163
164
  specification_version: 4
164
165
  summary: A fluent plugin that collects metrics and exposes for Prometheus.