fluentd 0.10.49 → 0.10.50
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 +11 -0
- data/fluentd.gemspec +1 -1
- data/lib/fluent/config/v1_parser.rb +4 -4
- data/lib/fluent/engine.rb +22 -6
- data/lib/fluent/formatter.rb +4 -1
- data/lib/fluent/mixin.rb +0 -14
- data/lib/fluent/parser.rb +70 -17
- data/lib/fluent/plugin/buf_memory.rb +1 -1
- data/lib/fluent/plugin/in_http.rb +0 -7
- data/lib/fluent/plugin/in_syslog.rb +7 -7
- data/lib/fluent/plugin/in_tail.rb +56 -40
- data/lib/fluent/test/input_test.rb +3 -4
- data/lib/fluent/version.rb +1 -1
- data/spec/config/config_parser_spec.rb +30 -30
- data/spec/config/configurable_spec.rb +2 -2
- data/spec/config/configure_proxy_spec.rb +20 -20
- data/spec/config/dsl_spec.rb +1 -1
- data/spec/config/helper.rb +3 -3
- data/spec/config/literal_parser_spec.rb +136 -136
- data/spec/config/section_spec.rb +5 -5
- data/test/plugin/test_in_tail.rb +129 -14
- data/test/plugin/test_out_file.rb +24 -0
- data/test/test_formatter.rb +9 -2
- data/test/test_parser.rb +209 -119
- metadata +4 -4
data/spec/config/section_spec.rb
CHANGED
@@ -60,17 +60,17 @@ describe Fluent::Config::Section do
|
|
60
60
|
describe '#instance_of?' do
|
61
61
|
it 'can judge whether it is a Section object or not' do
|
62
62
|
s = Fluent::Config::Section.new
|
63
|
-
expect(s.instance_of?(Fluent::Config::Section)).to
|
64
|
-
expect(s.instance_of?(BasicObject)).to
|
63
|
+
expect(s.instance_of?(Fluent::Config::Section)).to be true
|
64
|
+
expect(s.instance_of?(BasicObject)).to be false
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
describe '#is_a?' do
|
69
69
|
it 'can judge whether it belongs to or not' do
|
70
70
|
s = Fluent::Config::Section.new
|
71
|
-
expect(s.is_a?(Fluent::Config::Section)).to
|
72
|
-
expect(s.kind_of?(Fluent::Config::Section)).to
|
73
|
-
expect(s.is_a?(BasicObject)).to
|
71
|
+
expect(s.is_a?(Fluent::Config::Section)).to be true
|
72
|
+
expect(s.kind_of?(Fluent::Config::Section)).to be true
|
73
|
+
expect(s.is_a?(BasicObject)).to be true
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
data/test/plugin/test_in_tail.rb
CHANGED
@@ -13,12 +13,17 @@ class TailInputTest < Test::Unit::TestCase
|
|
13
13
|
|
14
14
|
TMP_DIR = File.dirname(__FILE__) + "/../tmp/tail#{ENV['TEST_ENV_NUMBER']}"
|
15
15
|
|
16
|
-
|
16
|
+
CONFIG = %[
|
17
17
|
path #{TMP_DIR}/tail.txt
|
18
18
|
tag t1
|
19
19
|
rotate_wait 2s
|
20
|
+
]
|
21
|
+
COMMON_CONFIG = CONFIG + %[
|
20
22
|
pos_file #{TMP_DIR}/tail.pos
|
21
23
|
]
|
24
|
+
CONFIG_READ_FROM_HEAD = %[
|
25
|
+
read_from_head true
|
26
|
+
]
|
22
27
|
SINGLE_LINE_CONFIG = %[
|
23
28
|
format /(?<message>.*)/
|
24
29
|
]
|
@@ -36,6 +41,8 @@ class TailInputTest < Test::Unit::TestCase
|
|
36
41
|
assert_equal "#{TMP_DIR}/tail.pos", d.instance.pos_file
|
37
42
|
end
|
38
43
|
|
44
|
+
# TODO: Should using more better approach instead of sleep wait
|
45
|
+
|
39
46
|
def test_emit
|
40
47
|
File.open("#{TMP_DIR}/tail.txt", "w") {|f|
|
41
48
|
f.puts "test1"
|
@@ -56,8 +63,89 @@ class TailInputTest < Test::Unit::TestCase
|
|
56
63
|
|
57
64
|
emits = d.emits
|
58
65
|
assert_equal(true, emits.length > 0)
|
59
|
-
assert_equal({"message"=>"test3"}, emits[0][2])
|
60
|
-
assert_equal({"message"=>"test4"}, emits[1][2])
|
66
|
+
assert_equal({"message" => "test3"}, emits[0][2])
|
67
|
+
assert_equal({"message" => "test4"}, emits[1][2])
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_emit_with_read_from_head
|
71
|
+
File.open("#{TMP_DIR}/tail.txt", "w") {|f|
|
72
|
+
f.puts "test1"
|
73
|
+
f.puts "test2"
|
74
|
+
}
|
75
|
+
|
76
|
+
d = create_driver(CONFIG_READ_FROM_HEAD + SINGLE_LINE_CONFIG)
|
77
|
+
|
78
|
+
d.run do
|
79
|
+
sleep 1
|
80
|
+
|
81
|
+
File.open("#{TMP_DIR}/tail.txt", "a") {|f|
|
82
|
+
f.puts "test3"
|
83
|
+
f.puts "test4"
|
84
|
+
}
|
85
|
+
sleep 1
|
86
|
+
end
|
87
|
+
|
88
|
+
emits = d.emits
|
89
|
+
assert(emits.length > 0)
|
90
|
+
assert_equal({"message" => "test1"}, emits[0][2])
|
91
|
+
assert_equal({"message" => "test2"}, emits[1][2])
|
92
|
+
assert_equal({"message" => "test3"}, emits[2][2])
|
93
|
+
assert_equal({"message" => "test4"}, emits[3][2])
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_rotate_file
|
97
|
+
emits = sub_test_rotate_file(SINGLE_LINE_CONFIG)
|
98
|
+
assert(emits.length > 0)
|
99
|
+
assert_equal({"message" => "test3"}, emits[0][2])
|
100
|
+
assert_equal({"message" => "test4"}, emits[1][2])
|
101
|
+
assert_equal({"message" => "test5"}, emits[2][2])
|
102
|
+
assert_equal({"message" => "test6"}, emits[3][2])
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_rotate_file_with_read_from_head
|
106
|
+
emits = sub_test_rotate_file(CONFIG_READ_FROM_HEAD + SINGLE_LINE_CONFIG)
|
107
|
+
assert(emits.length > 0)
|
108
|
+
assert_equal({"message" => "test1"}, emits[0][2])
|
109
|
+
assert_equal({"message" => "test2"}, emits[1][2])
|
110
|
+
assert_equal({"message" => "test3"}, emits[2][2])
|
111
|
+
assert_equal({"message" => "test4"}, emits[3][2])
|
112
|
+
assert_equal({"message" => "test5"}, emits[4][2])
|
113
|
+
assert_equal({"message" => "test6"}, emits[5][2])
|
114
|
+
end
|
115
|
+
|
116
|
+
def sub_test_rotate_file(config = nil)
|
117
|
+
File.open("#{TMP_DIR}/tail.txt", "w") {|f|
|
118
|
+
f.puts "test1"
|
119
|
+
f.puts "test2"
|
120
|
+
}
|
121
|
+
d = create_driver(config)
|
122
|
+
d.run do
|
123
|
+
sleep 1
|
124
|
+
|
125
|
+
File.open("#{TMP_DIR}/tail.txt", "a") {|f|
|
126
|
+
f.puts "test3"
|
127
|
+
f.puts "test4"
|
128
|
+
}
|
129
|
+
sleep 1
|
130
|
+
|
131
|
+
FileUtils.mv("#{TMP_DIR}/tail.txt", "#{TMP_DIR}/tail2.txt")
|
132
|
+
sleep 1
|
133
|
+
|
134
|
+
File.open("#{TMP_DIR}/tail.txt", "w") {|f| }
|
135
|
+
sleep 1
|
136
|
+
|
137
|
+
File.open("#{TMP_DIR}/tail.txt", "a") {|f|
|
138
|
+
f.puts "test5"
|
139
|
+
f.puts "test6"
|
140
|
+
}
|
141
|
+
sleep 1
|
142
|
+
end
|
143
|
+
|
144
|
+
d.run do
|
145
|
+
sleep 1
|
146
|
+
end
|
147
|
+
|
148
|
+
d.emits
|
61
149
|
end
|
62
150
|
|
63
151
|
def test_lf
|
@@ -79,7 +167,7 @@ class TailInputTest < Test::Unit::TestCase
|
|
79
167
|
|
80
168
|
emits = d.emits
|
81
169
|
assert_equal(true, emits.length > 0)
|
82
|
-
assert_equal({"message"=>"test3test4"}, emits[0][2])
|
170
|
+
assert_equal({"message" => "test3test4"}, emits[0][2])
|
83
171
|
end
|
84
172
|
|
85
173
|
def test_whitespace
|
@@ -103,12 +191,12 @@ class TailInputTest < Test::Unit::TestCase
|
|
103
191
|
|
104
192
|
emits = d.emits
|
105
193
|
assert_equal(true, emits.length > 0)
|
106
|
-
assert_equal({"message"=>" "}, emits[0][2])
|
107
|
-
assert_equal({"message"=>" 4 spaces"}, emits[1][2])
|
108
|
-
assert_equal({"message"=>"4 spaces "}, emits[2][2])
|
109
|
-
assert_equal({"message"=>" "}, emits[3][2])
|
110
|
-
assert_equal({"message"=>" tab"}, emits[4][2])
|
111
|
-
assert_equal({"message"=>"tab "}, emits[5][2])
|
194
|
+
assert_equal({"message" => " "}, emits[0][2])
|
195
|
+
assert_equal({"message" => " 4 spaces"}, emits[1][2])
|
196
|
+
assert_equal({"message" => "4 spaces "}, emits[2][2])
|
197
|
+
assert_equal({"message" => " "}, emits[3][2])
|
198
|
+
assert_equal({"message" => " tab"}, emits[4][2])
|
199
|
+
assert_equal({"message" => "tab "}, emits[5][2])
|
112
200
|
end
|
113
201
|
|
114
202
|
# multiline mode test
|
@@ -207,6 +295,33 @@ class TailInputTest < Test::Unit::TestCase
|
|
207
295
|
assert_equal({"message" => "test4"}, emits[3][2])
|
208
296
|
end
|
209
297
|
|
298
|
+
def test_multiline_without_firstline
|
299
|
+
File.open("#{TMP_DIR}/tail.txt", "w") { |f| }
|
300
|
+
|
301
|
+
d = create_driver %[
|
302
|
+
format multiline
|
303
|
+
format1 /(?<var1>foo \\d)\\n/
|
304
|
+
format2 /(?<var2>bar \\d)\\n/
|
305
|
+
format3 /(?<var3>baz \\d)/
|
306
|
+
]
|
307
|
+
d.run do
|
308
|
+
File.open("#{TMP_DIR}/tail.txt", "a") { |f|
|
309
|
+
f.puts "foo 1"
|
310
|
+
f.puts "bar 1"
|
311
|
+
f.puts "baz 1"
|
312
|
+
f.puts "foo 2"
|
313
|
+
f.puts "bar 2"
|
314
|
+
f.puts "baz 2"
|
315
|
+
}
|
316
|
+
sleep 1
|
317
|
+
end
|
318
|
+
|
319
|
+
emits = d.emits
|
320
|
+
assert_equal(2, emits.length)
|
321
|
+
assert_equal({"var1" => "foo 1", "var2" => "bar 1", "var3" => "baz 1"}, emits[0][2])
|
322
|
+
assert_equal({"var1" => "foo 2", "var2" => "bar 2", "var3" => "baz 2"}, emits[1][2])
|
323
|
+
end
|
324
|
+
|
210
325
|
# * path test
|
211
326
|
# TODO: Clean up tests
|
212
327
|
EX_RORATE_WAIT = 0
|
@@ -247,7 +362,7 @@ class TailInputTest < Test::Unit::TestCase
|
|
247
362
|
|
248
363
|
flexstub(Fluent::NewTailInput::TailWatcher) do |watcherclass|
|
249
364
|
EX_PATHS.each do |path|
|
250
|
-
watcherclass.should_receive(:new).with(path, EX_RORATE_WAIT, Fluent::NewTailInput::FilePositionEntry, any, any, any).once.and_return do
|
365
|
+
watcherclass.should_receive(:new).with(path, EX_RORATE_WAIT, Fluent::NewTailInput::FilePositionEntry, any, true, any, any).once.and_return do
|
251
366
|
flexmock('TailWatcher') { |watcher|
|
252
367
|
watcher.should_receive(:attach).once
|
253
368
|
watcher.should_receive(:unwatched=).zero_or_more_times
|
@@ -263,7 +378,7 @@ class TailInputTest < Test::Unit::TestCase
|
|
263
378
|
end
|
264
379
|
|
265
380
|
flexstub(Fluent::NewTailInput::TailWatcher) do |watcherclass|
|
266
|
-
watcherclass.should_receive(:new).with('test/plugin/data/2010/01/20100102-030406.log', EX_RORATE_WAIT, Fluent::NewTailInput::FilePositionEntry, any, any, any).once.and_return do
|
381
|
+
watcherclass.should_receive(:new).with('test/plugin/data/2010/01/20100102-030406.log', EX_RORATE_WAIT, Fluent::NewTailInput::FilePositionEntry, any, true, any, any).once.and_return do
|
267
382
|
flexmock('TailWatcher') do |watcher|
|
268
383
|
watcher.should_receive(:attach).once
|
269
384
|
watcher.should_receive(:unwatched=).zero_or_more_times
|
@@ -368,8 +483,8 @@ class TailInputTest < Test::Unit::TestCase
|
|
368
483
|
end
|
369
484
|
emits = d.emits
|
370
485
|
assert_equal(2, emits.length)
|
371
|
-
assert_equal({"message"=>"test3"}, emits[0][2])
|
372
|
-
assert_equal({"message"=>"test4"}, emits[1][2])
|
486
|
+
assert_equal({"message" => "test3"}, emits[0][2])
|
487
|
+
assert_equal({"message" => "test4"}, emits[1][2])
|
373
488
|
end
|
374
489
|
end
|
375
490
|
end
|
@@ -89,6 +89,30 @@ class FileOutputTest < Test::Unit::TestCase
|
|
89
89
|
check_gzipped_result(path, %[#{Yajl.dump({"a" => 1, 'time' => time})}\n] + %[#{Yajl.dump({"a" => 2, 'time' => time})}\n])
|
90
90
|
end
|
91
91
|
|
92
|
+
def test_write_with_format_ltsv
|
93
|
+
d = create_driver [CONFIG, 'format ltsv', 'include_time_key true'].join("\n")
|
94
|
+
|
95
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
96
|
+
d.emit({"a"=>1}, time)
|
97
|
+
d.emit({"a"=>2}, time)
|
98
|
+
|
99
|
+
# FileOutput#write returns path
|
100
|
+
path = d.run
|
101
|
+
check_gzipped_result(path, %[a:1\ttime:2011-01-02T13:14:15Z\n] + %[a:2\ttime:2011-01-02T13:14:15Z\n])
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_write_with_format_single_value
|
105
|
+
d = create_driver [CONFIG, 'format single_value', 'message_key a'].join("\n")
|
106
|
+
|
107
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
108
|
+
d.emit({"a"=>1}, time)
|
109
|
+
d.emit({"a"=>2}, time)
|
110
|
+
|
111
|
+
# FileOutput#write returns path
|
112
|
+
path = d.run
|
113
|
+
check_gzipped_result(path, %[1\n] + %[2\n])
|
114
|
+
end
|
115
|
+
|
92
116
|
def test_write_path_increment
|
93
117
|
d = create_driver
|
94
118
|
|
data/test/test_formatter.rb
CHANGED
@@ -177,7 +177,14 @@ module FormatterTest
|
|
177
177
|
def test_format
|
178
178
|
formatter = TextFormatter::TEMPLATE_REGISTRY.lookup('single_value').call
|
179
179
|
formatted = formatter.format('tag', Engine.now, {'message' => 'awesome'})
|
180
|
-
assert_equal(
|
180
|
+
assert_equal("awesome\n", formatted)
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_format_without_newline
|
184
|
+
formatter = TextFormatter::TEMPLATE_REGISTRY.lookup('single_value').call
|
185
|
+
formatter.configure('add_newline' => 'false')
|
186
|
+
formatted = formatter.format('tag', Engine.now, {'message' => 'awesome'})
|
187
|
+
assert_equal("awesome", formatted)
|
181
188
|
end
|
182
189
|
|
183
190
|
def test_format_with_message_key
|
@@ -185,7 +192,7 @@ module FormatterTest
|
|
185
192
|
formatter.configure('message_key' => 'foobar')
|
186
193
|
formatted = formatter.format('tag', Engine.now, {'foobar' => 'foo'})
|
187
194
|
|
188
|
-
assert_equal(
|
195
|
+
assert_equal("foo\n", formatted)
|
189
196
|
end
|
190
197
|
end
|
191
198
|
|
data/test/test_parser.rb
CHANGED
@@ -45,18 +45,19 @@ module ParserTest
|
|
45
45
|
include ParserTest
|
46
46
|
|
47
47
|
def internal_test_case(parser)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
48
|
+
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'
|
49
|
+
[parser.call(text), parser.call(text) { |time, record| return time, record}].each { |time, record|
|
50
|
+
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
51
|
+
assert_equal({
|
52
|
+
'user' => '-',
|
53
|
+
'flag' => true,
|
54
|
+
'code' => 200.0,
|
55
|
+
'size' => 777,
|
56
|
+
'date' => str2time('14/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'),
|
57
|
+
'host' => '192.168.0.1',
|
58
|
+
'path' => ['/', '/user']
|
59
|
+
}, record)
|
60
|
+
}
|
60
61
|
end
|
61
62
|
|
62
63
|
def test_call_with_typed
|
@@ -84,17 +85,17 @@ module ParserTest
|
|
84
85
|
end
|
85
86
|
|
86
87
|
def test_call
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
}
|
88
|
+
@parser.call('192.168.0.1 - - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777') { |time, record|
|
89
|
+
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
90
|
+
assert_equal({
|
91
|
+
'user' => '-',
|
92
|
+
'method' => 'GET',
|
93
|
+
'code' => '200',
|
94
|
+
'size' => '777',
|
95
|
+
'host' => '192.168.0.1',
|
96
|
+
'path' => '/'
|
97
|
+
}, record)
|
98
|
+
}
|
98
99
|
end
|
99
100
|
end
|
100
101
|
|
@@ -106,19 +107,19 @@ module ParserTest
|
|
106
107
|
end
|
107
108
|
|
108
109
|
def test_call
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
}
|
110
|
+
@parser.call('192.168.0.1 - - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0"') { |time, record|
|
111
|
+
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
112
|
+
assert_equal({
|
113
|
+
'user' => nil,
|
114
|
+
'method' => 'GET',
|
115
|
+
'code' => 200,
|
116
|
+
'size' => 777,
|
117
|
+
'host' => '192.168.0.1',
|
118
|
+
'path' => '/',
|
119
|
+
'referer' => nil,
|
120
|
+
'agent' => 'Opera/12.0'
|
121
|
+
}, record)
|
122
|
+
}
|
122
123
|
end
|
123
124
|
end
|
124
125
|
|
@@ -130,15 +131,15 @@ module ParserTest
|
|
130
131
|
end
|
131
132
|
|
132
133
|
def test_call
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
}
|
134
|
+
@parser.call('Feb 28 12:00:00 192.168.0.1 fluentd[11111]: [error] Syslog test') { |time, record|
|
135
|
+
assert_equal(str2time('Feb 28 12:00:00', '%b %d %H:%M:%S'), time)
|
136
|
+
assert_equal({
|
137
|
+
'host' => '192.168.0.1',
|
138
|
+
'ident' => 'fluentd',
|
139
|
+
'pid' => '11111',
|
140
|
+
'message' => '[error] Syslog test'
|
141
|
+
}, record)
|
142
|
+
}
|
142
143
|
end
|
143
144
|
end
|
144
145
|
|
@@ -150,14 +151,14 @@ module ParserTest
|
|
150
151
|
end
|
151
152
|
|
152
153
|
def test_call
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
}
|
154
|
+
@parser.call('{"time":1362020400,"host":"192.168.0.1","size":777,"method":"PUT"}') { |time, record|
|
155
|
+
assert_equal(str2time('2013-02-28 12:00:00 +0900').to_i, time)
|
156
|
+
assert_equal({
|
157
|
+
'host' => '192.168.0.1',
|
158
|
+
'size' => 777,
|
159
|
+
'method' => 'PUT',
|
160
|
+
}, record)
|
161
|
+
}
|
161
162
|
end
|
162
163
|
end
|
163
164
|
|
@@ -180,17 +181,62 @@ module ParserTest
|
|
180
181
|
end
|
181
182
|
|
182
183
|
def test_call
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
184
|
+
@parser.call('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|
|
185
|
+
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
186
|
+
assert_equal(@expected, record)
|
187
|
+
}
|
187
188
|
end
|
188
189
|
|
189
190
|
def test_call_with_empty_included_path
|
190
|
-
|
191
|
+
@parser.call('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|
|
192
|
+
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
193
|
+
assert_equal(@expected.merge('path' => '/a[ ]b'), record)
|
194
|
+
}
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
class TSVParserTest < ::Test::Unit::TestCase
|
199
|
+
include ParserTest
|
200
|
+
|
201
|
+
def test_config_params
|
202
|
+
parser = TextParser::TSVParser.new
|
191
203
|
|
192
|
-
assert_equal
|
193
|
-
|
204
|
+
assert_equal "\t", parser.delimiter
|
205
|
+
|
206
|
+
parser.configure(
|
207
|
+
'keys' => 'a,b',
|
208
|
+
'delimiter' => ',',
|
209
|
+
)
|
210
|
+
|
211
|
+
assert_equal ",", parser.delimiter
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_call
|
215
|
+
parser = TextParser::TSVParser.new
|
216
|
+
parser.configure('keys' => 'time,a,b', 'time_key' => 'time')
|
217
|
+
parser.call("2013/02/28 12:00:00\t192.168.0.1\t111") { |time, record|
|
218
|
+
assert_equal(str2time('2013/02/28 12:00:00', '%Y/%m/%d %H:%M:%S'), time)
|
219
|
+
assert_equal({
|
220
|
+
'a' => '192.168.0.1',
|
221
|
+
'b' => '111',
|
222
|
+
}, record)
|
223
|
+
}
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
class CSVParserTest < ::Test::Unit::TestCase
|
228
|
+
include ParserTest
|
229
|
+
|
230
|
+
def test_call
|
231
|
+
parser = TextParser::CSVParser.new
|
232
|
+
parser.configure('keys' => 'time,c,d', 'time_key' => 'time')
|
233
|
+
parser.call("2013/02/28 12:00:00,192.168.0.1,111") { |time, record|
|
234
|
+
assert_equal(str2time('2013/02/28 12:00:00', '%Y/%m/%d %H:%M:%S'), time)
|
235
|
+
assert_equal({
|
236
|
+
'c' => '192.168.0.1',
|
237
|
+
'd' => '111',
|
238
|
+
}, record)
|
239
|
+
}
|
194
240
|
end
|
195
241
|
end
|
196
242
|
|
@@ -215,13 +261,13 @@ module ParserTest
|
|
215
261
|
def test_call
|
216
262
|
parser = TextParser::LabeledTSVParser.new
|
217
263
|
parser.configure({})
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
}
|
264
|
+
parser.call("time:2013/02/28 12:00:00\thost:192.168.0.1\treq_id:111") { |time, record|
|
265
|
+
assert_equal(str2time('2013/02/28 12:00:00', '%Y/%m/%d %H:%M:%S'), time)
|
266
|
+
assert_equal({
|
267
|
+
'host' => '192.168.0.1',
|
268
|
+
'req_id' => '111',
|
269
|
+
}, record)
|
270
|
+
}
|
225
271
|
end
|
226
272
|
|
227
273
|
def test_call_with_customized_delimiter
|
@@ -230,13 +276,13 @@ module ParserTest
|
|
230
276
|
'delimiter' => ',',
|
231
277
|
'label_delimiter' => '=',
|
232
278
|
)
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
}
|
279
|
+
parser.call('time=2013/02/28 12:00:00,host=192.168.0.1,req_id=111') { |time, record|
|
280
|
+
assert_equal(str2time('2013/02/28 12:00:00', '%Y/%m/%d %H:%M:%S'), time)
|
281
|
+
assert_equal({
|
282
|
+
'host' => '192.168.0.1',
|
283
|
+
'req_id' => '111',
|
284
|
+
}, record)
|
285
|
+
}
|
240
286
|
end
|
241
287
|
|
242
288
|
def test_call_with_customized_time_format
|
@@ -245,13 +291,13 @@ module ParserTest
|
|
245
291
|
'time_key' => 'mytime',
|
246
292
|
'time_format' => '%d/%b/%Y:%H:%M:%S %z',
|
247
293
|
)
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
}
|
294
|
+
parser.call("mytime:28/Feb/2013:12:00:00 +0900\thost:192.168.0.1\treq_id:111") { |time, record|
|
295
|
+
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
296
|
+
assert_equal({
|
297
|
+
'host' => '192.168.0.1',
|
298
|
+
'req_id' => '111',
|
299
|
+
}, record)
|
300
|
+
}
|
255
301
|
end
|
256
302
|
end
|
257
303
|
|
@@ -268,17 +314,17 @@ module ParserTest
|
|
268
314
|
|
269
315
|
def test_call
|
270
316
|
parser = TextParser::TEMPLATE_REGISTRY.lookup('none').call
|
271
|
-
|
272
|
-
|
273
|
-
|
317
|
+
parser.call('log message!') { |time, record|
|
318
|
+
assert_equal({'message' => 'log message!'}, record)
|
319
|
+
}
|
274
320
|
end
|
275
321
|
|
276
322
|
def test_call_with_message_key
|
277
323
|
parser = TextParser::NoneParser.new
|
278
324
|
parser.configure('message_key' => 'foobar')
|
279
|
-
|
280
|
-
|
281
|
-
|
325
|
+
parser.call('log message!') { |time, record|
|
326
|
+
assert_equal({'foobar' => 'log message!'}, record)
|
327
|
+
}
|
282
328
|
end
|
283
329
|
end
|
284
330
|
|
@@ -301,31 +347,33 @@ module ParserTest
|
|
301
347
|
|
302
348
|
def test_call
|
303
349
|
parser = create_parser('format1' => '/^(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}) \[(?<thread>.*)\] (?<level>[^\s]+)(?<message>.*)/')
|
304
|
-
|
350
|
+
parser.call(<<EOS.chomp) { |time, record|
|
305
351
|
2013-3-03 14:27:33 [main] ERROR Main - Exception
|
306
352
|
javax.management.RuntimeErrorException: null
|
307
353
|
\tat Main.main(Main.java:16) ~[bin/:na]
|
308
354
|
EOS
|
309
355
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
356
|
+
assert_equal(str2time('2013-3-03 14:27:33').to_i, time)
|
357
|
+
assert_equal({
|
358
|
+
"thread" => "main",
|
359
|
+
"level" => "ERROR",
|
360
|
+
"message" => " Main - Exception\njavax.management.RuntimeErrorException: null\n\tat Main.main(Main.java:16) ~[bin/:na]"
|
361
|
+
}, record)
|
362
|
+
}
|
316
363
|
end
|
317
364
|
|
318
365
|
def test_call_with_firstline
|
319
366
|
parser = create_parser('format_firstline' => '/----/', 'format1' => '/time=(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}).*message=(?<message>.*)/')
|
320
|
-
|
367
|
+
parser.call(<<EOS.chomp) { |time, record|
|
321
368
|
----
|
322
369
|
time=2013-3-03 14:27:33
|
323
370
|
message=test1
|
324
371
|
EOS
|
325
372
|
|
326
|
-
|
327
|
-
|
328
|
-
|
373
|
+
assert(parser.firstline?('----'))
|
374
|
+
assert_equal(str2time('2013-3-03 14:27:33').to_i, time)
|
375
|
+
assert_equal({"message" => "test1"}, record)
|
376
|
+
}
|
329
377
|
end
|
330
378
|
|
331
379
|
def test_call_with_multiple_formats
|
@@ -336,7 +384,7 @@ EOS
|
|
336
384
|
'format4' => '/ Rendered (?<template>[^ ]+) within (?<layout>.+) \([\d\.]+ms\)\n/',
|
337
385
|
'format5' => '/Completed (?<code>[^ ]+) [^ ]+ in (?<runtime>[\d\.]+)ms \(Views: (?<view_runtime>[\d\.]+)ms \| ActiveRecord: (?<ar_runtime>[\d\.]+)ms\)/'
|
338
386
|
)
|
339
|
-
|
387
|
+
parser.call(<<EOS.chomp) { |time, record|
|
340
388
|
Started GET "/users/123/" for 127.0.0.1 at 2013-06-14 12:00:11 +0900
|
341
389
|
Processing by UsersController#show as HTML
|
342
390
|
Parameters: {"user_id"=>"123"}
|
@@ -344,40 +392,82 @@ Processing by UsersController#show as HTML
|
|
344
392
|
Completed 200 OK in 4ms (Views: 3.2ms | ActiveRecord: 0.0ms)
|
345
393
|
EOS
|
346
394
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
395
|
+
assert(parser.firstline?('Started GET "/users/123/" for 127.0.0.1...'))
|
396
|
+
assert_equal(str2time('2013-06-14 12:00:11 +0900').to_i, time)
|
397
|
+
assert_equal({
|
398
|
+
"method" => "GET",
|
399
|
+
"path" => "/users/123/",
|
400
|
+
"host" => "127.0.0.1",
|
401
|
+
"controller" => "UsersController",
|
402
|
+
"controller_method" => "show",
|
403
|
+
"format" => "HTML",
|
404
|
+
"parameters" => "{\"user_id\"=>\"123\"}",
|
405
|
+
"template" => "users/show.html.erb",
|
406
|
+
"layout" => "layouts/application",
|
407
|
+
"code" => "200",
|
408
|
+
"runtime" => "4",
|
409
|
+
"view_runtime" => "3.2",
|
410
|
+
"ar_runtime" => "0.0"
|
411
|
+
}, record)
|
412
|
+
}
|
364
413
|
end
|
365
414
|
end
|
366
415
|
|
367
|
-
class
|
416
|
+
class TextParserTest < ::Test::Unit::TestCase
|
368
417
|
include ParserTest
|
369
418
|
|
370
|
-
|
419
|
+
class MultiEventTestParser
|
420
|
+
include Fluent::Configurable
|
421
|
+
|
422
|
+
def call(text)
|
423
|
+
2.times { |i|
|
424
|
+
record = {}
|
425
|
+
record['message'] = text
|
426
|
+
record['number'] = i
|
427
|
+
yield Fluent::Engine.now, record
|
428
|
+
}
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
TextParser.register_template('multi_event_test', Proc.new { MultiEventTestParser.new })
|
433
|
+
|
434
|
+
def test_lookup_unknown_format
|
371
435
|
assert_raise ConfigError do
|
372
436
|
TextParser::TEMPLATE_REGISTRY.lookup('unknown')
|
373
437
|
end
|
374
438
|
end
|
375
439
|
|
376
|
-
def
|
440
|
+
def test_lookup_known_parser
|
377
441
|
$LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), 'scripts'))
|
378
442
|
assert_nothing_raised ConfigError do
|
379
443
|
TextParser::TEMPLATE_REGISTRY.lookup('known')
|
380
444
|
end
|
381
445
|
end
|
446
|
+
|
447
|
+
def test_parse_with_return
|
448
|
+
parser = TextParser.new
|
449
|
+
parser.configure('format' => 'none')
|
450
|
+
time, record = parser.parse('log message!')
|
451
|
+
assert_equal({'message' => 'log message!'}, record)
|
452
|
+
end
|
453
|
+
|
454
|
+
def test_parse_with_block
|
455
|
+
parser = TextParser.new
|
456
|
+
parser.configure('format' => 'none')
|
457
|
+
parser.parse('log message!') { |time, record|
|
458
|
+
assert_equal({'message' => 'log message!'}, record)
|
459
|
+
}
|
460
|
+
end
|
461
|
+
|
462
|
+
def test_multi_event_parser
|
463
|
+
parser = TextParser.new
|
464
|
+
parser.configure('format' => 'multi_event_test')
|
465
|
+
i = 0
|
466
|
+
parser.parse('log message!') { |time, record|
|
467
|
+
assert_equal('log message!', record['message'])
|
468
|
+
assert_equal(i, record['number'])
|
469
|
+
i += 1
|
470
|
+
}
|
471
|
+
end
|
382
472
|
end
|
383
473
|
end
|