fluent-plugin-prometheus 1.7.1 → 1.8.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: 32e8a803f1394e445d273b41ec9bde5f238f4193956c431a0866c93b2a2a0426
4
- data.tar.gz: 281024e977c3aee02030691ffb7cd86361b759dae259bb8103934db7e195f751
3
+ metadata.gz: 6be199d6eb3693d4fe35be96961c05475a667ce8a7fe4b344fb6c5f7c269e820
4
+ data.tar.gz: 3cb81f50d84773da036d7bafadfa41c05928a7fb062310eeea0eea6546382900
5
5
  SHA512:
6
- metadata.gz: 6e784fec1bca9a2ea8f725b5970ed5f08069b6d457ae11b23e1c22017d188046cab4718573c67a94b230acff1583ac12d6378a372a3713f311470c2b9a5818e3
7
- data.tar.gz: 805673a26e562f4607cefbbf256c12e3557317e115a88096357ddde30f6d5f8dea67835e580100c6bfb5aa9abfb542d0f5b0bff9374b6d4b48046034fea5527a
6
+ metadata.gz: fc05d9f8283546700cc401c771d5444470e806fd4193cc47f661e01fd91bcd402ac2b0aa7fd52f2fa92ff5811f76d19aca378e3ae9919b93de27bca8e0300581
7
+ data.tar.gz: e614db8e23a6dad5a0d416b224e49ca1895b641b4b0d41933954d709080344f90cb79bc51869533d0efc43e93422dd401e4b547fa85ea316fa1f13457236933f
@@ -0,0 +1,15 @@
1
+ Release 1.8.2 - 2020/07/17
2
+
3
+ * in_prometheus_output_monitor/in_prometheus_tail_monitor: Support USR2 reload
4
+
5
+ Release 1.8.1 - 2020/07/06
6
+
7
+ * Fix aggregate bug with async-http
8
+
9
+ Release 1.8.0 - 2020/04/17
10
+
11
+ * Use http_server helper
12
+ * Require fluentd v1.9.1 or later
13
+
14
+
15
+ For older releases, see commits on github repository.
data/README.md CHANGED
@@ -8,9 +8,13 @@ A fluent plugin that instruments metrics from records and exposes them via web i
8
8
 
9
9
  | fluent-plugin-prometheus | fluentd | ruby |
10
10
  |--------------------------|------------|--------|
11
- | 1.x.y | >= v0.14.8 | >= 2.1 |
11
+ | 1.x.y | >= v1.9.1 | >= 2.4 |
12
+ | 1.[0-7].y | >= v0.14.8 | >= 2.1 |
12
13
  | 0.x.y | >= v0.12.0 | >= 1.9 |
13
14
 
