fluentd 0.12.29 → 0.12.30
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/Rakefile +1 -1
- data/lib/fluent/env.rb +1 -0
- data/lib/fluent/formatter.rb +2 -1
- data/lib/fluent/parser.rb +2 -1
- data/lib/fluent/plugin/filter_parser.rb +26 -26
- data/lib/fluent/plugin/in_monitor_agent.rb +7 -2
- data/lib/fluent/plugin/in_tail.rb +2 -2
- data/lib/fluent/test/helpers.rb +86 -0
- data/lib/fluent/version.rb +1 -1
- data/test/config/test_configurable.rb +6 -6
- data/test/helper.rb +3 -0
- data/test/plugin/test_filter_parser.rb +29 -4
- data/test/test_formatter.rb +12 -0
- data/test/test_parser.rb +38 -38
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63a646de1e8fe70118ebe431f68ab2492486c094
|
4
|
+
data.tar.gz: 2f5d57af5036d8197aa5bcb92061498d273031e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5a6242bf2ee47e9aa32ad27bb9af3c67643a9d6b41decc801afaee842758a2dfd18b2bd32fabe2e21eadb293d370bd2a06c0b05e3d609f0ba97bed6325c42b4
|
7
|
+
data.tar.gz: 0bfabdc2a87e25ca1106b6df6d1193ebe2bd6dd7c47ac8b32050877d3ab5fe9ba7b9d94222f6cd8b0002c1a2dcf37fbaf3d541f385386b9d60237f582b735fd9
|
data/ChangeLog
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# v0.12
|
2
2
|
|
3
|
+
## Release 0.12.30 - 2016/12/01
|
4
|
+
|
5
|
+
### New features / Enhancement
|
6
|
+
|
7
|
+
* in_tail: Optimize to split lines
|
8
|
+
https://github.com/fluent/fluentd/pull/1325
|
9
|
+
* in_monitor_agent: Port #1317 changes
|
10
|
+
https://github.com/fluent/fluentd/pull/1317
|
11
|
+
* filter_parser: Add emit_invalid_record_to_error parameter
|
12
|
+
https://github.com/fluent/fluentd/pull/1339
|
13
|
+
* test: Add v0.14 compatible test helpers
|
14
|
+
https://github.com/fluent/fluentd/pull/1322
|
15
|
+
|
16
|
+
### Bug fixes
|
17
|
+
|
18
|
+
* Use compat mode instead of stric mode for oj
|
19
|
+
https://github.com/fluent/fluentd/pull/1304
|
20
|
+
* Port #1331 changes for oj
|
21
|
+
https://github.com/fluent/fluentd/pull/1331
|
22
|
+
|
3
23
|
## Release 0.12.29 - 2016/09/05
|
4
24
|
|
5
25
|
### New features / Enhancement
|
data/Rakefile
CHANGED
data/lib/fluent/env.rb
CHANGED
@@ -18,6 +18,7 @@ module Fluent
|
|
18
18
|
DEFAULT_CONFIG_PATH = ENV['FLUENT_CONF'] || '/etc/fluent/fluent.conf'
|
19
19
|
DEFAULT_PLUGIN_DIR = ENV['FLUENT_PLUGIN'] || '/etc/fluent/plugin'
|
20
20
|
DEFAULT_SOCKET_PATH = ENV['FLUENT_SOCKET'] || '/var/run/fluent/fluent.sock'
|
21
|
+
DEFAULT_OJ_OPTIONS = {bigdecimal_load: :float, mode: :compat, use_to_json: true}
|
21
22
|
DEFAULT_LISTEN_PORT = 24224
|
22
23
|
DEFAULT_FILE_PERMISSION = 0644
|
23
24
|
DEFAULT_DIR_PERMISSION = 0755
|
data/lib/fluent/formatter.rb
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
#
|
16
16
|
|
17
17
|
require 'fluent/configurable'
|
18
|
+
require 'fluent/env'
|
18
19
|
require 'fluent/registry'
|
19
20
|
require 'fluent/mixin'
|
20
21
|
|
@@ -141,7 +142,7 @@ module Fluent
|
|
141
142
|
begin
|
142
143
|
raise LoadError unless @json_parser == 'oj'
|
143
144
|
require 'oj'
|
144
|
-
Oj.default_options =
|
145
|
+
Oj.default_options = Fluent::DEFAULT_OJ_OPTIONS
|
145
146
|
@dump_proc = Oj.method(:dump)
|
146
147
|
rescue LoadError
|
147
148
|
@dump_proc = Yajl.method(:dump)
|
data/lib/fluent/parser.rb
CHANGED
@@ -22,6 +22,7 @@ require 'yajl'
|
|
22
22
|
require 'fluent/config/error'
|
23
23
|
require 'fluent/config/element'
|
24
24
|
require 'fluent/configurable'
|
25
|
+
require 'fluent/env'
|
25
26
|
require 'fluent/engine'
|
26
27
|
require 'fluent/registry'
|
27
28
|
require 'fluent/time'
|
@@ -260,7 +261,7 @@ module Fluent
|
|
260
261
|
begin
|
261
262
|
raise LoadError unless @json_parser == 'oj'
|
262
263
|
require 'oj'
|
263
|
-
Oj.default_options =
|
264
|
+
Oj.default_options = Fluent::DEFAULT_OJ_OPTIONS
|
264
265
|
@load_proc = Oj.method(:load)
|
265
266
|
@error_class = Oj::ParseError
|
266
267
|
rescue LoadError
|
@@ -12,6 +12,7 @@ class Fluent::ParserFilter < Fluent::Filter
|
|
12
12
|
config_param :suppress_parse_error_log, :bool, default: false
|
13
13
|
config_param :time_parse, :bool, default: true
|
14
14
|
config_param :ignore_key_not_exist, :bool, default: false
|
15
|
+
config_param :emit_invalid_record_to_error, :bool, default: false
|
15
16
|
|
16
17
|
attr_reader :parser
|
17
18
|
|
@@ -34,7 +35,11 @@ class Fluent::ParserFilter < Fluent::Filter
|
|
34
35
|
es.each do |time,record|
|
35
36
|
raw_value = record[@key_name]
|
36
37
|
if raw_value.nil?
|
37
|
-
|
38
|
+
if @emit_invalid_record_to_error
|
39
|
+
router.emit_error_event(tag, time, record, ArgumentError.new("#{@key_name} does not exist"))
|
40
|
+
else
|
41
|
+
log.warn "#{@key_name} does not exist" unless @ignore_key_not_exist
|
42
|
+
end
|
38
43
|
new_es.add(time, handle_parsed(tag, record, time, {})) if @reserve_data
|
39
44
|
next
|
40
45
|
end
|
@@ -45,7 +50,11 @@ class Fluent::ParserFilter < Fluent::Filter
|
|
45
50
|
r = handle_parsed(tag, record, t, values)
|
46
51
|
new_es.add(t, r)
|
47
52
|
else
|
48
|
-
|
53
|
+
if @emit_invalid_record_to_error
|
54
|
+
router.emit_error_event(tag, time, record, ::Fluent::ParserError.new("pattern not match with data '#{raw_value}'"))
|
55
|
+
else
|
56
|
+
log.warn "pattern not match with data '#{raw_value}'" unless @suppress_parse_error_log
|
57
|
+
end
|
49
58
|
if @reserve_data
|
50
59
|
t = time
|
51
60
|
r = handle_parsed(tag, record, time, {})
|
@@ -53,33 +62,24 @@ class Fluent::ParserFilter < Fluent::Filter
|
|
53
62
|
end
|
54
63
|
end
|
55
64
|
end
|
56
|
-
rescue Fluent::
|
57
|
-
|
58
|
-
|
59
|
-
if @replace_invalid_sequence
|
60
|
-
unless e.message.index("invalid byte sequence in") == 0
|
61
|
-
raise
|
62
|
-
end
|
63
|
-
replaced_string = replace_invalid_byte(raw_value)
|
64
|
-
@parser.parse(replaced_string) do |t,values|
|
65
|
-
if values
|
66
|
-
t ||= time
|
67
|
-
r = handle_parsed(tag, record, t, values)
|
68
|
-
new_es.add(t, r)
|
69
|
-
else
|
70
|
-
log.warn "pattern not match with data '#{raw_value}'" unless @suppress_parse_error_log
|
71
|
-
if @reserve_data
|
72
|
-
t = time
|
73
|
-
r = handle_parsed(tag, record, time, {})
|
74
|
-
new_es.add(t, r)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
65
|
+
rescue Fluent::ParserError => e
|
66
|
+
if @emit_invalid_record_to_error
|
67
|
+
router.emit_error_event(tag, time, record, e)
|
78
68
|
else
|
79
|
-
|
69
|
+
log.warn e.message unless @suppress_parse_error_log
|
80
70
|
end
|
71
|
+
rescue ArgumentError => e
|
72
|
+
raise unless @replace_invalid_sequence
|
73
|
+
raise unless e.message.index("invalid byte sequence in") == 0
|
74
|
+
|
75
|
+
raw_value = replace_invalid_byte(raw_value)
|
76
|
+
retry
|
81
77
|
rescue => e
|
82
|
-
|
78
|
+
if @emit_invalid_record_to_error
|
79
|
+
router.emit_error_event(tag, time, record, Fluent::ParserError.new("parse failed #{e.message}"))
|
80
|
+
else
|
81
|
+
log.warn "parse failed #{e.message}" unless @suppress_parse_error_log
|
82
|
+
end
|
83
83
|
end
|
84
84
|
end
|
85
85
|
new_es
|
@@ -33,6 +33,7 @@ module Fluent
|
|
33
33
|
config_param :tag, :string, default: nil
|
34
34
|
config_param :emit_interval, :time, default: 60
|
35
35
|
config_param :emit_config, :bool, default: false
|
36
|
+
config_param :include_config, :bool, default: true
|
36
37
|
|
37
38
|
class MonitorServlet < WEBrick::HTTPServlet::AbstractServlet
|
38
39
|
def initialize(server, agent)
|
@@ -76,12 +77,16 @@ module Fluent
|
|
76
77
|
|
77
78
|
# if ?debug=1 is set, set :with_debug_info for get_monitor_info
|
78
79
|
# and :pretty_json for render_json_error
|
79
|
-
opts = {}
|
80
|
+
opts = {with_config: @agent.include_config}
|
80
81
|
if s = qs['debug'] and s[0]
|
81
82
|
opts[:with_debug_info] = true
|
82
83
|
opts[:pretty_json] = true
|
83
84
|
end
|
84
85
|
|
86
|
+
if with_config = get_search_parameter(qs, 'with_config'.freeze)
|
87
|
+
opts[:with_config] = Fluent::Config.bool_value(with_config)
|
88
|
+
end
|
89
|
+
|
85
90
|
if tag = get_search_parameter(qs, 'tag'.freeze)
|
86
91
|
# ?tag= to search an output plugin by match pattern
|
87
92
|
if obj = @agent.plugin_info_by_tag(tag, opts)
|
@@ -389,7 +394,7 @@ module Fluent
|
|
389
394
|
obj['plugin_id'] = pe.plugin_id
|
390
395
|
obj['plugin_category'] = plugin_category(pe)
|
391
396
|
obj['type'] = pe.config['@type'] || pe.config['type']
|
392
|
-
obj['config'] = pe.config if
|
397
|
+
obj['config'] = pe.config if opts[:with_config]
|
393
398
|
|
394
399
|
# run MONITOR_INFO in plugins' instance context and store the info to obj
|
395
400
|
MONITOR_INFO.each_pair {|key,code|
|
@@ -579,8 +579,8 @@ module Fluent
|
|
579
579
|
else
|
580
580
|
@buffer << @io.readpartial(2048, @iobuf)
|
581
581
|
end
|
582
|
-
while
|
583
|
-
@lines <<
|
582
|
+
while idx = @buffer.index("\n".freeze)
|
583
|
+
@lines << @buffer.slice!(0, idx + 1)
|
584
584
|
end
|
585
585
|
if @lines.size >= @read_lines_limit
|
586
586
|
# not to use too much memory in case the file is very large
|
@@ -0,0 +1,86 @@
|
|
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/element'
|
18
|
+
require 'time'
|
19
|
+
require 'fluent/time'
|
20
|
+
|
21
|
+
module Fluent
|
22
|
+
module Test
|
23
|
+
module Helpers
|
24
|
+
# See "Example Custom Assertion: http://test-unit.github.io/test-unit/en/Test/Unit/Assertions.html
|
25
|
+
def assert_equal_event_time(expected, actual, message = nil)
|
26
|
+
expected_s = "#{expected}"
|
27
|
+
actual_s = "#{actual}"
|
28
|
+
message = build_message(message, <<EOT, expected_s, actual_s)
|
29
|
+
<?> time expected but was
|
30
|
+
<?>.
|
31
|
+
EOT
|
32
|
+
assert_block(message) do
|
33
|
+
expected.is_a?(Integer) && actual.is_a?(Integer) && expected == actual
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def config_element(name = 'test', argument = '', params = {}, elements = [])
|
38
|
+
Fluent::Config::Element.new(name, argument, params, elements)
|
39
|
+
end
|
40
|
+
|
41
|
+
def event_time(str = nil, format: nil)
|
42
|
+
if str
|
43
|
+
if format
|
44
|
+
Time.strptime(str, format).to_i
|
45
|
+
else
|
46
|
+
Time.parse(str).to_i
|
47
|
+
end
|
48
|
+
else
|
49
|
+
Time.now.to_i
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def with_timezone(tz)
|
54
|
+
oldtz, ENV['TZ'] = ENV['TZ'], tz
|
55
|
+
yield
|
56
|
+
ensure
|
57
|
+
ENV['TZ'] = oldtz
|
58
|
+
end
|
59
|
+
|
60
|
+
def time2str(time, localtime: false, format: nil)
|
61
|
+
if format
|
62
|
+
if localtime
|
63
|
+
Time.at(time).strftime(format)
|
64
|
+
else
|
65
|
+
Time.at(time).utc.strftime(format)
|
66
|
+
end
|
67
|
+
else
|
68
|
+
if localtime
|
69
|
+
Time.at(time).iso8601
|
70
|
+
else
|
71
|
+
Time.at(time).utc.iso8601
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def capture_log(driver)
|
77
|
+
tmp = driver.instance.log.out
|
78
|
+
driver.instance.log.out = StringIO.new
|
79
|
+
yield
|
80
|
+
return driver.instance.log.out.string
|
81
|
+
ensure
|
82
|
+
driver.instance.log.out = tmp
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/fluent/version.rb
CHANGED
@@ -296,7 +296,7 @@ module Fluent::Config
|
|
296
296
|
def e(name, arg = '', attrs = {}, elements = [])
|
297
297
|
attrs_str_keys = {}
|
298
298
|
attrs.each{|key, value| attrs_str_keys[key.to_s] = value }
|
299
|
-
|
299
|
+
config_element(name, arg, attrs_str_keys, elements)
|
300
300
|
end
|
301
301
|
|
302
302
|
BASE_ATTRS = {
|
@@ -577,7 +577,7 @@ module Fluent::Config
|
|
577
577
|
def e(name, arg = '', attrs = {}, elements = [])
|
578
578
|
attrs_str_keys = {}
|
579
579
|
attrs.each{|key, value| attrs_str_keys[key.to_s] = value }
|
580
|
-
|
580
|
+
config_element(name, arg, attrs_str_keys, elements)
|
581
581
|
end
|
582
582
|
|
583
583
|
test 'subclass configuration spec can overwrite superclass specs' do
|
@@ -682,7 +682,7 @@ module Fluent::Config
|
|
682
682
|
def e(name, arg = '', attrs = {}, elements = [])
|
683
683
|
attrs_str_keys = {}
|
684
684
|
attrs.each{|key, value| attrs_str_keys[key.to_s] = value }
|
685
|
-
|
685
|
+
config_element(name, arg, attrs_str_keys, elements)
|
686
686
|
end
|
687
687
|
|
688
688
|
test 'provides accessible data for alias attribute keys' do
|
@@ -701,7 +701,7 @@ module Fluent::Config
|
|
701
701
|
def e(name, arg = '', attrs = {}, elements = [])
|
702
702
|
attrs_str_keys = {}
|
703
703
|
attrs.each { |key, value| attrs_str_keys[key.to_s] = value }
|
704
|
-
|
704
|
+
config_element(name, arg, attrs_str_keys, elements)
|
705
705
|
end
|
706
706
|
|
707
707
|
setup do
|
@@ -813,7 +813,7 @@ module Fluent::Config
|
|
813
813
|
test 'warned if deprecated parameter is configured' do
|
814
814
|
obj = ConfigurableSpec::UnRecommended.new
|
815
815
|
obj.log = Fluent::Test::TestLogger.new
|
816
|
-
obj.configure(
|
816
|
+
obj.configure(config_element('ROOT', '', {'key1' => 'yay'}, []))
|
817
817
|
|
818
818
|
assert_equal 'yay', obj.key1
|
819
819
|
first_log = obj.log.logs.first
|
@@ -825,7 +825,7 @@ module Fluent::Config
|
|
825
825
|
obj.log = Fluent::Test::TestLogger.new
|
826
826
|
|
827
827
|
assert_raise Fluent::ObsoletedParameterError.new("'key2' parameter is already removed: key2 has been removed.") do
|
828
|
-
obj.configure(
|
828
|
+
obj.configure(config_element('ROOT', '', {'key2' => 'yay'}, []))
|
829
829
|
end
|
830
830
|
end
|
831
831
|
end
|
data/test/helper.rb
CHANGED
@@ -41,12 +41,15 @@ require 'test/unit/rr'
|
|
41
41
|
require 'fileutils'
|
42
42
|
require 'fluent/log'
|
43
43
|
require 'fluent/test'
|
44
|
+
require 'fluent/test/helpers'
|
44
45
|
|
45
46
|
unless defined?(Test::Unit::AssertionFailedError)
|
46
47
|
class Test::Unit::AssertionFailedError < StandardError
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
51
|
+
include Fluent::Test::Helpers
|
52
|
+
|
50
53
|
def unused_port
|
51
54
|
s = TCPServer.open(0)
|
52
55
|
port = s.addr[1]
|
@@ -1,8 +1,11 @@
|
|
1
1
|
require_relative '../helper'
|
2
2
|
require 'timecop'
|
3
3
|
require 'fluent/plugin/filter_parser'
|
4
|
+
require 'flexmock/test_unit'
|
4
5
|
|
5
6
|
class ParserFilterTest < Test::Unit::TestCase
|
7
|
+
include FlexMock::TestCase
|
8
|
+
|
6
9
|
setup do
|
7
10
|
Fluent::Test.setup
|
8
11
|
@time = Time.parse("2012-01-02 13:14:15")
|
@@ -588,6 +591,15 @@ class ParserFilterTest < Test::Unit::TestCase
|
|
588
591
|
assert_equal 1, filtered.length
|
589
592
|
assert_nil filtered[0][2]['data']
|
590
593
|
assert_equal 'bar', filtered[0][2]['foo']
|
594
|
+
|
595
|
+
d = create_driver(CONFIG_NOT_IGNORE + "emit_invalid_record_to_error true", 'test.no.ignore')
|
596
|
+
assert_nothing_raised {
|
597
|
+
flexmock(d.instance.router).should_receive(:emit_error_event).
|
598
|
+
with(String, Integer, Hash, ArgumentError).once
|
599
|
+
d.run do
|
600
|
+
d.filter({'foo' => 'bar'}, Time.now.to_i)
|
601
|
+
end
|
602
|
+
}
|
591
603
|
end
|
592
604
|
|
593
605
|
# suppress_parse_error_log test
|
@@ -689,13 +701,11 @@ class ParserFilterTest < Test::Unit::TestCase
|
|
689
701
|
end
|
690
702
|
|
691
703
|
def test_nothing_raised
|
692
|
-
swap_logger(@d.instance) do
|
693
704
|
assert_nothing_raised {
|
694
705
|
@d.run do
|
695
706
|
@d.filter({'message' => VALID_MESSAGE}, Time.now.to_i)
|
696
707
|
end
|
697
708
|
}
|
698
|
-
end
|
699
709
|
end
|
700
710
|
end
|
701
711
|
|
@@ -706,14 +716,29 @@ class ParserFilterTest < Test::Unit::TestCase
|
|
706
716
|
end
|
707
717
|
|
708
718
|
def test_nothing_raised
|
709
|
-
swap_logger(@d.instance) do
|
710
719
|
assert_nothing_raised {
|
711
720
|
@d.run do
|
712
721
|
@d.filter({'message' => INVALID_MESSAGE}, Time.now.to_i)
|
713
722
|
@d.filter({'message' => VALID_MESSAGE}, Time.now.to_i)
|
714
723
|
end
|
715
724
|
}
|
716
|
-
|
725
|
+
end
|
726
|
+
end
|
727
|
+
|
728
|
+
class EmitInvalidRecordErrorTest < self
|
729
|
+
def setup
|
730
|
+
# enabled 'suppress_parse_error_log'
|
731
|
+
@d = create_driver(CONFIG_ENABELED_SUPPRESS_PARSE_ERROR_LOG + "emit_invalid_record_to_error true", 'test.no.change')
|
732
|
+
end
|
733
|
+
|
734
|
+
def test_nothing_raised
|
735
|
+
flexmock(@d.instance.router).should_receive(:emit_error_event).
|
736
|
+
with(String, Integer, Hash, Fluent::ParserError).once
|
737
|
+
assert_nothing_raised {
|
738
|
+
@d.run do
|
739
|
+
@d.filter({'message' => INVALID_MESSAGE}, Time.now.to_i)
|
740
|
+
end
|
741
|
+
}
|
717
742
|
end
|
718
743
|
end
|
719
744
|
end
|
data/test/test_formatter.rb
CHANGED
@@ -29,6 +29,10 @@ module FormatterTest
|
|
29
29
|
{'message' => 'awesome'}
|
30
30
|
end
|
31
31
|
|
32
|
+
def symbolic_record
|
33
|
+
{:message => :awesome}
|
34
|
+
end
|
35
|
+
|
32
36
|
def with_timezone(tz)
|
33
37
|
oldtz, ENV['TZ'] = ENV['TZ'], tz
|
34
38
|
yield
|
@@ -138,6 +142,14 @@ module FormatterTest
|
|
138
142
|
assert_equal("#{Yajl.dump(record)}\n", formatted)
|
139
143
|
end
|
140
144
|
|
145
|
+
data('oj' => 'oj', 'yajl' => 'yajl')
|
146
|
+
def test_format_with_symbolic_record(data)
|
147
|
+
@formatter.configure('json_parser' => data)
|
148
|
+
formatted = @formatter.format(tag, @time, symbolic_record)
|
149
|
+
|
150
|
+
assert_equal("#{JSON.generate(record)}\n", formatted)
|
151
|
+
end
|
152
|
+
|
141
153
|
data('oj' => 'oj', 'yajl' => 'yajl')
|
142
154
|
def test_format_with_include_tag(data)
|
143
155
|
@formatter.configure('include_tag_key' => 'true', 'tag_key' => 'foo', 'json_parser' => data)
|
data/test/test_parser.rb
CHANGED
@@ -6,14 +6,6 @@ require 'fluent/plugin/string_util'
|
|
6
6
|
module ParserTest
|
7
7
|
include Fluent
|
8
8
|
|
9
|
-
def str2time(str_time, format = nil)
|
10
|
-
if format
|
11
|
-
Time.strptime(str_time, format).to_i
|
12
|
-
else
|
13
|
-
Time.parse(str_time).to_i
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
9
|
class BaseParserTest < ::Test::Unit::TestCase
|
18
10
|
include ParserTest
|
19
11
|
|
@@ -71,15 +63,15 @@ module ParserTest
|
|
71
63
|
def test_call_with_parse
|
72
64
|
parser = TextParser::TimeParser.new(nil)
|
73
65
|
|
74
|
-
time =
|
75
|
-
|
66
|
+
time = event_time('2013-09-18 12:00:00 +0900')
|
67
|
+
assert_equal_event_time(time, parser.parse('2013-09-18 12:00:00 +0900'))
|
76
68
|
end
|
77
69
|
|
78
70
|
def test_parse_with_strptime
|
79
71
|
parser = TextParser::TimeParser.new('%d/%b/%Y:%H:%M:%S %z')
|
80
72
|
|
81
|
-
time =
|
82
|
-
|
73
|
+
time = event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z')
|
74
|
+
assert_equal_event_time(time, parser.parse('28/Feb/2013:12:00:00 +0900'))
|
83
75
|
end
|
84
76
|
|
85
77
|
def test_parse_with_invalid_argument
|
@@ -99,13 +91,13 @@ module ParserTest
|
|
99
91
|
def internal_test_case(parser)
|
100
92
|
text = '192.168.0.1 - - [28/Feb/2013:12:00:00 +0900] [14/Feb/2013:12:00:00 +0900] "true /,/user HTTP/1.1" 200 777'
|
101
93
|
[parser.parse(text), parser.parse(text) { |time, record| return time, record}].each { |time, record|
|
102
|
-
|
94
|
+
assert_equal_event_time(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
|
103
95
|
assert_equal({
|
104
96
|
'user' => '-',
|
105
97
|
'flag' => true,
|
106
98
|
'code' => 200.0,
|
107
99
|
'size' => 777,
|
108
|
-
'date' =>
|
100
|
+
'date' => event_time('14/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'),
|
109
101
|
'host' => '192.168.0.1',
|
110
102
|
'path' => ['/', '/user']
|
111
103
|
}, record)
|
@@ -139,12 +131,12 @@ module ParserTest
|
|
139
131
|
)
|
140
132
|
text = '2013-02-28 12:00:00 +0900'
|
141
133
|
parser.parse(text) do |time, record|
|
142
|
-
assert_equal
|
134
|
+
assert_equal event_time(text), time
|
143
135
|
end
|
144
136
|
end
|
145
137
|
|
146
138
|
def test_parse_without_time
|
147
|
-
time_at_start =
|
139
|
+
time_at_start = event_time()
|
148
140
|
text = "tagomori_satoshi tagomoris 34\n"
|
149
141
|
|
150
142
|
parser = TextParser::RegexpParser.new(Regexp.new(%q!^(?<name>[^ ]*) (?<user>[^ ]*) (?<age>\d*)$!))
|
@@ -206,7 +198,7 @@ module ParserTest
|
|
206
198
|
def test_call(method_name)
|
207
199
|
m = @parser.method(method_name)
|
208
200
|
m.call('192.168.0.1 - - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777') { |time, record|
|
209
|
-
|
201
|
+
assert_equal_event_time(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
|
210
202
|
assert_equal({
|
211
203
|
'user' => '-',
|
212
204
|
'method' => 'GET',
|
@@ -245,21 +237,21 @@ module ParserTest
|
|
245
237
|
|
246
238
|
def test_parse
|
247
239
|
@parser.parse('[Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] client denied by server configuration') { |time, record|
|
248
|
-
|
240
|
+
assert_equal_event_time(event_time('Wed Oct 11 14:32:52 2000'), time)
|
249
241
|
assert_equal(@expected, record)
|
250
242
|
}
|
251
243
|
end
|
252
244
|
|
253
245
|
def test_parse_with_pid
|
254
246
|
@parser.parse('[Wed Oct 11 14:32:52 2000] [error] [pid 1000] [client 127.0.0.1] client denied by server configuration') { |time, record|
|
255
|
-
|
247
|
+
assert_equal_event_time(event_time('Wed Oct 11 14:32:52 2000'), time)
|
256
248
|
assert_equal(@expected.merge('pid' => '1000'), record)
|
257
249
|
}
|
258
250
|
end
|
259
251
|
|
260
252
|
def test_parse_without_client
|
261
253
|
@parser.parse('[Wed Oct 11 14:32:52 2000] [notice] Apache/2.2.15 (Unix) DAV/2 configured -- resuming normal operations') { |time, record|
|
262
|
-
|
254
|
+
assert_equal_event_time(event_time('Wed Oct 11 14:32:52 2000'), time)
|
263
255
|
assert_equal({
|
264
256
|
'level' => 'notice',
|
265
257
|
'message' => 'Apache/2.2.15 (Unix) DAV/2 configured -- resuming normal operations'
|
@@ -287,7 +279,7 @@ module ParserTest
|
|
287
279
|
|
288
280
|
def test_parse
|
289
281
|
@parser.parse('192.168.0.1 - - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0"') { |time, record|
|
290
|
-
|
282
|
+
assert_equal_event_time(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
|
291
283
|
assert_equal(@expected, record)
|
292
284
|
}
|
293
285
|
assert_equal(TextParser::ApacheParser::REGEXP, @parser.patterns['format'])
|
@@ -296,7 +288,7 @@ module ParserTest
|
|
296
288
|
|
297
289
|
def test_parse_without_http_version
|
298
290
|
@parser.parse('192.168.0.1 - - [28/Feb/2013:12:00:00 +0900] "GET /" 200 777 "-" "Opera/12.0"') { |time, record|
|
299
|
-
|
291
|
+
assert_equal_event_time(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
|
300
292
|
assert_equal(@expected, record)
|
301
293
|
}
|
302
294
|
end
|
@@ -318,7 +310,7 @@ module ParserTest
|
|
318
310
|
def test_parse
|
319
311
|
@parser.configure({})
|
320
312
|
@parser.parse('Feb 28 12:00:00 192.168.0.1 fluentd[11111]: [error] Syslog test') { |time, record|
|
321
|
-
|
313
|
+
assert_equal_event_time(event_time('Feb 28 12:00:00', format: '%b %d %H:%M:%S'), time)
|
322
314
|
assert_equal(@expected, record)
|
323
315
|
}
|
324
316
|
assert_equal(TextParser::SyslogParser::REGEXP, @parser.instance.patterns['format'])
|
@@ -328,7 +320,7 @@ module ParserTest
|
|
328
320
|
def test_parse_with_time_format
|
329
321
|
@parser.configure('time_format' => '%b %d %M:%S:%H')
|
330
322
|
@parser.parse('Feb 28 00:00:12 192.168.0.1 fluentd[11111]: [error] Syslog test') { |time, record|
|
331
|
-
|
323
|
+
assert_equal_event_time(event_time('Feb 28 12:00:00', format: '%b %d %H:%M:%S'), time)
|
332
324
|
assert_equal(@expected, record)
|
333
325
|
}
|
334
326
|
assert_equal('%b %d %M:%S:%H', @parser.instance.patterns['time_format'])
|
@@ -337,7 +329,7 @@ module ParserTest
|
|
337
329
|
def test_parse_with_priority
|
338
330
|
@parser.configure('with_priority' => true)
|
339
331
|
@parser.parse('<6>Feb 28 12:00:00 192.168.0.1 fluentd[11111]: [error] Syslog test') { |time, record|
|
340
|
-
|
332
|
+
assert_equal_event_time(event_time('Feb 28 12:00:00', format: '%b %d %H:%M:%S'), time)
|
341
333
|
assert_equal(@expected.merge('pri' => 6), record)
|
342
334
|
}
|
343
335
|
assert_equal(TextParser::SyslogParser::REGEXP_WITH_PRI, @parser.instance.patterns['format'])
|
@@ -347,7 +339,7 @@ module ParserTest
|
|
347
339
|
def test_parse_without_colon
|
348
340
|
@parser.configure({})
|
349
341
|
@parser.parse('Feb 28 12:00:00 192.168.0.1 fluentd[11111] [error] Syslog test') { |time, record|
|
350
|
-
|
342
|
+
assert_equal_event_time(event_time('Feb 28 12:00:00', format: '%b %d %H:%M:%S'), time)
|
351
343
|
assert_equal(@expected, record)
|
352
344
|
}
|
353
345
|
assert_equal(TextParser::SyslogParser::REGEXP, @parser.instance.patterns['format'])
|
@@ -377,7 +369,7 @@ module ParserTest
|
|
377
369
|
def test_parse(data)
|
378
370
|
@parser.configure('json_parser' => data)
|
379
371
|
@parser.parse('{"time":1362020400,"host":"192.168.0.1","size":777,"method":"PUT"}') { |time, record|
|
380
|
-
|
372
|
+
assert_equal_event_time(event_time('2013-02-28 12:00:00 +0900'), time)
|
381
373
|
assert_equal({
|
382
374
|
'host' => '192.168.0.1',
|
383
375
|
'size' => 777,
|
@@ -421,6 +413,14 @@ module ParserTest
|
|
421
413
|
}
|
422
414
|
end
|
423
415
|
|
416
|
+
data('oj' => 'oj', 'yajl' => 'yajl')
|
417
|
+
def test_parse_with_colon_string(data)
|
418
|
+
@parser.configure('json_parser' => data)
|
419
|
+
@parser.parse('{"time":1362020400,"log":":message"}') { |time, record|
|
420
|
+
assert_equal(record['log'], ':message')
|
421
|
+
}
|
422
|
+
end
|
423
|
+
|
424
424
|
data('oj' => 'oj', 'yajl' => 'yajl')
|
425
425
|
def test_parse_with_invalid_time(data)
|
426
426
|
@parser.configure('json_parser' => data)
|
@@ -464,21 +464,21 @@ module ParserTest
|
|
464
464
|
|
465
465
|
def test_parse
|
466
466
|
@parser.parse('127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0"') { |time, record|
|
467
|
-
|
467
|
+
assert_equal_event_time(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
|
468
468
|
assert_equal(@expected, record)
|
469
469
|
}
|
470
470
|
end
|
471
471
|
|
472
472
|
def test_parse_with_empty_included_path
|
473
473
|
@parser.parse('127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET /a[ ]b HTTP/1.1" 200 777 "-" "Opera/12.0"') { |time, record|
|
474
|
-
|
474
|
+
assert_equal_event_time(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
|
475
475
|
assert_equal(@expected.merge('path' => '/a[ ]b'), record)
|
476
476
|
}
|
477
477
|
end
|
478
478
|
|
479
479
|
def test_parse_without_http_version
|
480
480
|
@parser.parse('127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET /" 200 777 "-" "Opera/12.0"') { |time, record|
|
481
|
-
|
481
|
+
assert_equal_event_time(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
|
482
482
|
assert_equal(@expected, record)
|
483
483
|
}
|
484
484
|
end
|
@@ -507,7 +507,7 @@ module ParserTest
|
|
507
507
|
parser = TextParser::TSVParser.new
|
508
508
|
parser.configure('keys' => param, 'time_key' => 'time')
|
509
509
|
parser.parse("2013/02/28 12:00:00\t192.168.0.1\t111") { |time, record|
|
510
|
-
|
510
|
+
assert_equal_event_time(event_time('2013/02/28 12:00:00', format: '%Y/%m/%d %H:%M:%S'), time)
|
511
511
|
assert_equal({
|
512
512
|
'a' => '192.168.0.1',
|
513
513
|
'b' => '111',
|
@@ -612,7 +612,7 @@ module ParserTest
|
|
612
612
|
parser = TextParser::CSVParser.new
|
613
613
|
parser.configure('keys' => param, 'time_key' => 'time')
|
614
614
|
parser.parse("2013/02/28 12:00:00,192.168.0.1,111") { |time, record|
|
615
|
-
|
615
|
+
assert_equal_event_time(event_time('2013/02/28 12:00:00', format: '%Y/%m/%d %H:%M:%S'), time)
|
616
616
|
assert_equal({
|
617
617
|
'c' => '192.168.0.1',
|
618
618
|
'd' => '111',
|
@@ -715,7 +715,7 @@ module ParserTest
|
|
715
715
|
parser = TextParser::LabeledTSVParser.new
|
716
716
|
parser.configure({})
|
717
717
|
parser.parse("time:2013/02/28 12:00:00\thost:192.168.0.1\treq_id:111") { |time, record|
|
718
|
-
|
718
|
+
assert_equal_event_time(event_time('2013/02/28 12:00:00', format: '%Y/%m/%d %H:%M:%S'), time)
|
719
719
|
assert_equal({
|
720
720
|
'host' => '192.168.0.1',
|
721
721
|
'req_id' => '111',
|
@@ -730,7 +730,7 @@ module ParserTest
|
|
730
730
|
'label_delimiter' => '=',
|
731
731
|
)
|
732
732
|
parser.parse('time=2013/02/28 12:00:00,host=192.168.0.1,req_id=111') { |time, record|
|
733
|
-
|
733
|
+
assert_equal_event_time(event_time('2013/02/28 12:00:00', format: '%Y/%m/%d %H:%M:%S'), time)
|
734
734
|
assert_equal({
|
735
735
|
'host' => '192.168.0.1',
|
736
736
|
'req_id' => '111',
|
@@ -745,7 +745,7 @@ module ParserTest
|
|
745
745
|
'time_format' => '%d/%b/%Y:%H:%M:%S %z',
|
746
746
|
)
|
747
747
|
parser.parse("mytime:28/Feb/2013:12:00:00 +0900\thost:192.168.0.1\treq_id:111") { |time, record|
|
748
|
-
|
748
|
+
assert_equal_event_time(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
|
749
749
|
assert_equal({
|
750
750
|
'host' => '192.168.0.1',
|
751
751
|
'req_id' => '111',
|
@@ -890,7 +890,7 @@ javax.management.RuntimeErrorException: null
|
|
890
890
|
\tat Main.main(Main.java:16) ~[bin/:na]
|
891
891
|
EOS
|
892
892
|
|
893
|
-
|
893
|
+
assert_equal_event_time(event_time('2013-3-03 14:27:33'), time)
|
894
894
|
assert_equal({
|
895
895
|
"thread" => "main",
|
896
896
|
"level" => "ERROR",
|
@@ -908,7 +908,7 @@ message=test1
|
|
908
908
|
EOS
|
909
909
|
|
910
910
|
assert(parser.firstline?('----'))
|
911
|
-
|
911
|
+
assert_equal_event_time(event_time('2013-3-03 14:27:33'), time)
|
912
912
|
assert_equal({"message" => "test1"}, record)
|
913
913
|
}
|
914
914
|
end
|
@@ -930,7 +930,7 @@ Completed 200 OK in 4ms (Views: 3.2ms | ActiveRecord: 0.0ms)
|
|
930
930
|
EOS
|
931
931
|
|
932
932
|
assert(parser.firstline?('Started GET "/users/123/" for 127.0.0.1...'))
|
933
|
-
|
933
|
+
assert_equal_event_time(event_time('2013-06-14 12:00:11 +0900'), time)
|
934
934
|
assert_equal({
|
935
935
|
"method" => "GET",
|
936
936
|
"path" => "/users/123/",
|
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.12.
|
4
|
+
version: 0.12.30
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -403,6 +403,7 @@ files:
|
|
403
403
|
- lib/fluent/test/base.rb
|
404
404
|
- lib/fluent/test/filter_test.rb
|
405
405
|
- lib/fluent/test/formatter_test.rb
|
406
|
+
- lib/fluent/test/helpers.rb
|
406
407
|
- lib/fluent/test/input_test.rb
|
407
408
|
- lib/fluent/test/output_test.rb
|
408
409
|
- lib/fluent/test/parser_test.rb
|