fluent-plugin-prometheus 1.7.2 → 1.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +19 -0
- data/README.md +20 -3
- data/fluent-plugin-prometheus.gemspec +2 -2
- data/lib/fluent/plugin/in_prometheus.rb +147 -81
- data/lib/fluent/plugin/in_prometheus/async_wrapper.rb +47 -0
- data/lib/fluent/plugin/in_prometheus_output_monitor.rb +28 -25
- data/lib/fluent/plugin/in_prometheus_tail_monitor.rb +12 -9
- data/spec/fluent/plugin/in_prometheus_spec.rb +126 -2
- data/spec/fluent/plugin/in_prometheus_tail_monitor_spec.rb +42 -0
- data/spec/fluent/plugin/shared.rb +1 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e739b07c782da7117d24c2fd38e06cfdb244d5acf68670a38ebad9550261d5c
|
4
|
+
data.tar.gz: 93fcda335d86fc20d16b225cab8a075cc853823d0f616d453bc176fb26e787cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0017117f4c478bf3bb41e28d5103396771450377997dc642dc9b80d66729ce1fb26eb68cda184c7ad8f9805e51377869772834f8248732d3e067c728d5b7681
|
7
|
+
data.tar.gz: 6dc252c05caaf90530446fe8c102c8a60b89c1c918e3c00205b0c6ca845c9991faf8edc271b883fec402661f33f732cb7c027e705427097a8dc32af096005496
|
data/ChangeLog
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Release 1.8.3 - 2020/08/24
|
2
|
+
|
3
|
+
* Fix resourcr leak in async-http based server
|
4
|
+
|
5
|
+
Release 1.8.2 - 2020/07/17
|
6
|
+
|
7
|
+
* in_prometheus_output_monitor/in_prometheus_tail_monitor: Support USR2 reload
|
8
|
+
|
9
|
+
Release 1.8.1 - 2020/07/06
|
10
|
+
|
11
|
+
* Fix aggregate bug with async-http
|
12
|
+
|
13
|
+
Release 1.8.0 - 2020/04/17
|
14
|
+
|
15
|
+
* Use http_server helper
|
16
|
+
* Require fluentd v1.9.1 or later
|
17
|
+
|
18
|
+
|
19
|
+
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 | >=
|
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
|
-
- `
|
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.
|
3
|
+
spec.version = "1.8.3"
|
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", ">=
|
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 '
|
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:
|
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
|
-
|
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
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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
|
-
@
|
103
|
-
@
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
119
|
-
|
120
|
-
|
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
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
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
|
-
|
135
|
-
|
136
|
-
|
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
|
-
|
140
|
-
|
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,47 @@
|
|
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
|
+
Async::HTTP::Client.open(endpoint) do |client|
|
17
|
+
yield(AsyncHttpWrapper.new(client))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Response = Struct.new(:code, :body, :headers)
|
22
|
+
|
23
|
+
class AsyncHttpWrapper
|
24
|
+
def initialize(http)
|
25
|
+
@http = http
|
26
|
+
end
|
27
|
+
|
28
|
+
def get(path)
|
29
|
+
error = nil
|
30
|
+
response = Async::Task.current.async {
|
31
|
+
begin
|
32
|
+
@http.get(path)
|
33
|
+
rescue => e # Async::Reactor rescue all error. handle it by itself
|
34
|
+
error = e
|
35
|
+
end
|
36
|
+
}.wait
|
37
|
+
|
38
|
+
if error
|
39
|
+
raise error
|
40
|
+
end
|
41
|
+
|
42
|
+
Response.new(response.status.to_s, response.read || '', response.headers)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
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
|
|
@@ -53,12 +53,7 @@ module Fluent::Plugin
|
|
53
53
|
@base_labels[key] = expander.expand(value)
|
54
54
|
end
|
55
55
|
|
56
|
-
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
82
|
+
buffer_newest_timekey: get_gauge(
|
88
83
|
:fluentd_output_status_buffer_newest_timekey,
|
89
84
|
'Newest timekey in buffer.'),
|
90
|
-
buffer_oldest_timekey:
|
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:
|
90
|
+
retry_counts: get_gauge(
|
96
91
|
:fluentd_output_status_retry_count,
|
97
92
|
'Current retry counts.'),
|
98
|
-
num_errors:
|
93
|
+
num_errors: get_gauge(
|
99
94
|
:fluentd_output_status_num_errors,
|
100
95
|
'Current number of errors.'),
|
101
|
-
emit_count:
|
96
|
+
emit_count: get_gauge(
|
102
97
|
:fluentd_output_status_emit_count,
|
103
98
|
'Current emit counts.'),
|
104
|
-
emit_records:
|
99
|
+
emit_records: get_gauge(
|
105
100
|
:fluentd_output_status_emit_records,
|
106
101
|
'Current emit records.'),
|
107
|
-
write_count:
|
102
|
+
write_count: get_gauge(
|
108
103
|
:fluentd_output_status_write_count,
|
109
104
|
'Current write counts.'),
|
110
|
-
rollback_count:
|
105
|
+
rollback_count: get_gauge(
|
111
106
|
:fluentd_output_status_rollback_count,
|
112
107
|
'Current rollback counts.'),
|
113
|
-
flush_time_count:
|
108
|
+
flush_time_count: get_gauge(
|
114
109
|
:fluentd_output_status_flush_time_count,
|
115
110
|
'Total flush time.'),
|
116
|
-
slow_flush_count:
|
111
|
+
slow_flush_count: get_gauge(
|
117
112
|
:fluentd_output_status_slow_flush_count,
|
118
113
|
'Current slow flush counts.'),
|
119
|
-
retry_wait:
|
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.
|
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
|
-
|
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:
|
48
|
+
position: get_gauge(
|
54
49
|
:fluentd_tail_file_position,
|
55
50
|
'Current position of file.'),
|
56
|
-
inode:
|
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
|
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.
|
4
|
+
version: 1.8.3
|
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-
|
11
|
+
date: 2020-08-24 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:
|
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:
|
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
|