fluentd 1.13.3 → 1.14.0.rc
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/fluent/command/fluentd.rb +8 -0
- data/lib/fluent/compat/output.rb +9 -6
- data/lib/fluent/event_router.rb +28 -1
- data/lib/fluent/plugin.rb +10 -1
- data/lib/fluent/plugin/bare_output.rb +49 -8
- data/lib/fluent/plugin/buffer.rb +84 -22
- data/lib/fluent/plugin/filter.rb +35 -1
- data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
- data/lib/fluent/plugin/in_syslog.rb +13 -1
- data/lib/fluent/plugin/in_tail.rb +4 -1
- data/lib/fluent/plugin/in_tail/position_file.rb +1 -1
- data/lib/fluent/plugin/input.rb +39 -1
- data/lib/fluent/plugin/metrics.rb +119 -0
- data/lib/fluent/plugin/metrics_local.rb +96 -0
- data/lib/fluent/plugin/multi_output.rb +43 -6
- data/lib/fluent/plugin/output.rb +74 -33
- data/lib/fluent/plugin_helper.rb +1 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +8 -1
- data/lib/fluent/plugin_helper/metrics.rb +129 -0
- data/lib/fluent/plugin_helper/server.rb +4 -2
- data/lib/fluent/root_agent.rb +6 -0
- data/lib/fluent/supervisor.rb +2 -0
- data/lib/fluent/system_config.rb +9 -1
- data/lib/fluent/version.rb +1 -1
- data/test/config/test_system_config.rb +6 -0
- data/test/plugin/in_tail/test_position_file.rb +26 -4
- data/test/plugin/test_bare_output.rb +13 -0
- data/test/plugin/test_buffer.rb +8 -2
- data/test/plugin/test_filter.rb +11 -0
- data/test/plugin/test_in_monitor_agent.rb +214 -8
- data/test/plugin/test_in_syslog.rb +35 -0
- data/test/plugin/test_in_tail.rb +9 -26
- data/test/plugin/test_input.rb +11 -0
- data/test/plugin/test_metrics.rb +294 -0
- data/test/plugin/test_metrics_local.rb +96 -0
- data/test/plugin/test_multi_output.rb +25 -1
- data/test/plugin/test_output.rb +16 -0
- data/test/plugin_helper/test_event_emitter.rb +29 -0
- data/test/plugin_helper/test_metrics.rb +137 -0
- data/test/test_plugin_classes.rb +102 -0
- data/test/test_root_agent.rb +30 -1
- metadata +17 -8
data/lib/fluent/plugin/filter.rb
CHANGED
@@ -28,13 +28,47 @@ module Fluent
|
|
28
28
|
include PluginLoggerMixin
|
29
29
|
include PluginHelper::Mixin
|
30
30
|
|
31
|
-
helpers_internal :event_emitter
|
31
|
+
helpers_internal :event_emitter, :metrics
|
32
32
|
|
33
33
|
attr_reader :has_filter_with_time
|
34
34
|
|
35
35
|
def initialize
|
36
36
|
super
|
37
37
|
@has_filter_with_time = has_filter_with_time?
|
38
|
+
@emit_records_metrics = nil
|
39
|
+
@emit_size_metrics = nil
|
40
|
+
@counter_mutex = Mutex.new
|
41
|
+
@enable_size_metrics = false
|
42
|
+
end
|
43
|
+
|
44
|
+
def emit_records
|
45
|
+
@emit_records_metrics.get
|
46
|
+
end
|
47
|
+
|
48
|
+
def emit_size
|
49
|
+
@emit_size_metrics.get
|
50
|
+
end
|
51
|
+
|
52
|
+
def configure(conf)
|
53
|
+
super
|
54
|
+
|
55
|
+
@emit_records_metrics = metrics_create(namespace: "fluentd", subsystem: "filter", name: "emit_records", help_text: "Number of count emit records")
|
56
|
+
@emit_size_metrics = metrics_create(namespace: "fluentd", subsystem: "filter", name: "emit_size", help_text: "Total size of emit events")
|
57
|
+
@enable_size_metrics = !!system_config.enable_size_metrics
|
58
|
+
end
|
59
|
+
|
60
|
+
def statistics
|
61
|
+
stats = {
|
62
|
+
'emit_records' => @emit_records_metrics.get,
|
63
|
+
'emit_size' => @emit_size_metrics.get,
|
64
|
+
}
|
65
|
+
|
66
|
+
{ 'filter' => stats }
|
67
|
+
end
|
68
|
+
|
69
|
+
def measure_metrics(es)
|
70
|
+
@emit_records_metrics.add(es.size)
|
71
|
+
@emit_size_metrics.add(es.to_msgpack_stream.bytesize) if @enable_size_metrics
|
38
72
|
end
|
39
73
|
|
40
74
|
def filter(tag, time, record)
|
@@ -238,7 +238,7 @@ module Fluent::Plugin
|
|
238
238
|
'buffer_queue_length' => ->(){ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer); @buffer.queue.size },
|
239
239
|
'buffer_timekeys' => ->(){ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer); @buffer.timekeys },
|
240
240
|
'buffer_total_queued_size' => ->(){ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer); @buffer.stage_size + @buffer.queue_size },
|
241
|
-
'retry_count' => ->(){
|
241
|
+
'retry_count' => ->(){ respond_to?(:num_errors) ? num_errors : nil },
|
242
242
|
}
|
243
243
|
|
244
244
|
def all_plugins
|
@@ -335,7 +335,9 @@ module Fluent::Plugin
|
|
335
335
|
}
|
336
336
|
|
337
337
|
if pe.respond_to?(:statistics)
|
338
|
-
obj.merge!(pe.statistics
|
338
|
+
obj.merge!(pe.statistics.dig('output') || {})
|
339
|
+
obj.merge!(pe.statistics.dig('filter') || {})
|
340
|
+
obj.merge!(pe.statistics.dig('input') || {})
|
339
341
|
end
|
340
342
|
|
341
343
|
obj['retry'] = get_retry_info(pe.retry) if opts[:with_retry] && pe.instance_variable_defined?(:@retry)
|
@@ -89,6 +89,8 @@ module Fluent::Plugin
|
|
89
89
|
config_param :source_hostname_key, :string, default: nil
|
90
90
|
desc 'Try to resolve hostname from IP addresses or not.'
|
91
91
|
config_param :resolve_hostname, :bool, default: nil
|
92
|
+
desc 'Check the remote connection is still available by sending a keepalive packet if this value is true.'
|
93
|
+
config_param :send_keepalive_packet, :bool, default: false
|
92
94
|
desc 'The field name of source address of sender.'
|
93
95
|
config_param :source_address_key, :string, default: nil
|
94
96
|
desc 'The field name of the severity.'
|
@@ -143,6 +145,11 @@ module Fluent::Plugin
|
|
143
145
|
end
|
144
146
|
|
145
147
|
@_event_loop_run_timeout = @blocking_timeout
|
148
|
+
|
149
|
+
protocol = @protocol_type || @transport_config.protocol
|
150
|
+
if @send_keepalive_packet && protocol == :udp
|
151
|
+
raise Fluent::ConfigError, "send_keepalive_packet is available for tcp/tls"
|
152
|
+
end
|
146
153
|
end
|
147
154
|
|
148
155
|
def multi_workers_ready?
|
@@ -173,7 +180,12 @@ module Fluent::Plugin
|
|
173
180
|
|
174
181
|
delimiter = octet_count_frame ? " " : @delimiter
|
175
182
|
delimiter_size = delimiter.size
|
176
|
-
server_create_connection(
|
183
|
+
server_create_connection(
|
184
|
+
tls ? :in_syslog_tls_server : :in_syslog_tcp_server, @port,
|
185
|
+
bind: @bind,
|
186
|
+
resolve_name: @resolve_hostname,
|
187
|
+
send_keepalive_packet: @send_keepalive_packet
|
188
|
+
) do |conn|
|
177
189
|
conn.data do |data|
|
178
190
|
buffer = conn.buffer
|
179
191
|
buffer << data
|
@@ -1063,7 +1063,10 @@ module Fluent::Plugin
|
|
1063
1063
|
rescue RangeError
|
1064
1064
|
io.close if io
|
1065
1065
|
raise WatcherSetupError, "seek error with #{@path}: file position = #{@watcher.pe.read_pos.to_s(16)}, reading bytesize = #{@fifo.bytesize.to_s(16)}"
|
1066
|
-
rescue Errno::
|
1066
|
+
rescue Errno::EACCES => e
|
1067
|
+
@log.warn "#{e}"
|
1068
|
+
nil
|
1069
|
+
rescue Errno::ENOENT
|
1067
1070
|
nil
|
1068
1071
|
end
|
1069
1072
|
|
data/lib/fluent/plugin/input.rb
CHANGED
@@ -27,7 +27,45 @@ module Fluent
|
|
27
27
|
include PluginLoggerMixin
|
28
28
|
include PluginHelper::Mixin
|
29
29
|
|
30
|
-
helpers_internal :event_emitter
|
30
|
+
helpers_internal :event_emitter, :metrics
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
super
|
34
|
+
@emit_records_metrics = nil
|
35
|
+
@emit_size_metrics = nil
|
36
|
+
@counter_mutex = Mutex.new
|
37
|
+
@enable_size_metrics = false
|
38
|
+
end
|
39
|
+
|
40
|
+
def emit_records
|
41
|
+
@emit_records_metrics.get
|
42
|
+
end
|
43
|
+
|
44
|
+
def emit_size
|
45
|
+
@emit_size_metrics.get
|
46
|
+
end
|
47
|
+
|
48
|
+
def configure(conf)
|
49
|
+
super
|
50
|
+
|
51
|
+
@emit_records_metrics = metrics_create(namespace: "fluentd", subsystem: "input", name: "emit_records", help_text: "Number of count emit records")
|
52
|
+
@emit_size_metrics = metrics_create(namespace: "fluentd", subsystem: "input", name: "emit_size", help_text: "Total size of emit events")
|
53
|
+
@enable_size_metrics = !!system_config.enable_size_metrics
|
54
|
+
end
|
55
|
+
|
56
|
+
def statistics
|
57
|
+
stats = {
|
58
|
+
'emit_records' => @emit_records_metrics.get,
|
59
|
+
'emit_size' => @emit_size_metrics.get,
|
60
|
+
}
|
61
|
+
|
62
|
+
{ 'input' => stats }
|
63
|
+
end
|
64
|
+
|
65
|
+
def metric_callback(es)
|
66
|
+
@emit_records_metrics.add(es.size)
|
67
|
+
@emit_size_metrics.add(es.to_msgpack_stream.bytesize) if @enable_size_metrics
|
68
|
+
end
|
31
69
|
|
32
70
|
def multi_workers_ready?
|
33
71
|
false
|
@@ -0,0 +1,119 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'socket'
|
18
|
+
|
19
|
+
require 'fluent/plugin/base'
|
20
|
+
|
21
|
+
require 'fluent/log'
|
22
|
+
require 'fluent/unique_id'
|
23
|
+
require 'fluent/plugin_id'
|
24
|
+
|
25
|
+
module Fluent
|
26
|
+
module Plugin
|
27
|
+
class Metrics < Base
|
28
|
+
include PluginId
|
29
|
+
include PluginLoggerMixin
|
30
|
+
include UniqueId::Mixin
|
31
|
+
|
32
|
+
DEFAULT_TYPE = 'local'
|
33
|
+
|
34
|
+
configured_in :metrics
|
35
|
+
|
36
|
+
config_param :default_labels, :hash, default: {agent: "Fluentd", hostname: "#{Socket.gethostname}"}
|
37
|
+
config_param :labels, :hash, default: {}
|
38
|
+
|
39
|
+
attr_reader :use_gauge_metric
|
40
|
+
attr_reader :has_methods_for_gauge, :has_methods_for_counter
|
41
|
+
|
42
|
+
def initialize
|
43
|
+
super
|
44
|
+
|
45
|
+
@has_methods_for_counter = false
|
46
|
+
@has_methods_for_gauge = false
|
47
|
+
@use_gauge_metric = false
|
48
|
+
end
|
49
|
+
|
50
|
+
def configure(conf)
|
51
|
+
super
|
52
|
+
|
53
|
+
if use_gauge_metric
|
54
|
+
@has_methods_for_gauge = has_methods_for_gauge?
|
55
|
+
else
|
56
|
+
@has_methods_for_counter = has_methods_for_counter?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Some metrics should be counted by gauge.
|
61
|
+
# ref: https://prometheus.io/docs/concepts/metric_types/#gauge
|
62
|
+
def use_gauge_metric=(use_gauge_metric=false)
|
63
|
+
@use_gauge_metric = use_gauge_metric
|
64
|
+
end
|
65
|
+
|
66
|
+
def create(namespace:, subsystem:,name:,help_text:,labels: {})
|
67
|
+
# This API is for cmetrics type.
|
68
|
+
end
|
69
|
+
|
70
|
+
def get
|
71
|
+
raise NotImplementedError, "Implement this method in child class"
|
72
|
+
end
|
73
|
+
|
74
|
+
def inc
|
75
|
+
raise NotImplementedError, "Implement this method in child class"
|
76
|
+
end
|
77
|
+
|
78
|
+
def dec
|
79
|
+
raise NotImplementedError, "Implement this method in child class"
|
80
|
+
end
|
81
|
+
|
82
|
+
def add(value)
|
83
|
+
raise NotImplementedError, "Implement this method in child class"
|
84
|
+
end
|
85
|
+
|
86
|
+
def sub(value)
|
87
|
+
raise NotImplementedError, "Implement this method in child class"
|
88
|
+
end
|
89
|
+
|
90
|
+
def set(value)
|
91
|
+
raise NotImplementedError, "Implement this method in child class"
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def has_methods_for_counter?
|
97
|
+
implemented_methods = self.class.instance_methods(false)
|
98
|
+
|
99
|
+
if [:get, :inc, :add].all? {|e| implemented_methods.include?(e)} &&
|
100
|
+
[:set].all?{|e| self.class.method_defined?(e)}
|
101
|
+
true
|
102
|
+
else
|
103
|
+
raise "BUG: metrics plugin on counter mode MUST implement `get`, `inc`, `add` methods. And aliased `set` methods should be aliased from another method"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def has_methods_for_gauge?
|
108
|
+
implemented_methods = self.class.instance_methods(false)
|
109
|
+
|
110
|
+
if [:get, :inc, :add].all? {|e| implemented_methods.include?(e)} &&
|
111
|
+
[:set, :dec, :sub].all?{|e| self.class.method_defined?(e)}
|
112
|
+
true
|
113
|
+
else
|
114
|
+
raise "BUG: metrics plugin on gauge mode MUST implement `get`, `inc`, and `add` methods. And `dec`, `sub`, and `set` methods should be aliased from other methods"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/plugin'
|
18
|
+
require 'fluent/plugin/metrics'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
module Plugin
|
22
|
+
class LocalMetrics < Metrics
|
23
|
+
Fluent::Plugin.register_metrics('local', self)
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
super
|
27
|
+
@store = 0
|
28
|
+
@monitor = Monitor.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def configure(conf)
|
32
|
+
super
|
33
|
+
|
34
|
+
if use_gauge_metric
|
35
|
+
class << self
|
36
|
+
alias_method :dec, :dec_gauge
|
37
|
+
alias_method :set, :set_gauge
|
38
|
+
alias_method :sub, :sub_gauge
|
39
|
+
end
|
40
|
+
else
|
41
|
+
class << self
|
42
|
+
alias_method :set, :set_counter
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def multi_workers_ready?
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
def get
|
52
|
+
@monitor.synchronize do
|
53
|
+
@store
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def inc
|
58
|
+
@monitor.synchronize do
|
59
|
+
@store += 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def dec_gauge
|
64
|
+
@monitor.synchronize do
|
65
|
+
@store -= 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def add(value)
|
70
|
+
@monitor.synchronize do
|
71
|
+
@store += value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def sub_gauge(value)
|
76
|
+
@monitor.synchronize do
|
77
|
+
@store -= value
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_counter(value)
|
82
|
+
return if @store > value
|
83
|
+
|
84
|
+
@monitor.synchronize do
|
85
|
+
@store = value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def set_gauge(value)
|
90
|
+
@monitor.synchronize do
|
91
|
+
@store = value
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -27,6 +27,7 @@ module Fluent
|
|
27
27
|
include PluginHelper::Mixin # for event_emitter
|
28
28
|
|
29
29
|
helpers :event_emitter # to get router from agent, which will be supplied to child plugins
|
30
|
+
helpers_internal :metrics
|
30
31
|
|
31
32
|
config_section :store, param_name: :stores, multi: true, required: true do
|
32
33
|
config_argument :arg, :string, default: ''
|
@@ -46,11 +47,40 @@ module Fluent
|
|
46
47
|
|
47
48
|
@counter_mutex = Mutex.new
|
48
49
|
# TODO: well organized counters
|
49
|
-
@
|
50
|
-
@
|
51
|
-
@
|
50
|
+
@num_errors_metrics = nil
|
51
|
+
@emit_count_metrics = nil
|
52
|
+
@emit_records_metrics = nil
|
53
|
+
@emit_size_metrics = nil
|
52
54
|
# @write_count = 0
|
53
55
|
# @rollback_count = 0
|
56
|
+
@enable_size_metrics = false
|
57
|
+
end
|
58
|
+
|
59
|
+
def num_errors
|
60
|
+
@num_errors_metrics.get
|
61
|
+
end
|
62
|
+
|
63
|
+
def emit_count
|
64
|
+
@emit_count_metrics.get
|
65
|
+
end
|
66
|
+
|
67
|
+
def emit_size
|
68
|
+
@emit_size_metrics.get
|
69
|
+
end
|
70
|
+
|
71
|
+
def emit_records
|
72
|
+
@emit_records_metrics.get
|
73
|
+
end
|
74
|
+
|
75
|
+
def statistics
|
76
|
+
stats = {
|
77
|
+
'num_errors' => @num_errors_metrics.get,
|
78
|
+
'emit_records' => @emit_records_metrics.get,
|
79
|
+
'emit_count' => @emit_count_metrics.get,
|
80
|
+
'emit_size' => @emit_size_metrics.get,
|
81
|
+
}
|
82
|
+
|
83
|
+
{ 'multi_output' => stats }
|
54
84
|
end
|
55
85
|
|
56
86
|
def multi_output?
|
@@ -60,6 +90,12 @@ module Fluent
|
|
60
90
|
def configure(conf)
|
61
91
|
super
|
62
92
|
|
93
|
+
@num_errors_metrics = metrics_create(namespace: "fluentd", subsystem: "multi_output", name: "num_errors", help_text: "Number of count num errors")
|
94
|
+
@emit_count_metrics = metrics_create(namespace: "fluentd", subsystem: "multi_output", name: "emit_records", help_text: "Number of count emits")
|
95
|
+
@emit_records_metrics = metrics_create(namespace: "fluentd", subsystem: "multi_output", name: "emit_records", help_text: "Number of emit records")
|
96
|
+
@emit_size_metrics = metrics_create(namespace: "fluentd", subsystem: "multi_output", name: "emit_size", help_text: "Total size of emit events")
|
97
|
+
@enable_size_metrics = !!system_config.enable_size_metrics
|
98
|
+
|
63
99
|
@stores.each do |store|
|
64
100
|
store_conf = store.corresponding_config_element
|
65
101
|
type = store_conf['@type']
|
@@ -143,12 +179,13 @@ module Fluent
|
|
143
179
|
end
|
144
180
|
|
145
181
|
def emit_sync(tag, es)
|
146
|
-
@
|
182
|
+
@emit_count_metrics.inc
|
147
183
|
begin
|
148
184
|
process(tag, es)
|
149
|
-
@
|
185
|
+
@emit_records_metrics.add(es.size)
|
186
|
+
@emit_size_metrics.add(es.to_msgpack_stream.bytesize) if @enable_size_metrics
|
150
187
|
rescue
|
151
|
-
@
|
188
|
+
@num_errors_metrics.inc
|
152
189
|
raise
|
153
190
|
end
|
154
191
|
end
|