fluentd 0.14.2 → 0.14.5
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 +4 -4
- data/ChangeLog +77 -1131
- data/Rakefile +15 -0
- data/appveyor.yml +2 -2
- data/example/in_forward.conf +3 -0
- data/example/in_forward_client.conf +37 -0
- data/example/in_forward_shared_key.conf +15 -0
- data/example/in_forward_users.conf +24 -0
- data/example/multi_filters.conf +61 -0
- data/example/out_forward.conf +13 -13
- data/example/out_forward_client.conf +109 -0
- data/example/out_forward_shared_key.conf +36 -0
- data/example/out_forward_users.conf +65 -0
- data/example/{out_buffered_null.conf → out_null.conf} +10 -6
- data/example/secondary_file.conf +41 -0
- data/fluentd.gemspec +19 -16
- data/lib/fluent/agent.rb +5 -0
- data/lib/fluent/command/debug.rb +4 -4
- data/lib/fluent/compat/handle_tag_and_time_mixin.rb +2 -0
- data/lib/fluent/compat/output.rb +5 -2
- data/lib/fluent/config/configure_proxy.rb +26 -5
- data/lib/fluent/config/error.rb +3 -0
- data/lib/fluent/config/section.rb +15 -0
- data/lib/fluent/event_router.rb +77 -4
- data/lib/fluent/plugin/base.rb +12 -3
- data/lib/fluent/plugin/buffer.rb +5 -1
- data/lib/fluent/plugin/filter.rb +48 -6
- data/lib/fluent/plugin/filter_record_transformer.rb +3 -1
- data/lib/fluent/plugin/filter_stdout.rb +0 -4
- data/lib/fluent/plugin/in_debug_agent.rb +5 -5
- data/lib/fluent/plugin/in_dummy.rb +9 -1
- data/lib/fluent/plugin/in_forward.rb +330 -62
- data/lib/fluent/plugin/in_monitor_agent.rb +31 -77
- data/lib/fluent/plugin/in_tail.rb +76 -92
- data/lib/fluent/plugin/multi_output.rb +4 -0
- data/lib/fluent/plugin/out_forward.rb +328 -222
- data/lib/fluent/plugin/out_null.rb +37 -0
- data/lib/fluent/plugin/out_secondary_file.rb +128 -0
- data/lib/fluent/plugin/out_stdout.rb +38 -2
- data/lib/fluent/plugin/output.rb +29 -6
- data/lib/fluent/plugin/storage_local.rb +16 -0
- data/lib/fluent/plugin_helper/timer.rb +6 -1
- data/lib/fluent/root_agent.rb +4 -1
- data/lib/fluent/supervisor.rb +62 -9
- data/lib/fluent/test/base.rb +3 -0
- data/lib/fluent/test/driver/base.rb +5 -0
- data/lib/fluent/test/formatter_test.rb +2 -0
- data/lib/fluent/test/parser_test.rb +2 -0
- data/lib/fluent/test/startup_shutdown.rb +33 -0
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +1 -2
- data/test/compat/test_calls_super.rb +2 -0
- data/test/config/test_configurable.rb +88 -0
- data/test/config/test_types.rb +7 -3
- data/test/plugin/test_filter.rb +121 -23
- data/test/plugin/test_filter_record_transformer.rb +22 -6
- data/test/plugin/test_in_debug_agent.rb +2 -2
- data/test/plugin/test_in_forward.rb +920 -407
- data/test/plugin/test_in_monitor_agent.rb +333 -0
- data/test/plugin/test_in_tail.rb +686 -595
- data/test/plugin/test_out_forward.rb +150 -207
- data/test/plugin/test_out_null.rb +85 -9
- data/test/plugin/test_out_secondary_file.rb +432 -0
- data/test/plugin/test_out_stdout.rb +143 -45
- data/test/plugin/test_output.rb +53 -0
- data/test/plugin/test_output_as_buffered.rb +13 -0
- data/test/plugin/test_output_as_buffered_overflow.rb +3 -0
- data/test/plugin/test_output_as_buffered_retries.rb +11 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +12 -0
- data/test/plugin/test_output_as_standard.rb +12 -0
- data/test/plugin_helper/test_compat_parameters.rb +2 -0
- data/test/plugin_helper/test_timer.rb +31 -0
- data/test/test_event_router.rb +87 -0
- data/test/test_filter.rb +48 -6
- data/test/test_log.rb +5 -2
- data/test/test_output.rb +41 -1
- data/test/test_plugin_classes.rb +17 -9
- data/test/test_root_agent.rb +188 -0
- metadata +62 -68
- data/lib/fluent/plugin/out_buffered_null.rb +0 -59
- data/lib/fluent/plugin/out_buffered_stdout.rb +0 -70
- data/test/plugin/test_out_buffered_null.rb +0 -79
- data/test/plugin/test_out_buffered_stdout.rb +0 -122
|
@@ -20,13 +20,16 @@ require 'cgi'
|
|
|
20
20
|
|
|
21
21
|
require 'cool.io'
|
|
22
22
|
|
|
23
|
-
require 'fluent/input'
|
|
24
|
-
require 'fluent/output'
|
|
25
|
-
require 'fluent/
|
|
23
|
+
require 'fluent/plugin/input'
|
|
24
|
+
require 'fluent/plugin/output'
|
|
25
|
+
require 'fluent/plugin/multi_output'
|
|
26
|
+
require 'fluent/plugin/filter'
|
|
26
27
|
|
|
27
|
-
module Fluent
|
|
28
|
+
module Fluent::Plugin
|
|
28
29
|
class MonitorAgentInput < Input
|
|
29
|
-
Plugin.register_input('monitor_agent', self)
|
|
30
|
+
Fluent::Plugin.register_input('monitor_agent', self)
|
|
31
|
+
|
|
32
|
+
helpers :timer, :thread
|
|
30
33
|
|
|
31
34
|
config_param :bind, :string, default: '0.0.0.0'
|
|
32
35
|
config_param :port, :integer, default: 24220
|
|
@@ -142,7 +145,7 @@ module Fluent
|
|
|
142
145
|
|
|
143
146
|
class LTSVMonitorServlet < MonitorServlet
|
|
144
147
|
def process(req, res)
|
|
145
|
-
list,
|
|
148
|
+
list, _opts = build_object(req, res)
|
|
146
149
|
return unless list
|
|
147
150
|
|
|
148
151
|
normalized = JSON.parse(list.to_json)
|
|
@@ -204,36 +207,6 @@ module Fluent
|
|
|
204
207
|
end
|
|
205
208
|
end
|
|
206
209
|
|
|
207
|
-
class TimerWatcher < Coolio::TimerWatcher
|
|
208
|
-
def initialize(interval, log, &callback)
|
|
209
|
-
@callback = callback
|
|
210
|
-
@log = log
|
|
211
|
-
|
|
212
|
-
# Avoid long shutdown time
|
|
213
|
-
@num_call = 0
|
|
214
|
-
if interval >= 10
|
|
215
|
-
min_interval = 10
|
|
216
|
-
@call_interval = interval / 10
|
|
217
|
-
else
|
|
218
|
-
min_interval = interval
|
|
219
|
-
@call_interval = 0
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
super(min_interval, true)
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def on_timer
|
|
226
|
-
@num_call += 1
|
|
227
|
-
if @num_call >= @call_interval
|
|
228
|
-
@num_call = 0
|
|
229
|
-
@callback.call
|
|
230
|
-
end
|
|
231
|
-
rescue => e
|
|
232
|
-
@log.error e.to_s
|
|
233
|
-
@log.error_backtrace
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
210
|
def start
|
|
238
211
|
super
|
|
239
212
|
|
|
@@ -248,76 +221,55 @@ module Fluent
|
|
|
248
221
|
@srv.mount('/api/plugins.json', JSONMonitorServlet, self)
|
|
249
222
|
@srv.mount('/api/config', LTSVConfigMonitorServlet, self)
|
|
250
223
|
@srv.mount('/api/config.json', JSONConfigMonitorServlet, self)
|
|
251
|
-
|
|
224
|
+
thread_create :in_monitor_agent_servlet do
|
|
252
225
|
@srv.start
|
|
253
|
-
|
|
226
|
+
end
|
|
254
227
|
if @tag
|
|
255
228
|
log.debug "tag parameter is specified. Emit plugins info to '#{@tag}'"
|
|
256
229
|
|
|
257
|
-
@loop = Coolio::Loop.new
|
|
258
230
|
opts = {with_config: false}
|
|
259
|
-
|
|
260
|
-
es = MultiEventStream.new
|
|
261
|
-
now = Engine.now
|
|
231
|
+
timer_execute(:in_monitor_agent_emit, @emit_interval, repeat: true) {
|
|
232
|
+
es = Fluent::MultiEventStream.new
|
|
233
|
+
now = Fluent::Engine.now
|
|
262
234
|
plugins_info_all(opts).each { |record|
|
|
263
235
|
es.add(now, record)
|
|
264
236
|
}
|
|
265
237
|
router.emit_stream(@tag, es)
|
|
266
238
|
}
|
|
267
|
-
@loop.attach(timer)
|
|
268
|
-
@thread_for_emit = Thread.new(&method(:run))
|
|
269
239
|
end
|
|
270
240
|
end
|
|
271
241
|
|
|
272
|
-
def run
|
|
273
|
-
@loop.run
|
|
274
|
-
rescue => e
|
|
275
|
-
log.error "unexpected error", error: e.to_s
|
|
276
|
-
log.error_backtrace
|
|
277
|
-
end
|
|
278
|
-
|
|
279
242
|
def shutdown
|
|
280
243
|
if @srv
|
|
281
244
|
@srv.shutdown
|
|
282
245
|
@srv = nil
|
|
283
246
|
end
|
|
284
|
-
if @thread
|
|
285
|
-
@thread.join
|
|
286
|
-
@thread = nil
|
|
287
|
-
end
|
|
288
|
-
if @tag
|
|
289
|
-
@loop.watchers.each { |w| w.detach }
|
|
290
|
-
@loop.stop
|
|
291
|
-
@loop = nil
|
|
292
|
-
@thread_for_emit.join
|
|
293
|
-
@thread_for_emit = nil
|
|
294
|
-
end
|
|
295
247
|
|
|
296
248
|
super
|
|
297
249
|
end
|
|
298
250
|
|
|
299
251
|
MONITOR_INFO = {
|
|
300
|
-
'output_plugin' =>
|
|
301
|
-
'buffer_queue_length' =>
|
|
302
|
-
'buffer_total_queued_size' =>
|
|
303
|
-
'retry_count' =>
|
|
252
|
+
'output_plugin' => ->(){ is_a?(::Fluent::Plugin::Output) },
|
|
253
|
+
'buffer_queue_length' => ->(){ throw(:skip) unless instance_variable_defined?(:@buffer); @buffer.queue.size },
|
|
254
|
+
'buffer_total_queued_size' => ->(){ throw(:skip) unless instance_variable_defined?(:@buffer); @buffer.stage_size },
|
|
255
|
+
'retry_count' => ->(){ instance_variable_defined?(:@num_errors) ? @num_errors : nil },
|
|
304
256
|
}
|
|
305
257
|
|
|
306
258
|
def all_plugins
|
|
307
259
|
array = []
|
|
308
260
|
|
|
309
261
|
# get all input plugins
|
|
310
|
-
array.concat Engine.root_agent.inputs
|
|
262
|
+
array.concat Fluent::Engine.root_agent.inputs
|
|
311
263
|
|
|
312
264
|
# get all output plugins
|
|
313
|
-
Engine.root_agent.outputs.each { |o|
|
|
265
|
+
Fluent::Engine.root_agent.outputs.each { |o|
|
|
314
266
|
MonitorAgentInput.collect_children(o, array)
|
|
315
267
|
}
|
|
316
268
|
# get all filter plugins
|
|
317
|
-
Engine.root_agent.filters.each { |f|
|
|
269
|
+
Fluent::Engine.root_agent.filters.each { |f|
|
|
318
270
|
MonitorAgentInput.collect_children(f, array)
|
|
319
271
|
}
|
|
320
|
-
Engine.root_agent.labels.each { |name, l|
|
|
272
|
+
Fluent::Engine.root_agent.labels.each { |name, l|
|
|
321
273
|
# TODO: Add label name to outputs / filters for identifing plugins
|
|
322
274
|
l.outputs.each { |o| MonitorAgentInput.collect_children(o, array) }
|
|
323
275
|
l.filters.each { |f| MonitorAgentInput.collect_children(f, array) }
|
|
@@ -330,7 +282,7 @@ module Fluent
|
|
|
330
282
|
# from the plugin `pe` recursively
|
|
331
283
|
def self.collect_children(pe, array=[])
|
|
332
284
|
array << pe
|
|
333
|
-
if pe.is_a?(MultiOutput) && pe.respond_to?(:outputs)
|
|
285
|
+
if pe.is_a?(Fluent::Plugin::MultiOutput) || pe.is_a?(Fluent::MultiOutput) && pe.respond_to?(:outputs)
|
|
334
286
|
pe.outputs.each {|nop|
|
|
335
287
|
collect_children(nop, array)
|
|
336
288
|
}
|
|
@@ -341,10 +293,10 @@ module Fluent
|
|
|
341
293
|
# try to match the tag and get the info from the matched output plugin
|
|
342
294
|
# TODO: Support output in label
|
|
343
295
|
def plugin_info_by_tag(tag, opts={})
|
|
344
|
-
matches = Engine.root_agent.event_router.instance_variable_get(:@match_rules)
|
|
296
|
+
matches = Fluent::Engine.root_agent.event_router.instance_variable_get(:@match_rules)
|
|
345
297
|
matches.each { |rule|
|
|
346
298
|
if rule.match?(tag)
|
|
347
|
-
if rule.collector.is_a?(Output)
|
|
299
|
+
if rule.collector.is_a?(Fluent::Plugin::Output) || rule.collector.is_a?(Fluent::Output)
|
|
348
300
|
return get_monitor_info(rule.collector, opts)
|
|
349
301
|
end
|
|
350
302
|
end
|
|
@@ -381,8 +333,7 @@ module Fluent
|
|
|
381
333
|
}
|
|
382
334
|
end
|
|
383
335
|
|
|
384
|
-
|
|
385
|
-
IGNORE_ATTRIBUTES = %W(@config_root_section @config @masked_config).map(&:to_sym)
|
|
336
|
+
IGNORE_ATTRIBUTES = %i(@config_root_section @config @masked_config)
|
|
386
337
|
|
|
387
338
|
# get monitor info from the plugin `pe` and return a hash object
|
|
388
339
|
def get_monitor_info(pe, opts={})
|
|
@@ -397,8 +348,11 @@ module Fluent
|
|
|
397
348
|
# run MONITOR_INFO in plugins' instance context and store the info to obj
|
|
398
349
|
MONITOR_INFO.each_pair {|key,code|
|
|
399
350
|
begin
|
|
400
|
-
|
|
401
|
-
|
|
351
|
+
catch(:skip) do
|
|
352
|
+
obj[key] = pe.instance_exec(&code)
|
|
353
|
+
end
|
|
354
|
+
rescue => e
|
|
355
|
+
log.warn "unexpected error in monitoring plugins", key: key, plugin: pe.class, error: e
|
|
402
356
|
end
|
|
403
357
|
}
|
|
404
358
|
|
|
@@ -16,10 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
require 'cool.io'
|
|
18
18
|
|
|
19
|
-
require 'fluent/input'
|
|
19
|
+
require 'fluent/plugin/input'
|
|
20
20
|
require 'fluent/config/error'
|
|
21
21
|
require 'fluent/event'
|
|
22
|
-
require 'fluent/system_config'
|
|
23
22
|
require 'fluent/plugin/buffer'
|
|
24
23
|
|
|
25
24
|
if Fluent.windows?
|
|
@@ -28,11 +27,11 @@ else
|
|
|
28
27
|
Fluent::FileWrapper = File
|
|
29
28
|
end
|
|
30
29
|
|
|
31
|
-
module Fluent
|
|
32
|
-
class TailInput < Input
|
|
33
|
-
|
|
30
|
+
module Fluent::Plugin
|
|
31
|
+
class TailInput < Fluent::Plugin::Input
|
|
32
|
+
Fluent::Plugin.register_input('tail', self)
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
helpers :timer, :event_loop, :parser, :compat_parameters
|
|
36
35
|
|
|
37
36
|
FILE_PERMISSION = 0644
|
|
38
37
|
|
|
@@ -67,25 +66,34 @@ module Fluent
|
|
|
67
66
|
config_param :multiline_flush_interval, :time, default: nil
|
|
68
67
|
desc 'Enable the additional watch timer.'
|
|
69
68
|
config_param :enable_watch_timer, :bool, default: true
|
|
69
|
+
desc 'The encoding after conversion of the input.'
|
|
70
|
+
config_param :encoding, :string, default: nil
|
|
70
71
|
desc 'The encoding of the input.'
|
|
71
|
-
config_param :
|
|
72
|
-
begin
|
|
73
|
-
Encoding.find(encoding_name)
|
|
74
|
-
rescue ArgumentError => e
|
|
75
|
-
raise ConfigError, e.message
|
|
76
|
-
end
|
|
77
|
-
end
|
|
72
|
+
config_param :from_encoding, :string, default: nil
|
|
78
73
|
desc 'Add the log path being tailed to records. Specify the field name to be used.'
|
|
79
74
|
config_param :path_key, :string, default: nil
|
|
80
75
|
|
|
81
76
|
attr_reader :paths
|
|
82
77
|
|
|
83
78
|
def configure(conf)
|
|
79
|
+
compat_parameters_convert(conf, :parser)
|
|
80
|
+
parser_config = conf.elements('parse').first
|
|
81
|
+
unless parser_config
|
|
82
|
+
raise Fluent::ConfigError, "<parse> section is required."
|
|
83
|
+
end
|
|
84
|
+
unless parser_config["@type"]
|
|
85
|
+
raise Fluent::ConfigError, "parse/@type is required."
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
(1..Fluent::Plugin::MultilineParser::FORMAT_MAX_NUM).each do |n|
|
|
89
|
+
parser_config["format#{n}"] = conf["format#{n}"] if conf["format#{n}"]
|
|
90
|
+
end
|
|
91
|
+
|
|
84
92
|
super
|
|
85
93
|
|
|
86
94
|
@paths = @path.split(',').map {|path| path.strip }
|
|
87
95
|
if @paths.empty?
|
|
88
|
-
raise ConfigError, "tail: 'path' parameter is required on tail input"
|
|
96
|
+
raise Fluent::ConfigError, "tail: 'path' parameter is required on tail input"
|
|
89
97
|
end
|
|
90
98
|
|
|
91
99
|
unless @pos_file
|
|
@@ -93,21 +101,17 @@ module Fluent
|
|
|
93
101
|
$log.warn "this parameter is highly recommended to save the position to resume tailing."
|
|
94
102
|
end
|
|
95
103
|
|
|
96
|
-
configure_parser(conf)
|
|
97
104
|
configure_tag
|
|
105
|
+
configure_encoding
|
|
98
106
|
|
|
99
|
-
@multiline_mode =
|
|
107
|
+
@multiline_mode = parser_config["@type"] =~ /multiline/
|
|
100
108
|
@receive_handler = if @multiline_mode
|
|
101
109
|
method(:parse_multilines)
|
|
102
110
|
else
|
|
103
111
|
method(:parse_singleline)
|
|
104
112
|
end
|
|
105
113
|
@file_perm = system_config.file_permission || FILE_PERMISSION
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def configure_parser(conf)
|
|
109
|
-
@parser = Plugin.new_parser(conf['format'])
|
|
110
|
-
@parser.configure(conf)
|
|
114
|
+
@parser = parser_create(conf: parser_config)
|
|
111
115
|
end
|
|
112
116
|
|
|
113
117
|
def configure_tag
|
|
@@ -120,6 +124,25 @@ module Fluent
|
|
|
120
124
|
end
|
|
121
125
|
end
|
|
122
126
|
|
|
127
|
+
def configure_encoding
|
|
128
|
+
unless @encoding
|
|
129
|
+
if @from_encoding
|
|
130
|
+
raise Fluent::ConfigError, "tail: 'from_encoding' parameter must be specified with 'encoding' parameter."
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
@encoding = parse_encoding_param(@encoding) if @encoding
|
|
135
|
+
@from_encoding = parse_encoding_param(@from_encoding) if @from_encoding
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def parse_encoding_param(encoding_name)
|
|
139
|
+
begin
|
|
140
|
+
Encoding.find(encoding_name) if encoding_name
|
|
141
|
+
rescue ArgumentError => e
|
|
142
|
+
raise Fluent::ConfigError, e.message
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
123
146
|
def start
|
|
124
147
|
super
|
|
125
148
|
|
|
@@ -129,20 +152,12 @@ module Fluent
|
|
|
129
152
|
@pf = PositionFile.parse(@pf_file)
|
|
130
153
|
end
|
|
131
154
|
|
|
132
|
-
@loop = Coolio::Loop.new
|
|
133
155
|
refresh_watchers
|
|
134
|
-
|
|
135
|
-
@refresh_trigger = TailWatcher::TimerWatcher.new(@refresh_interval, true, log, &method(:refresh_watchers))
|
|
136
|
-
@refresh_trigger.attach(@loop)
|
|
137
|
-
@thread = Thread.new(&method(:run))
|
|
156
|
+
timer_execute(:in_tail_refresh_watchers, @refresh_interval, &method(:refresh_watchers))
|
|
138
157
|
end
|
|
139
158
|
|
|
140
159
|
def shutdown
|
|
141
|
-
@refresh_trigger.detach if @refresh_trigger && @refresh_trigger.attached?
|
|
142
|
-
|
|
143
160
|
stop_watchers(@tails.keys, true)
|
|
144
|
-
@loop.stop rescue nil # when all watchers are detached, `stop` raises RuntimeError. We can ignore this exception.
|
|
145
|
-
@thread.join
|
|
146
161
|
@pf_file.close if @pf_file
|
|
147
162
|
|
|
148
163
|
super
|
|
@@ -190,8 +205,11 @@ module Fluent
|
|
|
190
205
|
|
|
191
206
|
def setup_watcher(path, pe)
|
|
192
207
|
line_buffer_timer_flusher = (@multiline_mode && @multiline_flush_interval) ? TailWatcher::LineBufferTimerFlusher.new(log, @multiline_flush_interval, &method(:flush_buffer)) : nil
|
|
193
|
-
tw = TailWatcher.new(path, @rotate_wait, pe, log, @read_from_head, @enable_watch_timer, @read_lines_limit, method(:update_watcher), line_buffer_timer_flusher,
|
|
194
|
-
tw.attach
|
|
208
|
+
tw = TailWatcher.new(path, @rotate_wait, pe, log, @read_from_head, @enable_watch_timer, @read_lines_limit, method(:update_watcher), line_buffer_timer_flusher, &method(:receive_lines))
|
|
209
|
+
tw.attach do |watcher|
|
|
210
|
+
timer_execute(:in_tail_timer_trigger, 1, &watcher.method(:on_notify)) if watcher.enable_watch_timer
|
|
211
|
+
event_loop_attach(watcher.stat_trigger)
|
|
212
|
+
end
|
|
195
213
|
tw
|
|
196
214
|
end
|
|
197
215
|
|
|
@@ -202,7 +220,7 @@ module Fluent
|
|
|
202
220
|
pe = @pf[path]
|
|
203
221
|
if @read_from_head && pe.read_inode.zero?
|
|
204
222
|
begin
|
|
205
|
-
pe.update(FileWrapper.stat(path).ino, 0)
|
|
223
|
+
pe.update(Fluent::FileWrapper.stat(path).ino, 0)
|
|
206
224
|
rescue Errno::ENOENT
|
|
207
225
|
$log.warn "#{path} not found. Continuing without tailing it."
|
|
208
226
|
end
|
|
@@ -247,14 +265,21 @@ module Fluent
|
|
|
247
265
|
end
|
|
248
266
|
|
|
249
267
|
def close_watcher_after_rotate_wait(tw)
|
|
250
|
-
|
|
251
|
-
|
|
268
|
+
timer_execute(:in_tail_close_watcher, @rotate_wait, repeat: false) do
|
|
269
|
+
close_watcher(tw)
|
|
270
|
+
end
|
|
252
271
|
end
|
|
253
272
|
|
|
254
273
|
def flush_buffer(tw)
|
|
255
274
|
if lb = tw.line_buffer
|
|
256
275
|
lb.chomp!
|
|
257
|
-
|
|
276
|
+
if @encoding
|
|
277
|
+
if @from_encoding
|
|
278
|
+
lb.encode!(@encoding, @from_encoding)
|
|
279
|
+
else
|
|
280
|
+
lb.force_encoding(@encoding)
|
|
281
|
+
end
|
|
282
|
+
end
|
|
258
283
|
@parser.parse(lb) { |time, record|
|
|
259
284
|
if time && record
|
|
260
285
|
tag = if @tag_prefix || @tag_suffix
|
|
@@ -271,13 +296,6 @@ module Fluent
|
|
|
271
296
|
end
|
|
272
297
|
end
|
|
273
298
|
|
|
274
|
-
def run
|
|
275
|
-
@loop.run
|
|
276
|
-
rescue
|
|
277
|
-
log.error "unexpected error", error: $!.to_s
|
|
278
|
-
log.error_backtrace
|
|
279
|
-
end
|
|
280
|
-
|
|
281
299
|
# @return true if no error or unrecoverable error happens in emit action. false if got BufferOverflowError
|
|
282
300
|
def receive_lines(lines, tail_watcher)
|
|
283
301
|
es = @receive_handler.call(lines, tail_watcher)
|
|
@@ -303,7 +321,13 @@ module Fluent
|
|
|
303
321
|
def convert_line_to_event(line, es, tail_watcher)
|
|
304
322
|
begin
|
|
305
323
|
line.chomp! # remove \n
|
|
306
|
-
|
|
324
|
+
if @encoding
|
|
325
|
+
if @from_encoding
|
|
326
|
+
line.encode!(@encoding, @from_encoding)
|
|
327
|
+
else
|
|
328
|
+
line.force_encoding(@encoding)
|
|
329
|
+
end
|
|
330
|
+
end
|
|
307
331
|
@parser.parse(line) { |time, record|
|
|
308
332
|
if time && record
|
|
309
333
|
record[@path_key] ||= tail_watcher.path unless @path_key.nil?
|
|
@@ -319,7 +343,7 @@ module Fluent
|
|
|
319
343
|
end
|
|
320
344
|
|
|
321
345
|
def parse_singleline(lines, tail_watcher)
|
|
322
|
-
es = MultiEventStream.new
|
|
346
|
+
es = Fluent::MultiEventStream.new
|
|
323
347
|
lines.each { |line|
|
|
324
348
|
convert_line_to_event(line, es, tail_watcher)
|
|
325
349
|
}
|
|
@@ -328,7 +352,7 @@ module Fluent
|
|
|
328
352
|
|
|
329
353
|
def parse_multilines(lines, tail_watcher)
|
|
330
354
|
lb = tail_watcher.line_buffer
|
|
331
|
-
es = MultiEventStream.new
|
|
355
|
+
es = Fluent::MultiEventStream.new
|
|
332
356
|
if @parser.has_firstline?
|
|
333
357
|
tail_watcher.line_buffer_timer_flusher.reset_timer if tail_watcher.line_buffer_timer_flusher
|
|
334
358
|
lines.each { |line|
|
|
@@ -372,8 +396,6 @@ module Fluent
|
|
|
372
396
|
@receive_lines = receive_lines
|
|
373
397
|
@update_watcher = update_watcher
|
|
374
398
|
|
|
375
|
-
@timer_trigger = TimerWatcher.new(1, true, log, &method(:on_notify)) if @enable_watch_timer
|
|
376
|
-
|
|
377
399
|
@stat_trigger = StatWatcher.new(path, log, &method(:on_notify))
|
|
378
400
|
|
|
379
401
|
@rotate_handler = RotateHandler.new(path, log, &method(:on_rotate))
|
|
@@ -384,6 +406,8 @@ module Fluent
|
|
|
384
406
|
end
|
|
385
407
|
|
|
386
408
|
attr_reader :path
|
|
409
|
+
attr_reader :stat_trigger, :enable_watch_timer
|
|
410
|
+
attr_accessor :timer_trigger
|
|
387
411
|
attr_accessor :line_buffer, :line_buffer_timer_flusher
|
|
388
412
|
attr_accessor :unwatched # This is used for removing position entry from PositionFile
|
|
389
413
|
|
|
@@ -395,14 +419,12 @@ module Fluent
|
|
|
395
419
|
@receive_lines.call(lines, self)
|
|
396
420
|
end
|
|
397
421
|
|
|
398
|
-
def attach
|
|
399
|
-
|
|
400
|
-
@stat_trigger.attach(loop)
|
|
422
|
+
def attach
|
|
423
|
+
yield self
|
|
401
424
|
on_notify
|
|
402
425
|
end
|
|
403
426
|
|
|
404
427
|
def detach
|
|
405
|
-
@timer_trigger.detach if @enable_watch_timer && @timer_trigger.attached?
|
|
406
428
|
@stat_trigger.detach if @stat_trigger.attached?
|
|
407
429
|
end
|
|
408
430
|
|
|
@@ -495,22 +517,6 @@ module Fluent
|
|
|
495
517
|
pe # This pe will be updated in on_rotate after TailWatcher is initialized
|
|
496
518
|
end
|
|
497
519
|
|
|
498
|
-
class TimerWatcher < Coolio::TimerWatcher
|
|
499
|
-
def initialize(interval, repeat, log, &callback)
|
|
500
|
-
@callback = callback
|
|
501
|
-
@log = log
|
|
502
|
-
super(interval, repeat)
|
|
503
|
-
end
|
|
504
|
-
|
|
505
|
-
def on_timer
|
|
506
|
-
@callback.call
|
|
507
|
-
rescue
|
|
508
|
-
# TODO log?
|
|
509
|
-
@log.error $!.to_s
|
|
510
|
-
@log.error_backtrace
|
|
511
|
-
end
|
|
512
|
-
end
|
|
513
|
-
|
|
514
520
|
class StatWatcher < Coolio::StatWatcher
|
|
515
521
|
def initialize(path, log, &callback)
|
|
516
522
|
@callback = callback
|
|
@@ -527,24 +533,6 @@ module Fluent
|
|
|
527
533
|
end
|
|
528
534
|
end
|
|
529
535
|
|
|
530
|
-
class Closer < Coolio::TimerWatcher
|
|
531
|
-
def initialize(interval, tw, log, &callback)
|
|
532
|
-
@callback = callback
|
|
533
|
-
@tw = tw
|
|
534
|
-
@log = log
|
|
535
|
-
super(interval, false)
|
|
536
|
-
end
|
|
537
|
-
|
|
538
|
-
def on_timer
|
|
539
|
-
@callback.call(@tw)
|
|
540
|
-
rescue => e
|
|
541
|
-
@log.error e.to_s
|
|
542
|
-
@log.error_backtrace(e.backtrace)
|
|
543
|
-
ensure
|
|
544
|
-
detach
|
|
545
|
-
end
|
|
546
|
-
end
|
|
547
|
-
|
|
548
536
|
class IOHandler
|
|
549
537
|
def initialize(io, pe, log, read_lines_limit, first = true, &receive_lines)
|
|
550
538
|
@log = log
|
|
@@ -632,7 +620,7 @@ module Fluent
|
|
|
632
620
|
|
|
633
621
|
def on_notify
|
|
634
622
|
begin
|
|
635
|
-
stat = FileWrapper.stat(@path)
|
|
623
|
+
stat = Fluent::FileWrapper.stat(@path)
|
|
636
624
|
inode = stat.ino
|
|
637
625
|
fsize = stat.size
|
|
638
626
|
rescue Errno::ENOENT
|
|
@@ -645,7 +633,7 @@ module Fluent
|
|
|
645
633
|
if @inode != inode || fsize < @fsize
|
|
646
634
|
# rotated or truncated
|
|
647
635
|
begin
|
|
648
|
-
io = FileWrapper.open(@path)
|
|
636
|
+
io = Fluent::FileWrapper.open(@path)
|
|
649
637
|
rescue Errno::ENOENT
|
|
650
638
|
end
|
|
651
639
|
@on_rotate.call(io)
|
|
@@ -660,7 +648,6 @@ module Fluent
|
|
|
660
648
|
end
|
|
661
649
|
end
|
|
662
650
|
|
|
663
|
-
|
|
664
651
|
class LineBufferTimerFlusher
|
|
665
652
|
def initialize(log, flush_interval, &flush_method)
|
|
666
653
|
@log = log
|
|
@@ -685,7 +672,6 @@ module Fluent
|
|
|
685
672
|
end
|
|
686
673
|
end
|
|
687
674
|
|
|
688
|
-
|
|
689
675
|
class PositionFile
|
|
690
676
|
UNWATCHED_POSITION = 0xffffffffffffffff
|
|
691
677
|
|
|
@@ -805,6 +791,4 @@ module Fluent
|
|
|
805
791
|
end
|
|
806
792
|
end
|
|
807
793
|
end
|
|
808
|
-
|
|
809
|
-
NewTailInput = TailInput # for backward compatibility
|
|
810
794
|
end
|