fluentd 0.14.20.rc1 → 0.14.20
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/ChangeLog +20 -0
- data/fluentd.gemspec +1 -0
- data/lib/fluent/log.rb +88 -15
- data/lib/fluent/plugin/filter_grep.rb +28 -12
- data/lib/fluent/plugin/in_syslog.rb +1 -1
- data/lib/fluent/plugin/output.rb +1 -1
- data/lib/fluent/plugin_helper.rb +1 -0
- data/lib/fluent/plugin_helper/record_accessor.rb +172 -0
- data/lib/fluent/supervisor.rb +24 -12
- data/lib/fluent/system_config.rb +4 -0
- data/lib/fluent/version.rb +1 -1
- data/test/config/test_system_config.rb +18 -0
- data/test/plugin/test_filter_grep.rb +58 -2
- data/test/plugin/test_output.rb +1 -1
- data/test/plugin_helper/test_record_accessor.rb +108 -0
- data/test/test_log.rb +50 -0
- data/test/test_supervisor.rb +6 -0
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 419af849ffe16bdb83d13106862b94018d71dca1
|
4
|
+
data.tar.gz: 6f1435c4d5f9f1645267bb88f43aa86ee838075e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96ff26acaccd6870648fd36ca991e101058296abfa8585366c0b132d94a19c79ef75214527c026b3719061c943d0d0aeaec45c3bb58655b3f08f7da88d5a6aa6
|
7
|
+
data.tar.gz: a83370feeeabb3f9a3200f5575ce8ba9f4fe0a57349b9fe73dfd3f6b386492993483412883f91214b8903709a86dcacccac658cf663d1734aa37d5b1e4f5fa21
|
data/ChangeLog
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# v0.14
|
2
2
|
|
3
|
+
## Release v0.14.20 - 2017/07/31
|
4
|
+
|
5
|
+
### New features / Enhancements
|
6
|
+
|
7
|
+
* plugin: Add record_accessor plugin helper
|
8
|
+
https://github.com/fluent/fluentd/pull/1637
|
9
|
+
* log: Add format and time_format parameters to <system> setting
|
10
|
+
https://github.com/fluent/fluentd/pull/1644
|
11
|
+
|
12
|
+
### Bug fixes
|
13
|
+
|
14
|
+
* buf_file: Improve file handling to mitigate broken meta file
|
15
|
+
https://github.com/fluent/fluentd/pull/1628
|
16
|
+
* in_syslog: Fix the description of resolve_hostname parameter
|
17
|
+
https://github.com/fluent/fluentd/pull/1633
|
18
|
+
* process: Fix signal handling. Send signal to all workers
|
19
|
+
https://github.com/fluent/fluentd/pull/1642
|
20
|
+
* output: Fix error message typo
|
21
|
+
https://github.com/fluent/fluentd/pull/1643
|
22
|
+
|
3
23
|
## Release v0.14.19 - 2017/07/12
|
4
24
|
|
5
25
|
### New features / Enhancements
|
data/fluentd.gemspec
CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |gem|
|
|
28
28
|
gem.add_runtime_dependency("tzinfo", ["~> 1.0"])
|
29
29
|
gem.add_runtime_dependency("tzinfo-data", ["~> 1.0"])
|
30
30
|
gem.add_runtime_dependency("strptime", ["~> 0.1.7"])
|
31
|
+
gem.add_runtime_dependency("ruby_dig", ["~> 0.0.2"])
|
31
32
|
|
32
33
|
# build gem for a certain platform. see also Rakefile
|
33
34
|
fake_platform = ENV['GEM_BUILD_FAKE_PLATFORM'].to_s
|
data/lib/fluent/log.rb
CHANGED
@@ -96,8 +96,12 @@ module Fluent
|
|
96
96
|
@level = logger.level + 1
|
97
97
|
@debug_mode = false
|
98
98
|
@log_event_enabled = false
|
99
|
-
@time_format = '%Y-%m-%d %H:%M:%S %z '
|
100
99
|
@depth_offset = 1
|
100
|
+
@format = nil
|
101
|
+
@time_format = nil
|
102
|
+
@formatter = nil
|
103
|
+
|
104
|
+
self.format = :text
|
101
105
|
enable_color out.tty?
|
102
106
|
# TODO: This variable name is unclear so we should change to better name.
|
103
107
|
@threads_exclude_events = []
|
@@ -136,12 +140,14 @@ module Fluent
|
|
136
140
|
dl_opts[:log_level] = @level - 1
|
137
141
|
logger = ServerEngine::DaemonLogger.new(@out, dl_opts)
|
138
142
|
clone = self.class.new(logger, suppress_repeated_stacktrace: @suppress_repeated_stacktrace, process_type: @process_type, worker_id: @worker_id)
|
143
|
+
clone.format = @format
|
139
144
|
clone.time_format = @time_format
|
140
145
|
clone.log_event_enabled = @log_event_enabled
|
141
146
|
# optional headers/attrs are not copied, because new PluginLogger should have another one of it
|
142
147
|
clone
|
143
148
|
end
|
144
149
|
|
150
|
+
attr_reader :format
|
145
151
|
attr_accessor :log_event_enabled
|
146
152
|
attr_accessor :out
|
147
153
|
attr_accessor :level
|
@@ -154,6 +160,37 @@ module Fluent
|
|
154
160
|
nil
|
155
161
|
end
|
156
162
|
|
163
|
+
def format=(fmt)
|
164
|
+
return if @format == fmt
|
165
|
+
|
166
|
+
case fmt
|
167
|
+
when :text
|
168
|
+
@format = :text
|
169
|
+
@time_format = '%Y-%m-%d %H:%M:%S %z'
|
170
|
+
@formatter = Proc.new { |type, time, level, msg|
|
171
|
+
r = caller_line(type, time, @depth_offset, level)
|
172
|
+
r << msg
|
173
|
+
r
|
174
|
+
}
|
175
|
+
when :json
|
176
|
+
@format = :json
|
177
|
+
@time_format = '%Y-%m-%d %H:%M:%S %z'
|
178
|
+
@formatter = Proc.new { |type, time, level, msg|
|
179
|
+
r = {
|
180
|
+
'time' => time.strftime(@time_format),
|
181
|
+
'level' => LEVEL_TEXT[level],
|
182
|
+
'message' => msg
|
183
|
+
}
|
184
|
+
if wid = get_worker_id(type)
|
185
|
+
r['worker_id'] = wid
|
186
|
+
end
|
187
|
+
Yajl.dump(r)
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
nil
|
192
|
+
end
|
193
|
+
|
157
194
|
def reopen!
|
158
195
|
# do nothing in @logger.reopen! because it's already reopened in Supervisor.load_config
|
159
196
|
@logger.reopen! if @logger
|
@@ -235,7 +272,7 @@ module Fluent
|
|
235
272
|
return if skipped_type?(type)
|
236
273
|
args << block.call if block
|
237
274
|
time, msg = event(:trace, args)
|
238
|
-
puts [@color_trace,
|
275
|
+
puts [@color_trace, @formatter.call(type, time, LEVEL_TRACE, msg), @color_reset].join
|
239
276
|
rescue
|
240
277
|
# logger should not raise an exception. This rescue prevents unexpected behaviour.
|
241
278
|
end
|
@@ -256,7 +293,7 @@ module Fluent
|
|
256
293
|
return if skipped_type?(type)
|
257
294
|
args << block.call if block
|
258
295
|
time, msg = event(:debug, args)
|
259
|
-
puts [@color_debug,
|
296
|
+
puts [@color_debug, @formatter.call(type, time, LEVEL_DEBUG, msg), @color_reset].join
|
260
297
|
rescue
|
261
298
|
end
|
262
299
|
alias DEBUG debug
|
@@ -276,7 +313,7 @@ module Fluent
|
|
276
313
|
return if skipped_type?(type)
|
277
314
|
args << block.call if block
|
278
315
|
time, msg = event(:info, args)
|
279
|
-
puts [@color_info,
|
316
|
+
puts [@color_info, @formatter.call(type, time, LEVEL_INFO, msg), @color_reset].join
|
280
317
|
rescue
|
281
318
|
end
|
282
319
|
alias INFO info
|
@@ -296,7 +333,7 @@ module Fluent
|
|
296
333
|
return if skipped_type?(type)
|
297
334
|
args << block.call if block
|
298
335
|
time, msg = event(:warn, args)
|
299
|
-
puts [@color_warn,
|
336
|
+
puts [@color_warn, @formatter.call(type, time, LEVEL_WARN, msg), @color_reset].join
|
300
337
|
rescue
|
301
338
|
end
|
302
339
|
alias WARN warn
|
@@ -316,7 +353,7 @@ module Fluent
|
|
316
353
|
return if skipped_type?(type)
|
317
354
|
args << block.call if block
|
318
355
|
time, msg = event(:error, args)
|
319
|
-
puts [@color_error,
|
356
|
+
puts [@color_error, @formatter.call(type, time, LEVEL_ERROR, msg), @color_reset].join
|
320
357
|
rescue
|
321
358
|
end
|
322
359
|
alias ERROR error
|
@@ -336,7 +373,7 @@ module Fluent
|
|
336
373
|
return if skipped_type?(type)
|
337
374
|
args << block.call if block
|
338
375
|
time, msg = event(:fatal, args)
|
339
|
-
puts [@color_fatal,
|
376
|
+
puts [@color_fatal, @formatter.call(type, time, LEVEL_FATAL, msg), @color_reset].join
|
340
377
|
rescue
|
341
378
|
end
|
342
379
|
alias FATAL fatal
|
@@ -373,19 +410,47 @@ module Fluent
|
|
373
410
|
return if @level > level
|
374
411
|
|
375
412
|
time = Time.now
|
376
|
-
|
377
|
-
if @
|
378
|
-
|
413
|
+
|
414
|
+
if @format == :text
|
415
|
+
line = caller_line(type, time, 5, level)
|
416
|
+
if @suppress_repeated_stacktrace && (Thread.current[:last_repeated_stacktrace] == backtrace)
|
417
|
+
puts [" ", line, 'suppressed same stacktrace'].join
|
418
|
+
else
|
419
|
+
backtrace.each { |msg|
|
420
|
+
puts [" ", line, msg].join
|
421
|
+
}
|
422
|
+
Thread.current[:last_repeated_stacktrace] = backtrace if @suppress_repeated_stacktrace
|
423
|
+
end
|
379
424
|
else
|
380
|
-
|
381
|
-
|
425
|
+
r = {
|
426
|
+
'time' => time.strftime(@time_format),
|
427
|
+
'level' => LEVEL_TEXT[level],
|
382
428
|
}
|
383
|
-
|
429
|
+
if wid = get_worker_id(type)
|
430
|
+
r['worker_id'] = wid
|
431
|
+
end
|
432
|
+
|
433
|
+
if @suppress_repeated_stacktrace && (Thread.current[:last_repeated_stacktrace] == backtrace)
|
434
|
+
r['message'] = 'suppressed same stacktrace'
|
435
|
+
else
|
436
|
+
r['message'] = backtrace.join("\n")
|
437
|
+
Thread.current[:last_repeated_stacktrace] = backtrace if @suppress_repeated_stacktrace
|
438
|
+
end
|
439
|
+
|
440
|
+
puts Yajl.dump(r)
|
384
441
|
end
|
385
442
|
|
386
443
|
nil
|
387
444
|
end
|
388
445
|
|
446
|
+
def get_worker_id(type)
|
447
|
+
if type == :default && (@process_type == :worker0 || @process_type == :workers)
|
448
|
+
@worker_id
|
449
|
+
else
|
450
|
+
nil
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
389
454
|
def event(level, args)
|
390
455
|
time = Time.now
|
391
456
|
message = @optional_header ? @optional_header.dup : ''
|
@@ -426,7 +491,7 @@ module Fluent
|
|
426
491
|
else
|
427
492
|
"".freeze
|
428
493
|
end
|
429
|
-
log_msg = "#{time.strftime(@time_format)}[#{LEVEL_TEXT[level]}]: #{worker_id_part}"
|
494
|
+
log_msg = "#{time.strftime(@time_format)} [#{LEVEL_TEXT[level]}]: #{worker_id_part}"
|
430
495
|
if @debug_mode
|
431
496
|
line = caller(depth+1)[0]
|
432
497
|
if match = /^(.+?):(\d+)(?::in `(.*)')?/.match(line)
|
@@ -450,11 +515,13 @@ module Fluent
|
|
450
515
|
def initialize(logger)
|
451
516
|
@logger = logger
|
452
517
|
@level = @logger.level
|
518
|
+
@format = nil
|
453
519
|
@depth_offset = 2
|
454
520
|
if logger.instance_variable_defined?(:@suppress_repeated_stacktrace)
|
455
521
|
@suppress_repeated_stacktrace = logger.instance_variable_get(:@suppress_repeated_stacktrace)
|
456
522
|
end
|
457
523
|
|
524
|
+
self.format = @logger.format
|
458
525
|
enable_color @logger.enable_color?
|
459
526
|
end
|
460
527
|
|
@@ -462,15 +529,21 @@ module Fluent
|
|
462
529
|
@level = Log.str_to_level(log_level_str)
|
463
530
|
end
|
464
531
|
|
532
|
+
alias orig_format= format=
|
465
533
|
alias orig_enable_color enable_color
|
466
534
|
|
535
|
+
def format=(fmt)
|
536
|
+
self.orig_format = fmt
|
537
|
+
@logger.format = fmt
|
538
|
+
end
|
539
|
+
|
467
540
|
def enable_color(b = true)
|
468
541
|
orig_enable_color b
|
469
542
|
@logger.enable_color b
|
470
543
|
end
|
471
544
|
|
472
545
|
extend Forwardable
|
473
|
-
def_delegators '@logger', :enable_color?, :enable_debug, :enable_event,
|
546
|
+
def_delegators '@logger', :get_worker_id, :enable_color?, :enable_debug, :enable_event,
|
474
547
|
:disable_events, :log_event_enabled, :log_event_enamed=, :time_format, :time_format=,
|
475
548
|
:event, :caller_line, :puts, :write, :<<, :flush, :reset, :out, :out=,
|
476
549
|
:optional_header, :optional_header=, :optional_attrs, :optional_attrs=
|
@@ -22,6 +22,15 @@ module Fluent::Plugin
|
|
22
22
|
class GrepFilter < Filter
|
23
23
|
Fluent::Plugin.register_filter('grep', self)
|
24
24
|
|
25
|
+
def initialize
|
26
|
+
super
|
27
|
+
|
28
|
+
@_regexps = {}
|
29
|
+
@_excludes = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
helpers :record_accessor
|
33
|
+
|
25
34
|
REGEXP_MAX_NUM = 20
|
26
35
|
|
27
36
|
(1..REGEXP_MAX_NUM).each {|i| config_param :"regexp#{i}", :string, default: nil, deprecated: "Use <regexp> section" }
|
@@ -52,31 +61,38 @@ module Fluent::Plugin
|
|
52
61
|
def configure(conf)
|
53
62
|
super
|
54
63
|
|
55
|
-
|
64
|
+
rs = {}
|
56
65
|
(1..REGEXP_MAX_NUM).each do |i|
|
57
66
|
next unless conf["regexp#{i}"]
|
58
67
|
key, regexp = conf["regexp#{i}"].split(/ /, 2)
|
59
68
|
raise Fluent::ConfigError, "regexp#{i} does not contain 2 parameters" unless regexp
|
60
|
-
raise Fluent::ConfigError, "regexp#{i} contains a duplicated key, #{key}" if
|
61
|
-
|
69
|
+
raise Fluent::ConfigError, "regexp#{i} contains a duplicated key, #{key}" if rs[key]
|
70
|
+
rs[key] = Regexp.compile(regexp)
|
62
71
|
end
|
63
72
|
|
64
|
-
|
73
|
+
es = {}
|
65
74
|
(1..REGEXP_MAX_NUM).each do |i|
|
66
75
|
next unless conf["exclude#{i}"]
|
67
76
|
key, exclude = conf["exclude#{i}"].split(/ /, 2)
|
68
77
|
raise Fluent::ConfigError, "exclude#{i} does not contain 2 parameters" unless exclude
|
69
|
-
raise Fluent::ConfigError, "exclude#{i} contains a duplicated key, #{key}" if
|
70
|
-
|
78
|
+
raise Fluent::ConfigError, "exclude#{i} contains a duplicated key, #{key}" if es[key]
|
79
|
+
es[key] = Regexp.compile(exclude)
|
71
80
|
end
|
72
81
|
|
73
82
|
@regexps.each do |e|
|
74
|
-
raise Fluent::ConfigError, "Duplicate key: #{e.key}" if
|
75
|
-
|
83
|
+
raise Fluent::ConfigError, "Duplicate key: #{e.key}" if rs.key?(e.key)
|
84
|
+
rs[e.key] = e.pattern
|
76
85
|
end
|
77
86
|
@excludes.each do |e|
|
78
|
-
raise Fluent::ConfigError, "Duplicate key: #{e.key}" if
|
79
|
-
|
87
|
+
raise Fluent::ConfigError, "Duplicate key: #{e.key}" if es.key?(e.key)
|
88
|
+
es[e.key] = e.pattern
|
89
|
+
end
|
90
|
+
|
91
|
+
rs.each_pair do |k, v|
|
92
|
+
@_regexps[record_accessor_create(k)] = v
|
93
|
+
end
|
94
|
+
es.each_pair do |k, v|
|
95
|
+
@_excludes[record_accessor_create(k)] = v
|
80
96
|
end
|
81
97
|
end
|
82
98
|
|
@@ -85,10 +101,10 @@ module Fluent::Plugin
|
|
85
101
|
begin
|
86
102
|
catch(:break_loop) do
|
87
103
|
@_regexps.each do |key, regexp|
|
88
|
-
throw :break_loop unless ::Fluent::StringUtil.match_regexp(regexp,
|
104
|
+
throw :break_loop unless ::Fluent::StringUtil.match_regexp(regexp, key.call(record).to_s)
|
89
105
|
end
|
90
106
|
@_excludes.each do |key, exclude|
|
91
|
-
throw :break_loop if ::Fluent::StringUtil.match_regexp(exclude,
|
107
|
+
throw :break_loop if ::Fluent::StringUtil.match_regexp(exclude, key.call(record).to_s)
|
92
108
|
end
|
93
109
|
result = record
|
94
110
|
end
|
@@ -83,8 +83,8 @@ module Fluent::Plugin
|
|
83
83
|
|
84
84
|
desc 'The field name of hostname of sender.'
|
85
85
|
config_param :source_hostname_key, :string, default: nil
|
86
|
+
desc 'Try to resolve hostname from IP addresses or not.'
|
86
87
|
config_param :resolve_hostname, :bool, default: nil
|
87
|
-
desc 'Connections will be disconnected right after receiving first message if this value is true.'
|
88
88
|
desc 'The field name of source address of sender.'
|
89
89
|
config_param :source_address_key, :string, default: nil
|
90
90
|
desc 'The field name of the priority.'
|
data/lib/fluent/plugin/output.rb
CHANGED
@@ -700,7 +700,7 @@ module Fluent
|
|
700
700
|
rvalue = rvalue.gsub(CHUNK_KEY_PLACEHOLDER_PATTERN, hash)
|
701
701
|
end
|
702
702
|
if rvalue =~ CHUNK_KEY_PLACEHOLDER_PATTERN
|
703
|
-
log.warn "chunk key placeholder '#{$1}' not replaced.
|
703
|
+
log.warn "chunk key placeholder '#{$1}' not replaced. template:#{str}"
|
704
704
|
end
|
705
705
|
rvalue
|
706
706
|
end
|
data/lib/fluent/plugin_helper.rb
CHANGED
@@ -27,6 +27,7 @@ require 'fluent/plugin_helper/extract'
|
|
27
27
|
require 'fluent/plugin_helper/socket'
|
28
28
|
require 'fluent/plugin_helper/server'
|
29
29
|
require 'fluent/plugin_helper/retry_state'
|
30
|
+
require 'fluent/plugin_helper/record_accessor'
|
30
31
|
require 'fluent/plugin_helper/compat_parameters'
|
31
32
|
|
32
33
|
module Fluent
|
@@ -0,0 +1,172 @@
|
|
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/config/error'
|
18
|
+
unless {}.respond_to?(:dig)
|
19
|
+
begin
|
20
|
+
# backport_dig is faster than ruby_dig so prefer backport_dig.
|
21
|
+
require 'backport_dig'
|
22
|
+
rescue LoadError
|
23
|
+
require 'ruby_dig'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module Fluent
|
28
|
+
module PluginHelper
|
29
|
+
module RecordAccessor
|
30
|
+
def record_accessor_create(param)
|
31
|
+
Accessor.new(param)
|
32
|
+
end
|
33
|
+
|
34
|
+
class Accessor
|
35
|
+
def initialize(param)
|
36
|
+
@keys = Accessor.parse_parameter(param)
|
37
|
+
|
38
|
+
# Call [] for single key to reduce dig overhead
|
39
|
+
m = method(@keys.is_a?(Array) ? :call_dig : :call_index)
|
40
|
+
(class << self; self; end).module_eval do
|
41
|
+
define_method(:call, m)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def call(r)
|
46
|
+
end
|
47
|
+
|
48
|
+
# To optimize the performance, use class_eval with pre-expanding @keys
|
49
|
+
# See https://gist.github.com/repeatedly/ab553ed260cd080bd01ec71da9427312
|
50
|
+
def call_dig(r)
|
51
|
+
r.dig(*@keys)
|
52
|
+
end
|
53
|
+
|
54
|
+
def call_index(r)
|
55
|
+
r[@keys]
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.parse_parameter(param)
|
59
|
+
if param.start_with?('$.')
|
60
|
+
parse_dot_notation(param)
|
61
|
+
elsif param.start_with?('$[')
|
62
|
+
parse_bracket_notation(param)
|
63
|
+
else
|
64
|
+
param
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.parse_dot_notation(param)
|
69
|
+
result = []
|
70
|
+
keys = param[2..-1].split('.')
|
71
|
+
keys.each { |key|
|
72
|
+
if key.include?('[')
|
73
|
+
result.concat(parse_dot_array_op(key, param))
|
74
|
+
else
|
75
|
+
result << key
|
76
|
+
end
|
77
|
+
}
|
78
|
+
|
79
|
+
raise Fluent::ConfigError, "empty keys in dot notation" if result.empty?
|
80
|
+
validate_dot_keys(result)
|
81
|
+
|
82
|
+
result
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.validate_dot_keys(keys)
|
86
|
+
keys.each { |key|
|
87
|
+
next unless key.is_a?(String)
|
88
|
+
if /\s+/.match(key)
|
89
|
+
raise Fluent::ConfigError, "whitespace character is not allowed in dot notation. Use bracket notation: #{key}"
|
90
|
+
end
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.parse_dot_array_op(key, param)
|
95
|
+
start = key.index('[')
|
96
|
+
result = if start.zero?
|
97
|
+
[]
|
98
|
+
else
|
99
|
+
[key[0..start - 1]]
|
100
|
+
end
|
101
|
+
key = key[start + 1..-1]
|
102
|
+
in_bracket = true
|
103
|
+
|
104
|
+
until key.empty?
|
105
|
+
if in_bracket
|
106
|
+
if i = key.index(']')
|
107
|
+
index_value = key[0..i - 1]
|
108
|
+
raise Fluent::ConfigError, "missing array index in '[]'. Invalid syntax: #{param}" if index_value == ']'
|
109
|
+
result << Integer(index_value)
|
110
|
+
key = key[i + 1..-1]
|
111
|
+
in_bracket = false
|
112
|
+
else
|
113
|
+
raise Fluent::ConfigError, "'[' found but ']' not found. Invalid syntax: #{param}"
|
114
|
+
end
|
115
|
+
else
|
116
|
+
if i = key.index('[')
|
117
|
+
key = key[i + 1..-1]
|
118
|
+
in_bracket = true
|
119
|
+
else
|
120
|
+
raise Fluent::ConfigError, "found more characters after ']'. Invalid syntax: #{param}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
result
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.parse_bracket_notation(param)
|
129
|
+
orig_param = param
|
130
|
+
result = []
|
131
|
+
param = param[1..-1]
|
132
|
+
in_bracket = false
|
133
|
+
|
134
|
+
until param.empty?
|
135
|
+
if in_bracket
|
136
|
+
if param[0] == "'"
|
137
|
+
if i = param.index("']")
|
138
|
+
result << param[1..i - 1]
|
139
|
+
param = param[i + 2..-1]
|
140
|
+
in_bracket = false
|
141
|
+
else
|
142
|
+
raise Fluent::ConfigError, "Incomplete bracket. Invalid syntax: #{orig_param}"
|
143
|
+
end
|
144
|
+
else
|
145
|
+
if i = param.index(']')
|
146
|
+
index_value = param[0..i - 1]
|
147
|
+
raise Fluent::ConfigError, "missing array index in '[]'. Invalid syntax: #{param}" if index_value == ']'
|
148
|
+
result << Integer(index_value)
|
149
|
+
param = param[i + 1..-1]
|
150
|
+
in_bracket = false
|
151
|
+
else
|
152
|
+
raise Fluent::ConfigError, "'[' found but ']' not found. Invalid syntax: #{orig_param}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
else
|
156
|
+
if i = param.index('[')
|
157
|
+
param = param[i + 1..-1]
|
158
|
+
in_bracket = true
|
159
|
+
else
|
160
|
+
raise Fluent::ConfigError, "found more characters after ']'. Invalid syntax: #{orig_param}"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
raise Fluent::ConfigError, "empty keys in bracket notation" if result.empty?
|
166
|
+
|
167
|
+
result
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
data/lib/fluent/supervisor.rb
CHANGED
@@ -163,18 +163,22 @@ module Fluent
|
|
163
163
|
log.reopen!
|
164
164
|
end
|
165
165
|
|
166
|
-
if
|
167
|
-
|
168
|
-
|
166
|
+
if config[:worker_pid]
|
167
|
+
config[:worker_pid].each do |pid|
|
168
|
+
Process.kill(:USR1, pid)
|
169
|
+
# don't rescue Erro::ESRSH here (invalid status)
|
170
|
+
end
|
169
171
|
end
|
170
172
|
end
|
171
173
|
|
172
174
|
def kill_worker
|
173
|
-
if
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
175
|
+
if config[:worker_pid]
|
176
|
+
config[:worker_pid].each do |pid|
|
177
|
+
if Fluent.windows?
|
178
|
+
Process.kill :KILL, pid
|
179
|
+
else
|
180
|
+
Process.kill :TERM, pid
|
181
|
+
end
|
178
182
|
end
|
179
183
|
end
|
180
184
|
end
|
@@ -198,7 +202,7 @@ module Fluent
|
|
198
202
|
end
|
199
203
|
|
200
204
|
def after_start
|
201
|
-
config[:worker_pid]
|
205
|
+
(config[:worker_pid] ||= []).push(@pm.pid)
|
202
206
|
end
|
203
207
|
end
|
204
208
|
|
@@ -360,6 +364,11 @@ module Fluent
|
|
360
364
|
self
|
361
365
|
end
|
362
366
|
|
367
|
+
def apply_options(opts)
|
368
|
+
$log.format = opts[:format] if opts[:format]
|
369
|
+
$log.time_format = opts[:time_format] if opts[:time_format]
|
370
|
+
end
|
371
|
+
|
363
372
|
def level=(level)
|
364
373
|
@level = level
|
365
374
|
$log.level = level
|
@@ -439,6 +448,9 @@ module Fluent
|
|
439
448
|
show_plugin_config if @show_plugin_config
|
440
449
|
read_config
|
441
450
|
set_system_config
|
451
|
+
@log.apply_options(format: @system_config.log.format, time_format: @system_config.log.time_format)
|
452
|
+
|
453
|
+
$log.info :supervisor, "parsing config file is succeeded", path: @config_path
|
442
454
|
|
443
455
|
if @workers < 1
|
444
456
|
raise Fluent::ConfigError, "invalid number of workers (must be > 0):#{@workers}"
|
@@ -485,11 +497,12 @@ module Fluent
|
|
485
497
|
else :workers
|
486
498
|
end
|
487
499
|
@log.init(process_type, worker_id)
|
488
|
-
Process.setproctitle("worker:#{@process_name}") if @process_name
|
489
|
-
|
490
500
|
show_plugin_config if @show_plugin_config
|
491
501
|
read_config
|
492
502
|
set_system_config
|
503
|
+
@log.apply_options(format: @system_config.log.format, time_format: @system_config.log.time_format)
|
504
|
+
|
505
|
+
Process.setproctitle("worker:#{@process_name}") if @process_name
|
493
506
|
|
494
507
|
if @standalone_worker && @workers != 1
|
495
508
|
raise Fluent::ConfigError, "invalid number of workers (must be 1 or unspecified) with --no-supervisor: #{@workers}"
|
@@ -715,7 +728,6 @@ module Fluent
|
|
715
728
|
end
|
716
729
|
|
717
730
|
def read_config
|
718
|
-
$log.info :supervisor, "reading config file", path: @config_path
|
719
731
|
@config_fname = File.basename(@config_path)
|
720
732
|
@config_basedir = File.dirname(@config_path)
|
721
733
|
@config_data = File.open(@config_path, "r:utf-8:utf-8") {|f| f.read }
|
data/lib/fluent/system_config.rb
CHANGED
@@ -46,6 +46,10 @@ module Fluent
|
|
46
46
|
config_param :dir_permission, default: nil do |v|
|
47
47
|
v.to_i(8)
|
48
48
|
end
|
49
|
+
config_section :log, required: false, init: true, multi: false do
|
50
|
+
config_param :format, :enum, list: [:text, :json], default: :text
|
51
|
+
config_param :time_format, :string, default: '%Y-%m-%d %H:%M:%S %z'
|
52
|
+
end
|
49
53
|
|
50
54
|
def self.create(conf)
|
51
55
|
systems = conf.elements(name: 'system')
|
data/lib/fluent/version.rb
CHANGED
@@ -55,6 +55,8 @@ module Fluent::Config
|
|
55
55
|
assert_nil(sc.emit_error_log_interval)
|
56
56
|
assert_nil(sc.suppress_config_dump)
|
57
57
|
assert_nil(sc.without_source)
|
58
|
+
assert_equal(:text, sc.log.format)
|
59
|
+
assert_equal('%Y-%m-%d %H:%M:%S %z', sc.log.time_format)
|
58
60
|
assert_equal(1, s.instance_variable_get(:@workers))
|
59
61
|
assert_nil(s.instance_variable_get(:@root_dir))
|
60
62
|
assert_equal(Fluent::Log::LEVEL_INFO, s.instance_variable_get(:@log_level))
|
@@ -91,6 +93,22 @@ module Fluent::Config
|
|
91
93
|
assert_not_nil(s.instance_variable_get("@#{key}"))
|
92
94
|
end
|
93
95
|
|
96
|
+
test "log parameters" do
|
97
|
+
conf = parse_text(<<-EOS)
|
98
|
+
<system>
|
99
|
+
<log>
|
100
|
+
format json
|
101
|
+
time_format %Y
|
102
|
+
</log>
|
103
|
+
</system>
|
104
|
+
EOS
|
105
|
+
s = FakeSupervisor.new
|
106
|
+
sc = Fluent::SystemConfig.new(conf)
|
107
|
+
sc.apply(s)
|
108
|
+
assert_equal(:json, sc.log.format)
|
109
|
+
assert_equal('%Y', sc.log.time_format)
|
110
|
+
end
|
111
|
+
|
94
112
|
data(
|
95
113
|
'foo' => ['foo', 'bar'],
|
96
114
|
'hoge' => ['hoge', 'fuga'],
|
@@ -23,12 +23,16 @@ class GrepFilterTest < Test::Unit::TestCase
|
|
23
23
|
|
24
24
|
test "regexpN can contain a space" do
|
25
25
|
d = create_driver(%[regexp1 message foo])
|
26
|
-
|
26
|
+
d.instance._regexps.each_pair { |key, value|
|
27
|
+
assert_equal(Regexp.compile(/ foo/), value)
|
28
|
+
}
|
27
29
|
end
|
28
30
|
|
29
31
|
test "excludeN can contain a space" do
|
30
32
|
d = create_driver(%[exclude1 message foo])
|
31
|
-
|
33
|
+
d.instance._excludes.each_pair { |key, value|
|
34
|
+
assert_equal(Regexp.compile(/ foo/), value)
|
35
|
+
}
|
32
36
|
end
|
33
37
|
|
34
38
|
sub_test_case "duplicate key" do
|
@@ -163,6 +167,58 @@ class GrepFilterTest < Test::Unit::TestCase
|
|
163
167
|
end
|
164
168
|
end
|
165
169
|
|
170
|
+
sub_test_case 'nested keys' do
|
171
|
+
def messages
|
172
|
+
[
|
173
|
+
{"nest1" => {"nest2" => "INFO"}},
|
174
|
+
{"nest1" => {"nest2" => "WARN"}},
|
175
|
+
{"nest1" => {"nest2" => "WARN"}}
|
176
|
+
]
|
177
|
+
end
|
178
|
+
|
179
|
+
def filter(config, msgs)
|
180
|
+
d = create_driver(config)
|
181
|
+
d.run {
|
182
|
+
msgs.each { |msg|
|
183
|
+
d.feed("filter.test", @time, {'foo' => 'bar', 'message' => msg})
|
184
|
+
}
|
185
|
+
}
|
186
|
+
d.filtered_records
|
187
|
+
end
|
188
|
+
|
189
|
+
test 'regexps' do
|
190
|
+
conf = %[
|
191
|
+
<regexp>
|
192
|
+
key $.message.nest1.nest2
|
193
|
+
pattern WARN
|
194
|
+
</regexp>
|
195
|
+
]
|
196
|
+
filtered_records = filter(conf, messages)
|
197
|
+
assert_equal(2, filtered_records.size)
|
198
|
+
assert_block('only 2 nested logs') do
|
199
|
+
filtered_records.all? { |r|
|
200
|
+
r['message']['nest1']['nest2'] == 'WARN'
|
201
|
+
}
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
test 'excludes' do
|
206
|
+
conf = %[
|
207
|
+
<exclude>
|
208
|
+
key $.message.nest1.nest2
|
209
|
+
pattern WARN
|
210
|
+
</exclude>
|
211
|
+
]
|
212
|
+
filtered_records = filter(conf, messages)
|
213
|
+
assert_equal(1, filtered_records.size)
|
214
|
+
assert_block('only 2 nested logs') do
|
215
|
+
filtered_records.all? { |r|
|
216
|
+
r['message']['nest1']['nest2'] == 'INFO'
|
217
|
+
}
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
166
222
|
sub_test_case 'grep non-string jsonable values' do
|
167
223
|
def filter(msg, config = 'regexp1 message 0')
|
168
224
|
d = create_driver(config)
|
data/test/plugin/test_output.rb
CHANGED
@@ -372,7 +372,7 @@ class OutputTest < Test::Unit::TestCase
|
|
372
372
|
end
|
373
373
|
|
374
374
|
sub_test_case '#placeholder_validate!' do
|
375
|
-
test 'raises configuration error for a
|
375
|
+
test 'raises configuration error for a template when timestamp placeholders exist but time key is missing' do
|
376
376
|
@i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
|
377
377
|
assert_raise Fluent::ConfigError.new("Parameter 'path: /path/without/timestamp/file.%Y%m%d-%H%M.log' has timestamp placeholders, but chunk key 'time' is not configured") do
|
378
378
|
@i.placeholder_validate!(:path, "/path/without/timestamp/file.%Y%m%d-%H%M.log")
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require 'fluent/plugin_helper/record_accessor'
|
3
|
+
require 'fluent/plugin/base'
|
4
|
+
|
5
|
+
require 'time'
|
6
|
+
|
7
|
+
class RecordAccessorHelperTest < Test::Unit::TestCase
|
8
|
+
class Dummy < Fluent::Plugin::TestBase
|
9
|
+
helpers :record_accessor
|
10
|
+
end
|
11
|
+
|
12
|
+
sub_test_case 'parse nested key expression' do
|
13
|
+
data('normal' => 'key1',
|
14
|
+
'space' => 'ke y2',
|
15
|
+
'dot key' => 'this.is.key3')
|
16
|
+
test 'parse single key' do |param|
|
17
|
+
result = Fluent::PluginHelper::RecordAccessor::Accessor.parse_parameter(param)
|
18
|
+
assert_equal param, result
|
19
|
+
end
|
20
|
+
|
21
|
+
test "nested bracket keys with dot" do
|
22
|
+
result = Fluent::PluginHelper::RecordAccessor::Accessor.parse_parameter("$['key1']['this.is.key3']")
|
23
|
+
assert_equal ['key1', 'this.is.key3'], result
|
24
|
+
end
|
25
|
+
|
26
|
+
data('dot' => '$.key1.key2[0]',
|
27
|
+
'bracket' => "$['key1']['key2'][0]")
|
28
|
+
test "nested keys ['key1', 'key2', 0]" do |param|
|
29
|
+
result = Fluent::PluginHelper::RecordAccessor::Accessor.parse_parameter(param)
|
30
|
+
assert_equal ['key1', 'key2', 0], result
|
31
|
+
end
|
32
|
+
|
33
|
+
data('bracket' => "$['key1'][0]['ke y2']")
|
34
|
+
test "nested keys ['key1', 0, 'ke y2']" do |param|
|
35
|
+
result = Fluent::PluginHelper::RecordAccessor::Accessor.parse_parameter(param)
|
36
|
+
assert_equal ['key1', 0, 'ke y2'], result
|
37
|
+
end
|
38
|
+
|
39
|
+
data('dot' => '$.[0].key1.[1].key2',
|
40
|
+
'bracket' => "$[0]['key1'][1]['key2']")
|
41
|
+
test "nested keys [0, 'key1', 1, 'key2']" do |param|
|
42
|
+
result = Fluent::PluginHelper::RecordAccessor::Accessor.parse_parameter(param)
|
43
|
+
assert_equal [0, 'key1', 1, 'key2'], result
|
44
|
+
end
|
45
|
+
|
46
|
+
data("missing ']'" => "$['key1'",
|
47
|
+
"missing array index with dot" => "$.hello[]",
|
48
|
+
"missing array index with braket" => "$[]",
|
49
|
+
"more chars" => "$.key1[0]foo",
|
50
|
+
"whitespace char included key in dot notation" => "$.key[0].ke y",
|
51
|
+
"empty keys with dot" => "$.",
|
52
|
+
"empty keys with bracket" => "$[")
|
53
|
+
test 'invalid syntax' do |param|
|
54
|
+
assert_raise Fluent::ConfigError do
|
55
|
+
Fluent::PluginHelper::RecordAccessor::Accessor.parse_parameter(param)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
sub_test_case Fluent::PluginHelper::RecordAccessor::Accessor do
|
61
|
+
setup do
|
62
|
+
@d = Dummy.new
|
63
|
+
end
|
64
|
+
|
65
|
+
data('normal' => 'key1',
|
66
|
+
'space' => 'ke y2',
|
67
|
+
'dot key' => 'this.is.key3')
|
68
|
+
test 'access single key' do |param|
|
69
|
+
r = {'key1' => 'v1', 'ke y2' => 'v2', 'this.is.key3' => 'v3'}
|
70
|
+
accessor = @d.record_accessor_create(param)
|
71
|
+
assert_equal r[param], accessor.call(r)
|
72
|
+
end
|
73
|
+
|
74
|
+
test "nested bracket keys with dot" do
|
75
|
+
r = {'key1' => {'this.is.key3' => 'value'}}
|
76
|
+
accessor = @d.record_accessor_create("$['key1']['this.is.key3']")
|
77
|
+
assert_equal 'value', accessor.call(r)
|
78
|
+
end
|
79
|
+
|
80
|
+
data('dot' => '$.key1.key2[0]',
|
81
|
+
'bracket' => "$['key1']['key2'][0]")
|
82
|
+
test "nested keys ['key1', 'key2', 0]" do |param|
|
83
|
+
r = {'key1' => {'key2' => [1, 2, 3]}}
|
84
|
+
accessor = @d.record_accessor_create(param)
|
85
|
+
assert_equal 1, accessor.call(r)
|
86
|
+
end
|
87
|
+
|
88
|
+
data('bracket' => "$['key1'][0]['ke y2']")
|
89
|
+
test "nested keys ['key1', 0, 'ke y2']" do |param|
|
90
|
+
r = {'key1' => [{'ke y2' => "value"}]}
|
91
|
+
accessor = @d.record_accessor_create(param)
|
92
|
+
assert_equal 'value', accessor.call(r)
|
93
|
+
end
|
94
|
+
|
95
|
+
data("missing ']'" => "$['key1'",
|
96
|
+
"missing array index with dot" => "$.hello[]",
|
97
|
+
"missing array index with braket" => "$['hello'][]",
|
98
|
+
"whitespace char included key in dot notation" => "$.key[0].ke y",
|
99
|
+
"more chars" => "$.key1[0]foo",
|
100
|
+
"empty keys with dot" => "$.",
|
101
|
+
"empty keys with bracket" => "$[")
|
102
|
+
test 'invalid syntax' do |param|
|
103
|
+
assert_raise Fluent::ConfigError do
|
104
|
+
@d.record_accessor_create(param)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/test/test_log.rb
CHANGED
@@ -379,6 +379,56 @@ class LogTest < Test::Unit::TestCase
|
|
379
379
|
assert_equal(Fluent::Log::LEVEL_TRACE, log2.level)
|
380
380
|
end
|
381
381
|
|
382
|
+
def test_format_json
|
383
|
+
logdev = @log_device
|
384
|
+
logger = ServerEngine::DaemonLogger.new(logdev)
|
385
|
+
log = Fluent::Log.new(logger)
|
386
|
+
log.format = :json
|
387
|
+
log.level = Fluent::Log::LEVEL_TRACE
|
388
|
+
log.trace "trace log"
|
389
|
+
log.debug "debug log"
|
390
|
+
log.info "info log"
|
391
|
+
log.warn "warn log"
|
392
|
+
log.error "error log"
|
393
|
+
log.fatal "fatal log"
|
394
|
+
expected = [
|
395
|
+
"#{@timestamp_str} [trace]: trace log\n",
|
396
|
+
"#{@timestamp_str} [debug]: debug log\n",
|
397
|
+
"#{@timestamp_str} [info]: info log\n",
|
398
|
+
"#{@timestamp_str} [warn]: warn log\n",
|
399
|
+
"#{@timestamp_str} [error]: error log\n",
|
400
|
+
"#{@timestamp_str} [fatal]: fatal log\n"
|
401
|
+
]
|
402
|
+
assert_equal(expected, log.out.logs.map { |l|
|
403
|
+
r = JSON.parse(l)
|
404
|
+
"#{r['time']} [#{r['level']}]: #{r['message']}\n"
|
405
|
+
})
|
406
|
+
end
|
407
|
+
|
408
|
+
def test_time_format
|
409
|
+
logdev = @log_device
|
410
|
+
logger = ServerEngine::DaemonLogger.new(logdev)
|
411
|
+
log = Fluent::Log.new(logger)
|
412
|
+
log.time_format = "%Y"
|
413
|
+
log.level = Fluent::Log::LEVEL_TRACE
|
414
|
+
log.trace "trace log"
|
415
|
+
log.debug "debug log"
|
416
|
+
log.info "info log"
|
417
|
+
log.warn "warn log"
|
418
|
+
log.error "error log"
|
419
|
+
log.fatal "fatal log"
|
420
|
+
timestamp_str = @timestamp.strftime("%Y")
|
421
|
+
expected = [
|
422
|
+
"#{timestamp_str} [trace]: trace log\n",
|
423
|
+
"#{timestamp_str} [debug]: debug log\n",
|
424
|
+
"#{timestamp_str} [info]: info log\n",
|
425
|
+
"#{timestamp_str} [warn]: warn log\n",
|
426
|
+
"#{timestamp_str} [error]: error log\n",
|
427
|
+
"#{timestamp_str} [fatal]: fatal log\n"
|
428
|
+
]
|
429
|
+
assert_equal(expected, log.out.logs)
|
430
|
+
end
|
431
|
+
|
382
432
|
def test_disable_events
|
383
433
|
dl_opts = {}
|
384
434
|
dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
|
data/test/test_supervisor.rb
CHANGED
@@ -130,6 +130,10 @@ class SupervisorTest < ::Test::Unit::TestCase
|
|
130
130
|
process_name "process_name"
|
131
131
|
log_level info
|
132
132
|
root_dir #{TMP_ROOT_DIR}
|
133
|
+
<log>
|
134
|
+
format json
|
135
|
+
time_format %Y
|
136
|
+
</log>
|
133
137
|
</system>
|
134
138
|
EOC
|
135
139
|
conf = Fluent::Config.parse(conf_data, "(test)", "(test_dir)", true)
|
@@ -145,6 +149,8 @@ class SupervisorTest < ::Test::Unit::TestCase
|
|
145
149
|
assert_equal "process_name", sys_conf.process_name
|
146
150
|
assert_equal 2, sys_conf.log_level
|
147
151
|
assert_equal TMP_ROOT_DIR, sys_conf.root_dir
|
152
|
+
assert_equal :json, sys_conf.log.format
|
153
|
+
assert_equal '%Y', sys_conf.log.time_format
|
148
154
|
end
|
149
155
|
|
150
156
|
def test_main_process_signal_handlers
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluentd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.14.20
|
4
|
+
version: 0.14.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -160,6 +160,20 @@ dependencies:
|
|
160
160
|
- - "~>"
|
161
161
|
- !ruby/object:Gem::Version
|
162
162
|
version: 0.1.7
|
163
|
+
- !ruby/object:Gem::Dependency
|
164
|
+
name: ruby_dig
|
165
|
+
requirement: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - "~>"
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: 0.0.2
|
170
|
+
type: :runtime
|
171
|
+
prerelease: false
|
172
|
+
version_requirements: !ruby/object:Gem::Requirement
|
173
|
+
requirements:
|
174
|
+
- - "~>"
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: 0.0.2
|
163
177
|
- !ruby/object:Gem::Dependency
|
164
178
|
name: rake
|
165
179
|
requirement: !ruby/object:Gem::Requirement
|
@@ -503,6 +517,7 @@ files:
|
|
503
517
|
- lib/fluent/plugin_helper/formatter.rb
|
504
518
|
- lib/fluent/plugin_helper/inject.rb
|
505
519
|
- lib/fluent/plugin_helper/parser.rb
|
520
|
+
- lib/fluent/plugin_helper/record_accessor.rb
|
506
521
|
- lib/fluent/plugin_helper/retry_state.rb
|
507
522
|
- lib/fluent/plugin_helper/server.rb
|
508
523
|
- lib/fluent/plugin_helper/socket.rb
|
@@ -665,6 +680,7 @@ files:
|
|
665
680
|
- test/plugin_helper/test_formatter.rb
|
666
681
|
- test/plugin_helper/test_inject.rb
|
667
682
|
- test/plugin_helper/test_parser.rb
|
683
|
+
- test/plugin_helper/test_record_accessor.rb
|
668
684
|
- test/plugin_helper/test_retry_state.rb
|
669
685
|
- test/plugin_helper/test_server.rb
|
670
686
|
- test/plugin_helper/test_storage.rb
|
@@ -716,9 +732,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
716
732
|
version: '2.1'
|
717
733
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
718
734
|
requirements:
|
719
|
-
- - "
|
735
|
+
- - ">="
|
720
736
|
- !ruby/object:Gem::Version
|
721
|
-
version:
|
737
|
+
version: '0'
|
722
738
|
requirements: []
|
723
739
|
rubyforge_project:
|
724
740
|
rubygems_version: 2.6.11
|
@@ -830,6 +846,7 @@ test_files:
|
|
830
846
|
- test/plugin_helper/test_formatter.rb
|
831
847
|
- test/plugin_helper/test_inject.rb
|
832
848
|
- test/plugin_helper/test_parser.rb
|
849
|
+
- test/plugin_helper/test_record_accessor.rb
|
833
850
|
- test/plugin_helper/test_retry_state.rb
|
834
851
|
- test/plugin_helper/test_server.rb
|
835
852
|
- test/plugin_helper/test_storage.rb
|