15
+ Since v1.8.0, fluent-plugin-prometheus uses [http_server helper](https://docs.fluentd.org/plugin-helper-overview/api-plugin-helper-http_server) to launch HTTP server.
16
+ If you want to handle lots of connections, install `async-http` gem.
17
+
14
18
  ## Installation
15
19
 
16
20
  Add this line to your application's Gemfile:
@@ -63,6 +67,19 @@ More configuration parameters:
63
67
  When using multiple workers, each worker binds to port + `fluent_worker_id`.
64
68
  To scrape metrics from all workers at once, you can access http://localhost:24231/aggregated_metrics.
65
69
 
70
+ #### TLS setting
71
+
72
+ Use `<trasnport tls>`. See [transport config article](https://docs.fluentd.org/configuration/transport-section) for more details.
73
+
74
+ ```
75
+ <source>
76
+ @type prometheus
77
+ <transport tls>
78
+ # TLS parameters...
79
+ </transport
80
+ </source>
81
+ ```
82
+
66
83
  ### prometheus_monitor input plugin
67
84
 
68
85
  This plugin collects internal metrics in Fluentd. The metrics are similar to/part of [monitor_agent](https://docs.fluentd.org/input/monitor_agent).
@@ -71,7 +88,7 @@ This plugin collects internal metrics in Fluentd. The metrics are similar to/par
71
88
  #### Exposed metrics
72
89
 
73
90
  - `fluentd_status_buffer_queue_length`
74
- - `fluentd_status_buffer_total_queued_size`
91
+ - `fluentd_status_buffer_total_bytes`
75
92
  - `fluentd_status_retry_count`
76
93
  - `fluentd_status_buffer_newest_timekey` from fluentd v1.4.2
77
94
  - `fluentd_status_buffer_oldest_timekey` from fluentd v1.4.2
@@ -107,7 +124,7 @@ Metrics for output
107
124
  - `fluentd_output_status_emit_records`
108
125
  - `fluentd_output_status_write_count`
109
126
  - `fluentd_output_status_rollback_count`
110
- - `fluentd_output_status_flush_time_count` from fluentd v1.6.0
127
+ - `fluentd_output_status_flush_time_count` in milliseconds from fluentd v1.6.0
111
128
  - `fluentd_output_status_slow_flush_count` from fluentd v1.6.0
112
129
 
113
130
  Metrics for buffer
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "fluent-plugin-prometheus"
3
- spec.version = "1.7.1"
3
+ spec.version = "1.8.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.}
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
14
  spec.require_paths = ["lib"]
15
15
 
16
- spec.add_dependency "fluentd", ">= 0.14.20", "< 2"
16
+ spec.add_dependency "fluentd", ">= 1.9.1", "< 2"
17
17
  spec.add_dependency "prometheus-client", "< 0.10"
18
18
  spec.add_development_dependency "bundler"
19
19
  spec.add_development_dependency "rake"
@@ -2,13 +2,13 @@ require 'fluent/plugin/input'
2
2
  require 'fluent/plugin/prometheus'
3
3
  require 'fluent/plugin/prometheus_metrics'
4
4
  require 'net/http'
5
- require 'webrick'
5
+ require 'openssl'
6
6
 
7
7
  module Fluent::Plugin
8
8
  class PrometheusInput < Fluent::Plugin::Input
9
9
  Fluent::Plugin.register_input('prometheus', self)
10
10
 
11
- helpers :thread
11
+ helpers :thread, :http_server
12
12
 
13
13
  config_param :bind, :string, default: '0.0.0.0'
14
14
  config_param :port, :integer, default: 24231
@@ -17,30 +17,25 @@ module Fluent::Plugin
17
17
 
18
18
  desc 'Enable ssl configuration for the server'
19
19
  config_section :ssl, required: false, multi: false do
20
- config_param :enable, :bool, default: false
20
+ config_param :enable, :bool, default: false, deprecated: 'Use <transport tls> section'
21
21
 
22
22
  desc 'Path to the ssl certificate in PEM format. Read from file and added to conf as "SSLCertificate"'
23
- config_param :certificate_path, :string, default: nil
23
+ config_param :certificate_path, :string, default: nil, deprecated: 'Use cert_path in <transport tls> section'
24
24
 
25
25
  desc 'Path to the ssl private key in PEM format. Read from file and added to conf as "SSLPrivateKey"'
26
- config_param :private_key_path, :string, default: nil
26
+ config_param :private_key_path, :string, default: nil, deprecated: 'Use private_key_path in <transport tls> section'
27
27
 
28
28
  desc 'Path to CA in PEM format. Read from file and added to conf as "SSLCACertificateFile"'
29
- config_param :ca_path, :string, default: nil
29
+ config_param :ca_path, :string, default: nil, deprecated: 'Use ca_path in <transport tls> section'
30
30
 
31
31
  desc 'Additional ssl conf for the server. Ref: https://github.com/ruby/webrick/blob/master/lib/webrick/ssl.rb'
32
- config_param :extra_conf, :hash, default: {:SSLCertName => [['CN','nobody'],['DC','example']]}, symbolize_keys: true
32
+ config_param :extra_conf, :hash, default: nil, symbolize_keys: true, deprecated: 'See http helper config'
33
33
  end
34
34
 
35
- attr_reader :registry
36
-
37
- attr_reader :num_workers
38
- attr_reader :base_port
39
- attr_reader :metrics_path
40
-
41
35
  def initialize
42
36
  super
43
37
  @registry = ::Prometheus::Client.registry
38
+ @secure = nil
44
39
  end
45
40
 
46
41
  def configure(conf)
@@ -55,6 +50,7 @@ module Fluent::Plugin
55
50
  nil
56
51
  end
57
52
  @num_workers = sysconf && sysconf.workers ? sysconf.workers : 1
53
+ @secure = @transport_config.protocol == :tls || (@ssl && @ssl['enable'])
58
54
 
59
55
  @base_port = @port
60
56
  @port += fluentd_worker_id
@@ -66,7 +62,71 @@ module Fluent::Plugin
66
62
 
67
63
  def start
68
64
  super
69
- log.debug "listening prometheus http server on http://#{@bind}:#{@port}/#{@metrics_path} for worker#{fluentd_worker_id}"
65
+
66
+ scheme = @secure ? 'https' : 'http'
67
+ log.debug "listening prometheus http server on #{scheme}:://#{@bind}:#{@port}/#{@metrics_path} for worker#{fluentd_worker_id}"
68
+
69
+ proto = @secure ? :tls : :tcp
70
+
71
+ if @ssl && @ssl['enable'] && @ssl['extra_conf']
72
+ start_webrick
73
+ return
74
+ end
75
+
76
+ begin
77
+ require 'async'
78
+ require 'fluent/plugin/in_prometheus/async_wrapper'
79
+ extend AsyncWrapper
80
+ rescue LoadError => _
81
+ # ignore
82
+ end
83
+
84
+ tls_opt = if @ssl && @ssl['enable']
85
+ ssl_config = {}
86
+
87
+ if (@ssl['certificate_path'] && @ssl['private_key_path'].nil?) || (@ssl['certificate_path'].nil? && @ssl['private_key_path'])
88
+ raise Fluent::ConfigError.new('both certificate_path and private_key_path must be defined')
89
+ end
90
+
91
+ if @ssl['certificate_path']
92
+ ssl_config['cert_path'] = @ssl['certificate_path']
93
+ end
94
+
95
+ if @ssl['private_key_path']
96
+ ssl_config['private_key_path'] = @ssl['private_key_path']
97
+ end
98
+
99
+ if @ssl['ca_path']
100
+ ssl_config['ca_path'] = @ssl['ca_path']
101
+ # Only ca_path is insecure in fluentd
102
+ # https://github.com/fluent/fluentd/blob/2236ad45197ba336fd9faf56f442252c8b226f25/lib/fluent/plugin_helper/cert_option.rb#L68
103
+ ssl_config['insecure'] = true
104
+ end
105
+
106
+ ssl_config
107
+ end
108
+
109
+ http_server_create_http_server(:in_prometheus_server, addr: @bind, port: @port, logger: log, proto: proto, tls_opts: tls_opt) do |server|
110
+ server.get(@metrics_path) { |_req| all_metrics }
111
+ server.get(@aggregated_metrics_path) { |_req| all_workers_metrics }
112
+ end
113
+ end
114
+
115
+ def shutdown
116
+ if @webrick_server
117
+ @webrick_server.shutdown
118
+ @webrick_server = nil
119
+ end
120
+ super
121
+ end
122
+
123
+ private
124
+
125
+ # For compatiblity because http helper can't support extra_conf option
126
+ def start_webrick
127
+ require 'webrick/https'
128
+ require 'webrick'
129
+
70
130
  config = {
71
131
  BindAddress: @bind,
72
132
  Port: @port,
@@ -74,90 +134,96 @@ module Fluent::Plugin
74
134
  Logger: WEBrick::Log.new(STDERR, WEBrick::Log::FATAL),
75
135
  AccessLog: [],
76
136
  }
77
- unless @ssl.nil? || !@ssl['enable']
78
- require 'webrick/https'
79
- require 'openssl'
80
- if (@ssl['certificate_path'] && @ssl['private_key_path'].nil?) || (@ssl['certificate_path'].nil? && @ssl['private_key_path'])
81
- raise RuntimeError.new("certificate_path and private_key_path most both be defined")
82
- end
83
- ssl_config = {
84
- SSLEnable: true
85
- }
86
- if @ssl['certificate_path']
87
- cert = OpenSSL::X509::Certificate.new(File.read(@ssl['certificate_path']))
88
- ssl_config[:SSLCertificate] = cert
89
- end
90
- if @ssl['private_key_path']
91
- key = OpenSSL::PKey::RSA.new(File.read(@ssl['private_key_path']))
92
- ssl_config[:SSLPrivateKey] = key
93
- end
94
- ssl_config[:SSLCACertificateFile] = @ssl['ca_path'] if @ssl['ca_path']
95
- ssl_config = ssl_config.merge(@ssl['extra_conf'])
96
- config = ssl_config.merge(config)
137
+ if (@ssl['certificate_path'] && @ssl['private_key_path'].nil?) || (@ssl['certificate_path'].nil? && @ssl['private_key_path'])
138
+ raise RuntimeError.new("certificate_path and private_key_path most both be defined")
139
+ end
140
+
141
+ ssl_config = {
142
+ SSLEnable: true,
143
+ SSLCertName: [['CN', 'nobody'], ['DC', 'example']]
144
+ }
145
+
146
+ if @ssl['certificate_path']
147
+ cert = OpenSSL::X509::Certificate.new(File.read(@ssl['certificate_path']))
148
+ ssl_config[:SSLCertificate] = cert
97
149
  end
150
+
151
+ if @ssl['private_key_path']
152
+ key = OpenSSL::PKey.read(@ssl['private_key_path'])
153
+ ssl_config[:SSLPrivateKey] = key
154
+ end
155
+
156
+ ssl_config[:SSLCACertificateFile] = @ssl['ca_path'] if @ssl['ca_path']
157
+ ssl_config = ssl_config.merge(@ssl['extra_conf']) if @ssl['extra_conf']
158
+ config = ssl_config.merge(config)
159
+
98
160
  @log.on_debug do
99
161
  @log.debug("WEBrick conf: #{config}")
100
162
  end
101
163
 
102
- @server = WEBrick::HTTPServer.new(config)
103
- @server.mount(@metrics_path, MonitorServlet, self)
104
- @server.mount(@aggregated_metrics_path, MonitorServletAll, self)
105
- thread_create(:in_prometheus) do
106
- @server.start
164
+ @webrick_server = WEBrick::HTTPServer.new(config)
165
+ @webrick_server.mount_proc(@metrics_path) do |_req, res|
166
+ status, header, body = all_metrics
167
+ res.status = status
168
+ res['Content-Type'] = header['Content-Type']
169
+ res.body = body
170
+ res
107
171
  end
108
- end
109
172
 
110
- def shutdown
111
- if @server
112
- @server.shutdown
113
- @server = nil
173
+ @webrick_server.mount_proc(@aggregated_metrics_path) do |_req, res|
174
+ status, header, body = all_workers_metrics
175
+ res.status = status
176
+ res['Content-Type'] = header['Content-Type']
177
+ res.body = body
178
+ res
179
+ end
180
+
181
+ thread_create(:in_prometheus_webrick) do
182
+ @webrick_server.start
114
183
  end
115
- super
116
184
  end
117
185
 
118
- class MonitorServlet < WEBrick::HTTPServlet::AbstractServlet
119
- def initialize(server, prometheus)
120
- @prometheus = prometheus
186
+ def all_metrics
187
+ [200, { 'Content-Type' => ::Prometheus::Client::Formats::Text::CONTENT_TYPE }, ::Prometheus::Client::Formats::Text.marshal(@registry)]
188
+ rescue => e
189
+ [500, { 'Content-Type' => 'text/plain' }, e.to_s]
190
+ end
191
+
192
+ def all_workers_metrics
193
+ full_result = PromMetricsAggregator.new
194
+
195
+ send_request_to_each_worker do |resp|
196
+ if resp.code.to_s == '200'
197
+ full_result.add_metrics(resp.body)
198
+ end
121
199
  end
122
200
 
123
- def do_GET(req, res)
124
- res.status = 200
125
- res['Content-Type'] = ::Prometheus::Client::Formats::Text::CONTENT_TYPE
126
- res.body = ::Prometheus::Client::Formats::Text.marshal(@prometheus.registry)
127
- rescue
128
- res.status = 500
129
- res['Content-Type'] = 'text/plain'
130
- res.body = $!.to_s
201
+ [200, { 'Content-Type' => ::Prometheus::Client::Formats::Text::CONTENT_TYPE }, full_result.get_metrics]
202
+ rescue => e
203
+ [500, { 'Content-Type' => 'text/plain' }, e.to_s]
204
+ end
205
+
206
+ def send_request_to_each_worker
207
+ bind = (@bind == '0.0.0.0') ? '127.0.0.1' : @bind
208
+ [*(@base_port...(@base_port + @num_workers))].each do |worker_port|
209
+ do_request(host: bind, port: worker_port, secure: @secure) do |http|
210
+ yield(http.get(@metrics_path))
211
+ end
131
212
  end
132
213
  end
133
214
 
134
- class MonitorServletAll < WEBrick::HTTPServlet::AbstractServlet
135
- def initialize(server, prometheus)
136
- @prometheus = prometheus
215
+ # might be replaced by AsyncWrapper if async gem is installed
216
+ def do_request(host:, port:, secure:)
217
+ http = Net::HTTP.new(host, port)
218
+
219
+ if secure
220
+ http.use_ssl = true
221
+ # target is our child process. so it's secure.
222
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
137
223
  end
138
224
 
139
- def do_GET(req, res)
140
- res.status = 200
141
- res['Content-Type'] = ::Prometheus::Client::Formats::Text::CONTENT_TYPE
142
-
143
- full_result = PromMetricsAggregator.new
144
- fluent_server_ip = @prometheus.bind == '0.0.0.0' ? '127.0.0.1' : @prometheus.bind
145
- current_worker = 0
146
- while current_worker < @prometheus.num_workers
147
- Net::HTTP.start(fluent_server_ip, @prometheus.base_port + current_worker) do |http|
148
- req = Net::HTTP::Get.new(@prometheus.metrics_path)
149
- result = http.request(req)
150
- if result.is_a?(Net::HTTPSuccess)
151
- full_result.add_metrics(result.body)
152
- end
153
- end
154
- current_worker += 1
155
- end
156
- res.body = full_result.get_metrics
157
- rescue
158
- res.status = 500
159
- res['Content-Type'] = 'text/plain'
160
- res.body = $!.to_s
225
+ http.start do
226
+ yield(http)
161
227
  end
162
228
  end
163
229
  end
@@ -0,0 +1,46 @@
1
+ require 'async'
2
+
3
+ module Fluent::Plugin
4
+ class PrometheusInput
5
+ module AsyncWrapper
6
+ def do_request(host:, port:, secure:)
7
+ endpoint =
8
+ if secure
9
+ context = OpenSSL::SSL::SSLContext.new
10
+ context.verify_mode = OpenSSL::SSL::VERIFY_NONE
11
+ Async::HTTP::Endpoint.parse("https://#{host}:#{port}", ssl_context: context)
12
+ else
13
+ Async::HTTP::Endpoint.parse("http://#{host}:#{port}")
14
+ end
15
+
16
+ client = Async::HTTP::Client.new(endpoint)
17
+ yield(AsyncHttpWrapper.new(client))
18
+ end
19
+
20
+ Response = Struct.new(:code, :body, :headers)
21
+
22
+ class AsyncHttpWrapper
23
+ def initialize(http)
24
+ @http = http
25
+ end
26
+
27
+ def get(path)
28
+ error = nil
29
+ response = Async::Task.current.async {
30
+ begin
31
+ @http.get(path)
32
+ rescue => e # Async::Reactor rescue all error. handle it by itself
33
+ error = e
34
+ end
35
+ }.wait
36
+
37
+ if error
38
+ raise error
39
+ end
40
+
41
+ Response.new(response.status.to_s, response.body.read, response.headers)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,9 +1,9 @@
1
- require 'fluent/input'
1
+ require 'fluent/plugin/input'
2
2
  require 'fluent/plugin/in_monitor_agent'
3
3
  require 'fluent/plugin/prometheus'
4
4
 
5
5
  module Fluent::Plugin
6
- class PrometheusOutputMonitorInput < Fluent::Input
6
+ class PrometheusOutputMonitorInput < Fluent::Plugin::Input
7
7
  Fluent::Plugin.register_input('prometheus_output_monitor', self)
8
8
  include Fluent::Plugin::PrometheusLabelParser
9
9
 
@@ -44,7 +44,7 @@ module Fluent::Plugin
44
44
  super
45
45
  hostname = Socket.gethostname
46
46
  expander_builder = Fluent::Plugin::Prometheus.placeholder_expander(log)
47
- expander = expander_builder.buidl({ 'hostname' => hostname, 'worker_id' => fluentd_worker_id })
47
+ expander = expander_builder.build({ 'hostname' => hostname, 'worker_id' => fluentd_worker_id })
48
48
  @base_labels = parse_labels_elements(conf)
49
49
  @base_labels.each do |key, value|
50
50
  unless value.is_a?(String)
@@ -53,12 +53,7 @@ module Fluent::Plugin
53
53
  @base_labels[key] = expander.expand(value)
54
54
  end
55
55
 
56
- if defined?(Fluent::Plugin) && defined?(Fluent::Plugin::MonitorAgentInput)
57
- # from v0.14.6
58
- @monitor_agent = Fluent::Plugin::MonitorAgentInput.new
59
- else
60
- @monitor_agent = Fluent::MonitorAgentInput.new
61
- end
56
+ @monitor_agent = Fluent::Plugin::MonitorAgentInput.new
62
57
  end
63
58
 
64
59
  def start
@@ -66,57 +61,57 @@ module Fluent::Plugin
66
61
 
67
62
  @metrics = {
68
63
  # Buffer metrics
69
- buffer_total_queued_size: @registry.gauge(
64
+ buffer_total_queued_size: get_gauge(
70
65
  :fluentd_output_status_buffer_total_bytes,
71
66
  'Current total size of stage and queue buffers.'),
72
- buffer_stage_length: @registry.gauge(
67
+ buffer_stage_length: get_gauge(
73
68
  :fluentd_output_status_buffer_stage_length,
74
69
  'Current length of stage buffers.'),
75
- buffer_stage_byte_size: @registry.gauge(
70
+ buffer_stage_byte_size: get_gauge(
76
71
  :fluentd_output_status_buffer_stage_byte_size,
77
72
  'Current total size of stage buffers.'),
78
- buffer_queue_length: @registry.gauge(
73
+ buffer_queue_length: get_gauge(
79
74
  :fluentd_output_status_buffer_queue_length,
80
75
  'Current length of queue buffers.'),
81
- buffer_queue_byte_size: @registry.gauge(
76
+ buffer_queue_byte_size: get_gauge(
82
77
  :fluentd_output_status_queue_byte_size,
83
78
  'Current total size of queue buffers.'),
84
- buffer_available_buffer_space_ratios: @registry.gauge(
79
+ buffer_available_buffer_space_ratios: get_gauge(
85
80
  :fluentd_output_status_buffer_available_space_ratio,
86
81
  'Ratio of available space in buffer.'),
87
- buffer_newest_timekey: @registry.gauge(
82
+ buffer_newest_timekey: get_gauge(
88
83
  :fluentd_output_status_buffer_newest_timekey,
89
84
  'Newest timekey in buffer.'),
90
- buffer_oldest_timekey: @registry.gauge(
85
+ buffer_oldest_timekey: get_gauge(
91
86
  :fluentd_output_status_buffer_oldest_timekey,
92
87
  'Oldest timekey in buffer.'),
93
88
 
94
89
  # Output metrics
95
- retry_counts: @registry.gauge(
90
+ retry_counts: get_gauge(
96
91
  :fluentd_output_status_retry_count,
97
92
  'Current retry counts.'),
98
- num_errors: @registry.gauge(
93
+ num_errors: get_gauge(
99
94
  :fluentd_output_status_num_errors,
100
95
  'Current number of errors.'),
101
- emit_count: @registry.gauge(
96
+ emit_count: get_gauge(
102
97
  :fluentd_output_status_emit_count,
103
98
  'Current emit counts.'),
104
- emit_records: @registry.gauge(
99
+ emit_records: get_gauge(
105
100
  :fluentd_output_status_emit_records,
106
101
  'Current emit records.'),
107
- write_count: @registry.gauge(
102
+ write_count: get_gauge(
108
103
  :fluentd_output_status_write_count,
109
104
  'Current write counts.'),
110
- rollback_count: @registry.gauge(
105
+ rollback_count: get_gauge(
111
106
  :fluentd_output_status_rollback_count,
112
107
  'Current rollback counts.'),
113
- flush_time_count: @registry.gauge(
108
+ flush_time_count: get_gauge(
114
109
  :fluentd_output_status_flush_time_count,
115
110
  'Total flush time.'),
116
- slow_flush_count: @registry.gauge(
111
+ slow_flush_count: get_gauge(
117
112
  :fluentd_output_status_slow_flush_count,
118
113
  'Current slow flush counts.'),
119
- retry_wait: @registry.gauge(
114
+ retry_wait: get_gauge(
120
115
  :fluentd_output_status_retry_wait,
121
116
  'Current retry wait'),
122
117
  }
@@ -198,5 +193,13 @@ module Fluent::Plugin
198
193
  type: plugin_info["type"],
199
194
  )
200
195
  end
196
+
197
+ def get_gauge(name, docstring)
198
+ if @registry.exist?(name)
199
+ @registry.get(name)
200
+ else
201
+ @registry.gauge(name, docstring)
202
+ end
203
+ end
201
204
  end
202
205
  end
@@ -29,7 +29,7 @@ module Fluent::Plugin
29
29
  super
30
30
  hostname = Socket.gethostname
31
31
  expander_builder = Fluent::Plugin::Prometheus.placeholder_expander(log)
32
- expander = expander_builder.prepare_placeholders({ 'hostname' => hostname, 'worker_id' => fluentd_worker_id })
32
+ expander = expander_builder.build({ 'hostname' => hostname, 'worker_id' => fluentd_worker_id })
33
33
  @base_labels = parse_labels_elements(conf)
34
34
  @base_labels.each do |key, value|
35
35
  unless value.is_a?(String)
@@ -38,22 +38,17 @@ module Fluent::Plugin
38
38
  @base_labels[key] = expander.expand(value)
39
39
  end
40
40
 
41
- if defined?(Fluent::Plugin) && defined?(Fluent::Plugin::MonitorAgentInput)
42
- # from v0.14.6
43
- @monitor_agent = Fluent::Plugin::MonitorAgentInput.new
44
- else
45
- @monitor_agent = Fluent::MonitorAgentInput.new
46
- end
41
+ @monitor_agent = Fluent::Plugin::MonitorAgentInput.new
47
42
  end
48
43
 
49
44
  def start
50
45
  super
51
46
 
52
47
  @metrics = {
53
- position: @registry.gauge(
48
+ position: get_gauge(
54
49
  :fluentd_tail_file_position,
55
50
  'Current position of file.'),
56
- inode: @registry.gauge(
51
+ inode: get_gauge(
57
52
  :fluentd_tail_file_inode,
58
53
  'Current inode of file.'),
59
54
  }
@@ -91,5 +86,13 @@ module Fluent::Plugin
91
86
  path: path,
92
87
  )
93
88
  end
89
+
90
+ def get_gauge(name, docstring)
91
+ if @registry.exist?(name)
92
+ @registry.get(name)
93
+ else
94
+ @registry.gauge(name, docstring)
95
+ end
96
+ end
94
97
  end
95
98
  end
@@ -6,11 +6,11 @@ require 'net/http'
6
6
 
7
7
  describe Fluent::Plugin::PrometheusInput do
8
8
  CONFIG = %[
9
- type prometheus
9
+ @type prometheus
10
10
  ]
11
11
 
12
12
  LOCAL_CONFIG = %[
13
- type prometheus
13
+ @type prometheus
14
14
  bind 127.0.0.1
15
15
  ]
16
16
 
@@ -47,6 +47,130 @@ describe Fluent::Plugin::PrometheusInput do
47
47
  end
48
48
  end
49
49
 
50
+ describe '#start' do
51
+ context 'with transport section' do
52
+ let(:config) do
53
+ %[
54
+ @type prometheus
55
+ bind 127.0.0.1
56
+ <transport tls>
57
+ insecure true
58
+ </transport>
59
+ ]
60
+ end
61
+
62
+ it 'returns 200' do
63
+ driver.run(timeout: 1) do
64
+ Net::HTTP.start('127.0.0.1', port, verify_mode: OpenSSL::SSL::VERIFY_NONE, use_ssl: true) do |http|
65
+ req = Net::HTTP::Get.new('/metrics')
66
+ res = http.request(req)
67
+ expect(res.code).to eq('200')
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ context 'old parameters are given' do
74
+ context 'when extra_conf is used' do
75
+ let(:config) do
76
+ %[
77
+ @type prometheus
78
+ bind 127.0.0.1
79
+ <ssl>
80
+ enable true
81
+ extra_conf { "SSLCertName": [["CN", "nobody"], ["DC", "example"]] }
82
+ </ssl>
83
+ ]
84
+ end
85
+
86
+ it 'uses webrick' do
87
+ expect(driver.instance).to receive(:start_webrick).once
88
+ driver.run(timeout: 1)
89
+ end
90
+
91
+ it 'returns 200' do
92
+ driver.run(timeout: 1) do
93
+ Net::HTTP.start('127.0.0.1', port, verify_mode: OpenSSL::SSL::VERIFY_NONE, use_ssl: true) do |http|
94
+ req = Net::HTTP::Get.new('/metrics')
95
+ res = http.request(req)
96
+ expect(res.code).to eq('200')
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ context 'cert_path and private_key_path combination' do
103
+ let(:config) do
104
+ %[
105
+ @type prometheus
106
+ bind 127.0.0.1
107
+ <ssl>
108
+ enable true
109
+ certificate_path path
110
+ private_key_path path1
111
+ </ssl>
112
+ ]
113
+ end
114
+
115
+ it 'converts them into new transport section' do
116
+ expect(driver.instance).to receive(:http_server_create_http_server).with(
117
+ :in_prometheus_server,
118
+ addr: anything,
119
+ logger: anything,
120
+ port: anything,
121
+ proto: :tls,
122
+ tls_opts: { 'cert_path' => 'path', 'private_key_path' => 'path1' }
123
+ ).once
124
+
125
+ driver.run(timeout: 1)
126
+ end
127
+ end
128
+
129
+ context 'insecure and ca_path' do
130
+ let(:config) do
131
+ %[
132
+ @type prometheus
133
+ bind 127.0.0.1
134
+ <ssl>
135
+ enable true
136
+ ca_path path
137
+ </ssl>
138
+ ]
139
+ end
140
+
141
+ it 'converts them into new transport section' do
142
+ expect(driver.instance).to receive(:http_server_create_http_server).with(
143
+ :in_prometheus_server,
144
+ addr: anything,
145
+ logger: anything,
146
+ port: anything,
147
+ proto: :tls,
148
+ tls_opts: { 'ca_path' => 'path', 'insecure' => true }
149
+ ).once
150
+
151
+ driver.run(timeout: 1)
152
+ end
153
+ end
154
+
155
+ context 'when only private_key_path is geven' do
156
+ let(:config) do
157
+ %[
158
+ @type prometheus
159
+ bind 127.0.0.1
160
+ <ssl>
161
+ enable true
162
+ private_key_path path
163
+ </ssl>
164
+ ]
165
+ end
166
+
167
+ it 'raises ConfigError' do
168
+ expect { driver.run(timeout: 1) }.to raise_error(Fluent::ConfigError, 'both certificate_path and private_key_path must be defined')
169
+ end
170
+ end
171
+ end
172
+ end
173
+
50
174
  describe '#run' do
51
175
  context '/metrics' do
52
176
  let(:config) { LOCAL_CONFIG }
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'fluent/plugin/in_prometheus_tail_monitor'
3
+ require 'fluent/test/driver/input'
4
+
5
+ describe Fluent::Plugin::PrometheusTailMonitorInput do
6
+ MONITOR_CONFIG = %[
7
+ @type prometheus_tail_monitor
8
+ <labels>
9
+ host ${hostname}
10
+ foo bar
11
+ </labels>
12
+ ]
13
+
14
+ INVALID_MONITOR_CONFIG = %[
15
+ @type prometheus_tail_monitor
16
+
17
+ <labels>
18
+ host ${hostname}
19
+ foo bar
20
+ invalid_use1 $.foo.bar
21
+ invalid_use2 $[0][1]
22
+ </labels>
23
+ ]
24
+
25
+ let(:config) { MONITOR_CONFIG }
26
+ let(:driver) { Fluent::Test::Driver::Input.new(Fluent::Plugin::PrometheusTailMonitorInput).configure(config) }
27
+
28
+ describe '#configure' do
29
+ describe 'valid' do
30
+ it 'does not raise error' do
31
+ expect { driver }.not_to raise_error
32
+ end
33
+ end
34
+
35
+ describe 'invalid' do
36
+ let(:config) { INVALID_MONITOR_CONFIG }
37
+ it 'expect raise error' do
38
+ expect { driver }.to raise_error
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,6 +1,6 @@
1
1
 
2
2
  BASE_CONFIG = %[
3
- type prometheus
3
+ @type prometheus
4
4
  ]
5
5
 
6
6
  SIMPLE_CONFIG = BASE_CONFIG + %[
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.7.1
4
+ version: 1.8.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-02-13 00:00:00.000000000 Z
11
+ date: 2020-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.14.20
19
+ version: 1.9.1
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '2'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.14.20
29
+ version: 1.9.1
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '2'
@@ -110,6 +110,7 @@ files:
110
110
  - ".gitignore"
111
111
  - ".rspec"
112
112
  - ".travis.yml"
113
+ - ChangeLog
113
114
  - Gemfile
114
115
  - LICENSE
115
116
  - README.md
@@ -117,6 +118,7 @@ files:
117
118
  - fluent-plugin-prometheus.gemspec
118
119
  - lib/fluent/plugin/filter_prometheus.rb
119
120
  - lib/fluent/plugin/in_prometheus.rb
121
+ - lib/fluent/plugin/in_prometheus/async_wrapper.rb
120
122
  - lib/fluent/plugin/in_prometheus_monitor.rb
121
123
  - lib/fluent/plugin/in_prometheus_output_monitor.rb
122
124
  - lib/fluent/plugin/in_prometheus_tail_monitor.rb
@@ -131,6 +133,7 @@ files:
131
133
  - spec/fluent/plugin/filter_prometheus_spec.rb
132
134
  - spec/fluent/plugin/in_prometheus_monitor_spec.rb
133
135
  - spec/fluent/plugin/in_prometheus_spec.rb
136
+ - spec/fluent/plugin/in_prometheus_tail_monitor_spec.rb
134
137
  - spec/fluent/plugin/out_prometheus_spec.rb
135
138
  - spec/fluent/plugin/prometheus/placeholder_expander_spec.rb
136
139
  - spec/fluent/plugin/prometheus_metrics_spec.rb
@@ -163,6 +166,7 @@ test_files:
163
166
  - spec/fluent/plugin/filter_prometheus_spec.rb
164
167
  - spec/fluent/plugin/in_prometheus_monitor_spec.rb
165
168
  - spec/fluent/plugin/in_prometheus_spec.rb
169
+ - spec/fluent/plugin/in_prometheus_tail_monitor_spec.rb
166
170
  - spec/fluent/plugin/out_prometheus_spec.rb
167
171
  - spec/fluent/plugin/prometheus/placeholder_expander_spec.rb
168
172
  - spec/fluent/plugin/prometheus_metrics_spec.rb