fluent-plugin-prometheus 0.2.1 → 0.3.0

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
  SHA1:
3
- metadata.gz: bc459ea9922aeb0b292c93035e176c4a3c2dfa03
4
- data.tar.gz: c2598bbe1b5e3cd7de282d7db394c0f5b0a89723
3
+ metadata.gz: 85a4bc3e525bcf86677e899b7e6fc565cff5cfff
4
+ data.tar.gz: 76db50326565b85f18ef1ddf5bbf08dd7d4f3de8
5
5
  SHA512:
6
- metadata.gz: 7da56621296f4f7f279334f998e5f238fadf881ce08d4aef8dfaab2d96a81e490db42689a276b544e3830b87ba83a8507168d33c3006df17164ed3551a14c2b0
7
- data.tar.gz: ea09dd18c3d52d3b852c917c661318d5143ba4a9946c34eaa03adfc160d6fc1179676fdb635d44ca15fa99dacb3b3676f1ab6e688883835c17de3c8ad7b79ea7
6
+ metadata.gz: ca87c98ff6ffb9b0c2b7ad82b8f5d5a875fcc70f5b6e539e59fa15f1d3624d08d0cfc13ae47ccaa1eeed6c5d2087655ec9d21b8c8ff342f69fe96c42789fb095
7
+ data.tar.gz: 80d39b58eb5289f0d8f2b5d5b4f8e7eec58ce3b7bcae4dcfa00abdf6699e6dc73c61498806803f7d2eac80ce9f95dfa42a8ffc1d220ef243396701ac64d3ae80
@@ -1,13 +1,18 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.2
5
- - 2.3.1
4
+ - "2.3.3"
5
+ - "2.4.0"
6
6
 
7
7
  gemfile:
8
8
  - Gemfile
9
- - Gemfile.fluentd.0.10
10
9
  - Gemfile.fluentd.0.12
10
+ - Gemfile.fluentd.0.10
11
+
12
+ matrix:
13
+ allow_failures:
14
+ - gemfile: Gemfile.fluentd.0.10
15
+ rvm: 2.4.0
11
16
 
12
17
  script:
13
18
  - bundle exec rake spec
data/README.md CHANGED
@@ -73,6 +73,70 @@ More configuration parameters:
73
73
  - `<labels>`: additional labels for this metric (optional). See [Labels](#Labels)
74
74
  - `interval`: interval to update monitor_agent information in seconds (default: 5)
75
75
 
76
+ ### prometheus_output_monitor input plugin
77
+
78
+ This plugin collects internal metrics for output plugin in Fluentd. This is similar to `prometheus_monitor` plugin, but specialized for input plugin. There are Many metrics `prometheus_monitor` does not include, such as `num_errors`, `retry_wait` and so on.
79
+
80
+ Current exposed metrics:
81
+
82
+ - `fluentd_output_status_buffer_queue_length`
83
+ - `fluentd_output_status_buffer_total_bytes`
84
+ - `fluentd_output_status_retry_count`
85
+ - `fluentd_output_status_num_errors`
86
+ - `fluentd_output_status_emit_count`
87
+ - `fluentd_output_status_retry_wait`
88
+ - current retry_wait computed from last retry time and next retry time
89
+ - `fluentd_output_status_emit_records`
90
+ - only for v0.14
91
+ - `fluentd_output_status_write_count`
92
+ - only for v0.14
93
+ - `fluentd_output_status_rollback_count`
94
+ - only for v0.14
95
+
96
+
97
+ With following configuration, those metrics are collected.
98
+
99
+ <source>
100
+ type prometheus_output_monitor
101
+ </source>
102
+
103
+ More configuration parameters:
104
+
105
+ - `<labels>`: additional labels for this metric (optional). See [Labels](#Labels)
106
+ - `interval`: interval to update monitor_agent information in seconds (default: 5)
107
+
108
+ ### prometheus_tail_monitor input plugin
109
+
110
+ **experimental**
111
+
112
+ This plugin collects internal metrics for in_tail plugin in Fluentd. in_tail plugin holds internal state for files that the plugin is watching. The state is sometimes important to monitor plugins work correctly.
113
+
114
+ This plugin uses internal class of Fluentd, so it's easy to break.
115
+
116
+ Current exposed metrics:
117
+
118
+ - `fluentd_tail_file_position`
119
+ - Current bytes which plugin reads from the file
120
+ - `fluentd_tail_file_inode`
121
+ - inode of the file
122
+
123
+ Default labels:
124
+
125
+ - `plugin_id`: a value set for a plugin in configuration.
126
+ - `type`: plugin name. `in_tail` only for now.
127
+ - `path`: file path
128
+
129
+ With following configuration, those metrics are collected.
130
+
131
+ <source>
132
+ type prometheus_output_monitor
133
+ </source>
134
+
135
+ More configuration parameters:
136
+
137
+ - `<labels>`: additional labels for this metric (optional). See [Labels](#Labels)
138
+ - `interval`: interval to update monitor_agent information in seconds (default: 5)
139
+
76
140
  ### prometheus output/filter plugin
77
141
 
78
142
  Both output/filter plugins instrument metrics from records. Both plugins have no impact against values of each records, just read.
@@ -315,8 +379,8 @@ $ bundle install --path vendor/bundle
315
379
  Download pre-compiled prometheus binary and start it. It listens on 9090.
316
380
 
317
381
  ```
318
- $ wget https://github.com/prometheus/prometheus/releases/download/v1.0.1/prometheus-1.0.1.linux-amd64.tar.gz -O - | tar zxf -
319
- $ ./prometheus-1.0.1.linux-amd64/prometheus -config.file=./misc/prometheus.yaml -storage.local.path=./prometheus/metrics
382
+ $ wget https://github.com/prometheus/prometheus/releases/download/v1.5.2/prometheus-1.5.2.linux-amd64.tar.gz -O - | tar zxf -
383
+ $ ./prometheus-1.5.2.linux-amd64/prometheus -config.file=./misc/prometheus.yaml -storage.local.path=./prometheus/metrics
320
384
  ```
321
385
 
322
386
  Install Nginx for sample metrics. It listens on 80 and 9999.
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "fluent-plugin-prometheus"
3
- spec.version = "0.2.1"
3
+ spec.version = "0.3.0"
4
4
  spec.authors = ["Masahiro Sano"]
5
5
  spec.email = ["sabottenda@gmail.com"]
6
6
  spec.summary = %q{A fluent plugin that collects metrics and exposes for Prometheus.}
@@ -22,6 +22,7 @@ module Fluent
22
22
  end
23
23
 
24
24
  def start
25
+ super
25
26
  @server = WEBrick::HTTPServer.new(
26
27
  BindAddress: @bind,
27
28
  Port: @port,
@@ -33,6 +34,7 @@ module Fluent
33
34
  end
34
35
 
35
36
  def shutdown
37
+ super
36
38
  if @server
37
39
  @server.shutdown
38
40
  @server = nil
@@ -1,7 +1,6 @@
1
1
  require 'fluent/input'
2
2
  require 'fluent/plugin/in_monitor_agent'
3
3
  require 'fluent/plugin/prometheus'
4
- require 'webrick'
5
4
 
6
5
  module Fluent
7
6
  class PrometheusMonitorInput < Input
@@ -65,6 +64,7 @@ module Fluent
65
64
  end
66
65
 
67
66
  def start
67
+ super
68
68
  @loop = Coolio::Loop.new
69
69
  @timer = TimerWatcher.new(@interval, true, log, &method(:update_monitor_info))
70
70
  @loop.attach(@timer)
@@ -72,6 +72,7 @@ module Fluent
72
72
  end
73
73
 
74
74
  def shutdown
75
+ super
75
76
  @loop.watchers.each {|w| w.detach }
76
77
  @loop.stop
77
78
  @thread.join
@@ -0,0 +1,178 @@
1
+ require 'fluent/input'
2
+ require 'fluent/plugin/in_monitor_agent'
3
+ require 'fluent/plugin/prometheus'
4
+
5
+ module Fluent
6
+ class PrometheusOutputMonitorInput < Input
7
+ Plugin.register_input('prometheus_output_monitor', self)
8
+
9
+ config_param :interval, :time, :default => 5
10
+ attr_reader :registry
11
+
12
+ MONITOR_IVARS = [
13
+ :num_errors,
14
+ :emit_count,
15
+
16
+ # for v0.12
17
+ :last_retry_time,
18
+
19
+ # from v0.14
20
+ :emit_records,
21
+ :write_count,
22
+ :rollback_count,
23
+ ]
24
+
25
+ def initialize
26
+ super
27
+ @registry = ::Prometheus::Client.registry
28
+ end
29
+
30
+ def configure(conf)
31
+ super
32
+ hostname = Socket.gethostname
33
+ expander = Fluent::Prometheus.placeholder_expander(log)
34
+ placeholders = expander.prepare_placeholders({'hostname' => hostname})
35
+ @base_labels = Fluent::Prometheus.parse_labels_elements(conf)
36
+ @base_labels.each do |key, value|
37
+ @base_labels[key] = expander.expand(value, placeholders)
38
+ end
39
+
40
+ if defined?(Fluent::Plugin) && defined?(Fluent::Plugin::MonitorAgentInput)
41
+ # from v0.14.6
42
+ @monitor_agent = Fluent::Plugin::MonitorAgentInput.new
43
+ else
44
+ @monitor_agent = Fluent::MonitorAgentInput.new
45
+ end
46
+
47
+ @metrics = {
48
+ buffer_queue_length: @registry.gauge(
49
+ :fluentd_output_status_buffer_queue_length,
50
+ 'Current buffer queue length.'),
51
+ buffer_total_queued_size: @registry.gauge(
52
+ :fluentd_output_status_buffer_total_bytes,
53
+ 'Current total size of queued buffers.'),
54
+ retry_counts: @registry.gauge(
55
+ :fluentd_output_status_retry_count,
56
+ 'Current retry counts.'),
57
+ num_errors: @registry.gauge(
58
+ :fluentd_output_status_num_errors,
59
+ 'Current number of errors.'),
60
+ emit_count: @registry.gauge(
61
+ :fluentd_output_status_emit_count,
62
+ 'Current emit counts.'),
63
+ emit_records: @registry.gauge(
64
+ :fluentd_output_status_emit_records,
65
+ 'Current emit records.'),
66
+ write_count: @registry.gauge(
67
+ :fluentd_output_status_write_count,
68
+ 'Current write counts.'),
69
+ rollback_count: @registry.gauge(
70
+ :fluentd_output_status_rollback_count,
71
+ 'Current rollback counts.'),
72
+ retry_wait: @registry.gauge(
73
+ :fluentd_output_status_retry_wait,
74
+ 'Current retry wait'),
75
+ }
76
+ end
77
+
78
+ class TimerWatcher < Coolio::TimerWatcher
79
+ def initialize(interval, repeat, log, &callback)
80
+ @callback = callback
81
+ @log = log
82
+ super(interval, repeat)
83
+ end
84
+
85
+ def on_timer
86
+ @callback.call
87
+ rescue
88
+ @log.error $!.to_s
89
+ @log.error_backtrace
90
+ end
91
+ end
92
+
93
+ def start
94
+ super
95
+ @loop = Coolio::Loop.new
96
+ @timer = TimerWatcher.new(@interval, true, log, &method(:update_monitor_info))
97
+ @loop.attach(@timer)
98
+ @thread = Thread.new(&method(:run))
99
+ end
100
+
101
+ def shutdown
102
+ super
103
+ @loop.watchers.each {|w| w.detach }
104
+ @loop.stop
105
+ @thread.join
106
+ end
107
+
108
+ def run
109
+ @loop.run
110
+ rescue
111
+ log.error "unexpected error", :error=>$!.to_s
112
+ log.error_backtrace
113
+ end
114
+
115
+ def update_monitor_info
116
+ opts = {
117
+ ivars: MONITOR_IVARS,
118
+ with_retry: true,
119
+ }
120
+
121
+ agent_info = @monitor_agent.plugins_info_all(opts).select {|info|
122
+ info['plugin_category'] == 'output'.freeze
123
+ }
124
+
125
+ monitor_info = {
126
+ 'buffer_queue_length' => @metrics[:buffer_queue_length],
127
+ 'buffer_total_queued_size' => @metrics[:buffer_total_queued_size],
128
+ 'retry_count' => @metrics[:retry_counts],
129
+ }
130
+ instance_vars_info = {
131
+ num_errors: @metrics[:num_errors],
132
+ write_count: @metrics[:write_count],
133
+ emit_count: @metrics[:emit_count],
134
+ emit_records: @metrics[:emit_records],
135
+ rollback_count: @metrics[:rollback_count],
136
+ }
137
+
138
+ agent_info.each do |info|
139
+ label = labels(info)
140
+
141
+ monitor_info.each do |name, metric|
142
+ if info[name]
143
+ metric.set(label, info[name])
144
+ end
145
+ end
146
+
147
+ if info['instance_variables']
148
+ instance_vars_info.each do |name, metric|
149
+ if info['instance_variables'][name]
150
+ metric.set(label, info['instance_variables'][name])
151
+ end
152
+ end
153
+ end
154
+
155
+ # compute current retry_wait
156
+ if info['retry']
157
+ next_time = info['retry']['next_time']
158
+ start_time = info['retry']['start']
159
+ if start_time.nil? && info['instance_variables']
160
+ # v0.12 does not include start, use last_retry_time instead
161
+ start_time = info['instance_variables'][:last_retry_time]
162
+ end
163
+ if next_time && start_time
164
+ wait = next_time - start_time
165
+ @metrics[:retry_wait].set(label, wait.to_f)
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ def labels(plugin_info)
172
+ @base_labels.merge(
173
+ plugin_id: plugin_info["plugin_id"],
174
+ type: plugin_info["type"],
175
+ )
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,117 @@
1
+ require 'fluent/input'
2
+ require 'fluent/plugin/in_monitor_agent'
3
+ require 'fluent/plugin/prometheus'
4
+
5
+ module Fluent
6
+ class PrometheusTailMonitorInput < Input
7
+ Plugin.register_input('prometheus_tail_monitor', self)
8
+
9
+ config_param :interval, :time, :default => 5
10
+ attr_reader :registry
11
+
12
+ MONITOR_IVARS = [
13
+ :tails,
14
+ ]
15
+
16
+ def initialize
17
+ super
18
+ @registry = ::Prometheus::Client.registry
19
+ end
20
+
21
+ def configure(conf)
22
+ super
23
+ hostname = Socket.gethostname
24
+ expander = Fluent::Prometheus.placeholder_expander(log)
25
+ placeholders = expander.prepare_placeholders({'hostname' => hostname})
26
+ @base_labels = Fluent::Prometheus.parse_labels_elements(conf)
27
+ @base_labels.each do |key, value|
28
+ @base_labels[key] = expander.expand(value, placeholders)
29
+ end
30
+
31
+ if defined?(Fluent::Plugin) && defined?(Fluent::Plugin::MonitorAgentInput)
32
+ # from v0.14.6
33
+ @monitor_agent = Fluent::Plugin::MonitorAgentInput.new
34
+ else
35
+ @monitor_agent = Fluent::MonitorAgentInput.new
36
+ end
37
+
38
+ @metrics = {
39
+ position: @registry.gauge(
40
+ :fluentd_tail_file_position,
41
+ 'Current position of file.'),
42
+ inode: @registry.gauge(
43
+ :fluentd_tail_file_inode,
44
+ 'Current inode of file.'),
45
+ }
46
+ end
47
+
48
+ class TimerWatcher < Coolio::TimerWatcher
49
+ def initialize(interval, repeat, log, &callback)
50
+ @callback = callback
51
+ @log = log
52
+ super(interval, repeat)
53
+ end
54
+
55
+ def on_timer
56
+ @callback.call
57
+ rescue
58
+ @log.error $!.to_s
59
+ @log.error_backtrace
60
+ end
61
+ end
62
+
63
+ def start
64
+ super
65
+ @loop = Coolio::Loop.new
66
+ @timer = TimerWatcher.new(@interval, true, log, &method(:update_monitor_info))
67
+ @loop.attach(@timer)
68
+ @thread = Thread.new(&method(:run))
69
+ end
70
+
71
+ def shutdown
72
+ super
73
+ @loop.watchers.each {|w| w.detach }
74
+ @loop.stop
75
+ @thread.join
76
+ end
77
+
78
+ def run
79
+ @loop.run
80
+ rescue
81
+ log.error "unexpected error", :error=>$!.to_s
82
+ log.error_backtrace
83
+ end
84
+
85
+ def update_monitor_info
86
+ opts = {
87
+ ivars: MONITOR_IVARS,
88
+ }
89
+
90
+ agent_info = @monitor_agent.plugins_info_all(opts).select {|info|
91
+ info['type'] == 'tail'.freeze
92
+ }
93
+
94
+ agent_info.each do |info|
95
+ tails = info['instance_variables'][:tails]
96
+ next if tails.nil?
97
+
98
+ tails.each do |_, watcher|
99
+ # Access to internal variable of internal class...
100
+ # Very fragile implementation
101
+ pe = watcher.instance_variable_get(:@pe)
102
+ label = labels(info, watcher.path)
103
+ @metrics[:inode].set(label, pe.read_inode)
104
+ @metrics[:position].set(label, pe.read_pos)
105
+ end
106
+ end
107
+ end
108
+
109
+ def labels(plugin_info, path)
110
+ @base_labels.merge(
111
+ plugin_id: plugin_info["plugin_id"],
112
+ type: plugin_info["type"],
113
+ path: path,
114
+ )
115
+ end
116
+ end
117
+ end
@@ -13,6 +13,22 @@
13
13
  </labels>
14
14
  </source>
15
15
 
16
+ # input plugin that collects metrics for output plugin
17
+ <source>
18
+ @type prometheus_output_monitor
19
+ <labels>
20
+ host ${hostname}
21
+ </labels>
22
+ </source>
23
+
24
+ # input plugin that collects metrics for in_tail plugin
25
+ <source>
26
+ @type prometheus_tail_monitor
27
+ <labels>
28
+ host ${hostname}
29
+ </labels>
30
+ </source>
31
+
16
32
  ## Nginx Access Log Configuration
17
33
 
18
34
  <source>
@@ -1,8 +1,13 @@
1
1
  # A job to scrape an endpoint of Fluentd running on localhost.
2
2
  scrape_configs:
3
+ - job_name: 'prometheus'
4
+ scrape_interval: 5s
5
+ static_configs:
6
+ - targets:
7
+ - 'localhost:9090'
3
8
  - job_name: fluentd
4
9
  scrape_interval: 5s
5
10
  static_configs:
6
11
  - targets:
7
- - 'localhost:24231'
12
+ - 'localhost:24231'
8
13
  metrics_path: /metrics
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: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Sano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-11 00:00:00.000000000 Z
11
+ date: 2017-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -114,6 +114,8 @@ files:
114
114
  - lib/fluent/plugin/filter_prometheus.rb
115
115
  - lib/fluent/plugin/in_prometheus.rb
116
116
  - lib/fluent/plugin/in_prometheus_monitor.rb
117
+ - lib/fluent/plugin/in_prometheus_output_monitor.rb
118
+ - lib/fluent/plugin/in_prometheus_tail_monitor.rb
117
119
  - lib/fluent/plugin/out_prometheus.rb
118
120
  - lib/fluent/plugin/prometheus.rb
119
121
  - misc/fluentd_sample.conf
@@ -144,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
146
  version: '0'
145
147
  requirements: []
146
148
  rubyforge_project:
147
- rubygems_version: 2.2.3
149
+ rubygems_version: 2.6.11
148
150
  signing_key:
149
151
  specification_version: 4
150
152
  summary: A fluent plugin that collects metrics and exposes for Prometheus.