fluentd 0.12.0.pre.2 → 0.12.0.pre.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/example/v0_12_filter.conf +78 -0
- data/fluentd.gemspec +2 -1
- data/lib/fluent/agent.rb +2 -1
- data/lib/fluent/buffer.rb +9 -5
- data/lib/fluent/command/fluentd.rb +4 -0
- data/lib/fluent/config/basic_parser.rb +1 -0
- data/lib/fluent/config/configure_proxy.rb +7 -7
- data/lib/fluent/config/types.rb +1 -0
- data/lib/fluent/config/v1_parser.rb +1 -1
- data/lib/fluent/engine.rb +0 -25
- data/lib/fluent/env.rb +1 -0
- data/lib/fluent/event_router.rb +6 -2
- data/lib/fluent/filter.rb +12 -1
- data/lib/fluent/formatter.rb +85 -16
- data/lib/fluent/label.rb +4 -0
- data/lib/fluent/output.rb +1 -0
- data/lib/fluent/parser.rb +25 -23
- data/lib/fluent/plugin.rb +18 -0
- data/lib/fluent/plugin/buf_file.rb +1 -1
- data/lib/fluent/plugin/in_dummy.rb +103 -0
- data/lib/fluent/plugin/in_http.rb +30 -10
- data/lib/fluent/plugin/in_syslog.rb +4 -4
- data/lib/fluent/plugin/in_tail.rb +6 -6
- data/lib/fluent/plugin/out_file.rb +3 -3
- data/lib/fluent/plugin/socket_util.rb +2 -2
- data/lib/fluent/registry.rb +9 -27
- data/lib/fluent/root_agent.rb +26 -7
- data/lib/fluent/supervisor.rb +40 -27
- data/lib/fluent/test.rb +1 -0
- data/lib/fluent/test/base.rb +14 -0
- data/lib/fluent/test/filter_test.rb +33 -0
- data/lib/fluent/test/output_test.rb +7 -1
- data/lib/fluent/version.rb +1 -1
- data/test/config/test_config_parser.rb +6 -2
- data/test/config/test_configurable.rb +1 -1
- data/test/config/test_configure_proxy.rb +1 -1
- data/test/config/test_dsl.rb +1 -1
- data/test/config/test_literal_parser.rb +2 -2
- data/test/config/test_section.rb +1 -1
- data/test/config/test_system_config.rb +65 -15
- data/test/config/test_types.rb +63 -0
- data/test/helper.rb +2 -1
- data/test/plugin/test_buf_file.rb +1 -1
- data/test/plugin/test_buf_memory.rb +1 -1
- data/test/plugin/test_filter_grep.rb +17 -23
- data/test/plugin/test_filter_record_transformer.rb +18 -21
- data/test/plugin/test_in_dummy.rb +95 -0
- data/test/plugin/test_in_exec.rb +1 -1
- data/test/plugin/test_in_forward.rb +1 -1
- data/test/plugin/test_in_gc_stat.rb +1 -1
- data/test/plugin/test_in_http.rb +1 -1
- data/test/plugin/test_in_object_space.rb +1 -1
- data/test/plugin/test_in_status.rb +1 -1
- data/test/plugin/test_in_stream.rb +1 -1
- data/test/plugin/test_in_syslog.rb +1 -1
- data/test/plugin/test_in_tail.rb +1 -1
- data/test/plugin/test_in_tcp.rb +1 -1
- data/test/plugin/test_in_udp.rb +1 -1
- data/test/plugin/test_out_copy.rb +12 -1
- data/test/plugin/test_out_exec.rb +1 -1
- data/test/plugin/test_out_exec_filter.rb +1 -1
- data/test/plugin/test_out_file.rb +61 -8
- data/test/plugin/test_out_forward.rb +1 -1
- data/test/plugin/test_out_roundrobin.rb +12 -1
- data/test/plugin/test_out_stdout.rb +1 -1
- data/test/plugin/test_out_stream.rb +1 -1
- data/test/scripts/fluent/plugin/formatter_known.rb +4 -1
- data/{lib → test/scripts}/fluent/plugin/out_test.rb +0 -0
- data/test/scripts/fluent/plugin/parser_known.rb +2 -1
- data/test/test_buffer.rb +1 -1
- data/test/test_config.rb +1 -1
- data/test/test_configdsl.rb +1 -1
- data/test/test_event_router.rb +233 -0
- data/test/test_formatter.rb +160 -3
- data/test/test_input.rb +30 -0
- data/test/test_match.rb +100 -77
- data/test/test_mixin.rb +1 -1
- data/test/test_output.rb +1 -1
- data/test/test_parser.rb +5 -3
- data/test/test_plugin_classes.rb +60 -0
- metadata +32 -4
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../helper'
|
2
2
|
require 'fluent/test'
|
3
3
|
require 'fileutils'
|
4
4
|
require 'time'
|
@@ -126,7 +126,7 @@ class FileOutputTest < Test::Unit::TestCase
|
|
126
126
|
|
127
127
|
# FileOutput#write returns path
|
128
128
|
path = d.run
|
129
|
-
expect_path = "#{TMP_DIR}/out_file_test.
|
129
|
+
expect_path = "#{TMP_DIR}/out_file_test.20110102_0.log.gz"
|
130
130
|
assert_equal expect_path, path
|
131
131
|
|
132
132
|
check_gzipped_result(path, %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n])
|
@@ -178,13 +178,13 @@ class FileOutputTest < Test::Unit::TestCase
|
|
178
178
|
|
179
179
|
# FileOutput#write returns path
|
180
180
|
path = d.run
|
181
|
-
assert_equal "#{TMP_DIR}/out_file_test.
|
181
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102_0.log.gz", path
|
182
182
|
check_gzipped_result(path, formatted_lines)
|
183
183
|
path = d.run
|
184
|
-
assert_equal "#{TMP_DIR}/out_file_test.
|
184
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102_1.log.gz", path
|
185
185
|
check_gzipped_result(path, formatted_lines)
|
186
186
|
path = d.run
|
187
|
-
assert_equal "#{TMP_DIR}/out_file_test.
|
187
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102_2.log.gz", path
|
188
188
|
check_gzipped_result(path, formatted_lines)
|
189
189
|
end
|
190
190
|
|
@@ -203,13 +203,13 @@ class FileOutputTest < Test::Unit::TestCase
|
|
203
203
|
|
204
204
|
# FileOutput#write returns path
|
205
205
|
path = d.run
|
206
|
-
assert_equal "#{TMP_DIR}/out_file_test
|
206
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
207
207
|
check_gzipped_result(path, formatted_lines)
|
208
208
|
path = d.run
|
209
|
-
assert_equal "#{TMP_DIR}/out_file_test
|
209
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
210
210
|
check_gzipped_result(path, formatted_lines * 2)
|
211
211
|
path = d.run
|
212
|
-
assert_equal "#{TMP_DIR}/out_file_test
|
212
|
+
assert_equal "#{TMP_DIR}/out_file_test.20110102.log.gz", path
|
213
213
|
check_gzipped_result(path, formatted_lines * 3)
|
214
214
|
end
|
215
215
|
|
@@ -241,5 +241,58 @@ class FileOutputTest < Test::Unit::TestCase
|
|
241
241
|
FileUtils.rm_rf(symlink_path)
|
242
242
|
end
|
243
243
|
end
|
244
|
+
|
245
|
+
sub_test_case 'path' do
|
246
|
+
test 'normal' do
|
247
|
+
d = create_driver(%[
|
248
|
+
path #{TMP_DIR}/out_file_test
|
249
|
+
time_slice_format %Y-%m-%d-%H
|
250
|
+
utc true
|
251
|
+
])
|
252
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
253
|
+
d.emit({"a"=>1}, time)
|
254
|
+
# FileOutput#write returns path
|
255
|
+
path = d.run
|
256
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13_0.log", path
|
257
|
+
end
|
258
|
+
|
259
|
+
test 'normal with append' do
|
260
|
+
d = create_driver(%[
|
261
|
+
path #{TMP_DIR}/out_file_test
|
262
|
+
time_slice_format %Y-%m-%d-%H
|
263
|
+
utc true
|
264
|
+
append true
|
265
|
+
])
|
266
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
267
|
+
d.emit({"a"=>1}, time)
|
268
|
+
path = d.run
|
269
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13.log", path
|
270
|
+
end
|
271
|
+
|
272
|
+
test '*' do
|
273
|
+
d = create_driver(%[
|
274
|
+
path #{TMP_DIR}/out_file_test.*.txt
|
275
|
+
time_slice_format %Y-%m-%d-%H
|
276
|
+
utc true
|
277
|
+
])
|
278
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
279
|
+
d.emit({"a"=>1}, time)
|
280
|
+
path = d.run
|
281
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13_0.txt", path
|
282
|
+
end
|
283
|
+
|
284
|
+
test '* with append' do
|
285
|
+
d = create_driver(%[
|
286
|
+
path #{TMP_DIR}/out_file_test.*.txt
|
287
|
+
time_slice_format %Y-%m-%d-%H
|
288
|
+
utc true
|
289
|
+
append true
|
290
|
+
])
|
291
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
292
|
+
d.emit({"a"=>1}, time)
|
293
|
+
path = d.run
|
294
|
+
assert_equal "#{TMP_DIR}/out_file_test.2011-01-02-13.txt", path
|
295
|
+
end
|
296
|
+
end
|
244
297
|
end
|
245
298
|
|
@@ -1,7 +1,18 @@
|
|
1
|
-
|
1
|
+
require_relative '../helper'
|
2
2
|
require 'fluent/test'
|
3
3
|
|
4
4
|
class RoundRobinOutputTest < Test::Unit::TestCase
|
5
|
+
class << self
|
6
|
+
def startup
|
7
|
+
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'scripts'))
|
8
|
+
require 'fluent/plugin/out_test'
|
9
|
+
end
|
10
|
+
|
11
|
+
def shutdown
|
12
|
+
$LOAD_PATH.shift
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
5
16
|
def setup
|
6
17
|
Fluent::Test.setup
|
7
18
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module Fluent
|
2
|
-
TextFormatter.register_template('
|
2
|
+
TextFormatter.register_template('known_old', Proc.new { |tag, time, record|
|
3
|
+
"#{tag}:#{time}:#{record.size}"
|
4
|
+
})
|
5
|
+
Plugin.register_formatter('known', Proc.new { |tag, time, record|
|
3
6
|
"#{tag}:#{time}:#{record.size}"
|
4
7
|
})
|
5
8
|
end
|
File without changes
|
data/test/test_buffer.rb
CHANGED
data/test/test_config.rb
CHANGED
data/test/test_configdsl.rb
CHANGED
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'fluent/event_router'
|
2
|
+
require_relative 'test_plugin_classes'
|
3
|
+
|
4
|
+
class EventRouterTest < ::Test::Unit::TestCase
|
5
|
+
include Fluent
|
6
|
+
include FluentTest
|
7
|
+
|
8
|
+
teardown do
|
9
|
+
@output = nil
|
10
|
+
@filter = nil
|
11
|
+
@error_output = nil
|
12
|
+
@emit_handler = nil
|
13
|
+
@default_collector = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def output
|
17
|
+
@output ||= FluentTestOutput.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def filter
|
21
|
+
@filter ||= FluentTestFilter.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def error_output
|
25
|
+
@error_output ||= FluentTestErrorOutput.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def emit_handler
|
29
|
+
@emit_handler ||= TestEmitErrorHandler.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def default_collector
|
33
|
+
@default_collector ||= FluentTestOutput.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def event(record, time = Engine.now)
|
37
|
+
OneEventStream.new(time, record)
|
38
|
+
end
|
39
|
+
|
40
|
+
DEFAULT_EVENT_NUM = 5
|
41
|
+
|
42
|
+
def events(num = DEFAULT_EVENT_NUM)
|
43
|
+
es = MultiEventStream.new
|
44
|
+
num.times { |i|
|
45
|
+
es.add(Engine.now, 'key' => "value#{i}")
|
46
|
+
}
|
47
|
+
es
|
48
|
+
end
|
49
|
+
|
50
|
+
sub_test_case EventRouter::MatchCache do
|
51
|
+
setup do
|
52
|
+
@match_cache = EventRouter::MatchCache.new
|
53
|
+
end
|
54
|
+
|
55
|
+
test "call block when non-cached key" do
|
56
|
+
assert_raise(RuntimeError.new('Test!')) {
|
57
|
+
@match_cache.get('test') { raise 'Test!' }
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
test "don't call block when cached key" do
|
62
|
+
@match_cache.get('test') { "I'm cached" }
|
63
|
+
assert_nothing_raised {
|
64
|
+
@match_cache.get('test') { raise 'Test!' }
|
65
|
+
}
|
66
|
+
assert_equal "I'm cached", @match_cache.get('test') { raise 'Test!' }
|
67
|
+
end
|
68
|
+
|
69
|
+
test "call block when keys are expired" do
|
70
|
+
cache_size = EventRouter::MatchCache::MATCH_CACHE_SIZE
|
71
|
+
cache_size.times { |i|
|
72
|
+
@match_cache.get("test#{i}") { "I'm cached #{i}" }
|
73
|
+
}
|
74
|
+
assert_nothing_raised {
|
75
|
+
cache_size.times { |i|
|
76
|
+
@match_cache.get("test#{i}") { raise "Why called?" }
|
77
|
+
}
|
78
|
+
}
|
79
|
+
# expire old keys
|
80
|
+
cache_size.times { |i|
|
81
|
+
@match_cache.get("new_test#{i}") { "I'm young #{i}" }
|
82
|
+
}
|
83
|
+
num_called = 0
|
84
|
+
cache_size.times { |i|
|
85
|
+
@match_cache.get("test#{i}") { num_called += 1 }
|
86
|
+
}
|
87
|
+
assert_equal cache_size, num_called
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
sub_test_case EventRouter::Pipeline do
|
92
|
+
setup do
|
93
|
+
@pipeline = EventRouter::Pipeline.new
|
94
|
+
@es = event('key' => 'value')
|
95
|
+
end
|
96
|
+
|
97
|
+
test 'set one output' do
|
98
|
+
@pipeline.set_output(output)
|
99
|
+
@pipeline.emit('test', @es, nil)
|
100
|
+
assert_equal 1, output.events.size
|
101
|
+
assert_equal 'value', output.events['test'].first['key']
|
102
|
+
end
|
103
|
+
|
104
|
+
sub_test_case 'with filter' do
|
105
|
+
setup do
|
106
|
+
@pipeline.set_output(output)
|
107
|
+
end
|
108
|
+
|
109
|
+
test 'set one filer' do
|
110
|
+
@pipeline.add_filter(filter)
|
111
|
+
@pipeline.emit('test', @es, nil)
|
112
|
+
assert_equal 1, output.events.size
|
113
|
+
assert_equal 'value', output.events['test'].first['key']
|
114
|
+
assert_equal 0, output.events['test'].first['__test__']
|
115
|
+
end
|
116
|
+
|
117
|
+
test 'set one filer with multi events' do
|
118
|
+
@pipeline.add_filter(filter)
|
119
|
+
@pipeline.emit('test', events, nil)
|
120
|
+
assert_equal 1, output.events.size
|
121
|
+
assert_equal 5, output.events['test'].size
|
122
|
+
DEFAULT_EVENT_NUM.times { |i|
|
123
|
+
assert_equal "value#{i}", output.events['test'][i]['key']
|
124
|
+
assert_equal i, output.events['test'][i]['__test__']
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
sub_test_case EventRouter do
|
131
|
+
teardown do
|
132
|
+
@event_router = nil
|
133
|
+
end
|
134
|
+
|
135
|
+
def event_router
|
136
|
+
@event_router ||= EventRouter.new(default_collector, emit_handler)
|
137
|
+
end
|
138
|
+
|
139
|
+
sub_test_case 'default collector' do
|
140
|
+
test 'call default collector when no output' do
|
141
|
+
assert_rr do
|
142
|
+
mock(default_collector).emit('test', is_a(OneEventStream), NullOutputChain.instance)
|
143
|
+
event_router.emit('test', Engine.now, 'k' => 'v')
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
test "call default collector when only filter" do
|
148
|
+
event_router.add_rule('test', filter)
|
149
|
+
assert_rr do
|
150
|
+
# After apply Filter, EventStream becomes MultiEventStream by default
|
151
|
+
mock(default_collector).emit('test', is_a(MultiEventStream), NullOutputChain.instance)
|
152
|
+
event_router.emit('test', Engine.now, 'k' => 'v')
|
153
|
+
end
|
154
|
+
assert_equal 1, filter.num
|
155
|
+
end
|
156
|
+
|
157
|
+
test "call default collector when no matched with output" do
|
158
|
+
event_router.add_rule('test', output)
|
159
|
+
assert_rr do
|
160
|
+
mock(default_collector).emit('dummy', is_a(OneEventStream), NullOutputChain.instance)
|
161
|
+
event_router.emit('dummy', Engine.now, 'k' => 'v')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
test "don't call default collector when tag matched" do
|
166
|
+
event_router.add_rule('test', output)
|
167
|
+
assert_rr do
|
168
|
+
dont_allow(default_collector).emit('test', is_a(OneEventStream), NullOutputChain.instance)
|
169
|
+
event_router.emit('test', Engine.now, 'k' => 'v')
|
170
|
+
end
|
171
|
+
# check emit handler doesn't catch rr error
|
172
|
+
assert_empty emit_handler.events
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
sub_test_case 'filter' do
|
177
|
+
test 'filter should be called when tag matched' do
|
178
|
+
event_router.add_rule('test', filter)
|
179
|
+
|
180
|
+
assert_rr do
|
181
|
+
mock(filter).filter_stream('test', is_a(OneEventStream)) { events }
|
182
|
+
event_router.emit('test', Engine.now, 'k' => 'v')
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
test 'filter should not be called when tag mismatched' do
|
187
|
+
event_router.add_rule('test', filter)
|
188
|
+
|
189
|
+
assert_rr do
|
190
|
+
dont_allow(filter).filter_stream('test', is_a(OneEventStream)) { events }
|
191
|
+
event_router.emit('foo', Engine.now, 'k' => 'v')
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
test 'filter changes records' do
|
196
|
+
event_router.add_rule('test', filter)
|
197
|
+
event_router.add_rule('test', output)
|
198
|
+
event_router.emit('test', Engine.now, 'k' => 'v')
|
199
|
+
|
200
|
+
assert_equal 1, filter.num
|
201
|
+
assert_equal 1, output.events['test'].size
|
202
|
+
assert_equal 0, output.events['test'].first['__test__']
|
203
|
+
assert_equal 'v', output.events['test'].first['k']
|
204
|
+
end
|
205
|
+
|
206
|
+
test 'filter can be chained' do
|
207
|
+
other_filter = FluentTestFilter.new('__hoge__')
|
208
|
+
event_router.add_rule('test', filter)
|
209
|
+
event_router.add_rule('test', other_filter)
|
210
|
+
event_router.add_rule('test', output)
|
211
|
+
event_router.emit('test', Engine.now, 'k' => 'v')
|
212
|
+
|
213
|
+
assert_equal 1, filter.num
|
214
|
+
assert_equal 1, other_filter.num
|
215
|
+
assert_equal 1, output.events['test'].size
|
216
|
+
assert_equal 0, output.events['test'].first['__test__']
|
217
|
+
assert_equal 0, output.events['test'].first['__hoge__']
|
218
|
+
assert_equal 'v', output.events['test'].first['k']
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
sub_test_case 'emit_error_handler' do
|
223
|
+
test 'call handle_emits_error when emit failed' do
|
224
|
+
event_router.add_rule('test', error_output)
|
225
|
+
|
226
|
+
assert_rr do
|
227
|
+
mock(emit_handler).handle_emits_error('test', is_a(OneEventStream), is_a(RuntimeError))
|
228
|
+
event_router.emit('test', Engine.now, 'k' => 'v')
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
data/test/test_formatter.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative 'helper'
|
2
2
|
require 'fluent/test'
|
3
3
|
require 'fluent/formatter'
|
4
4
|
|
@@ -120,6 +120,49 @@ module FormatterTest
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
+
class MessagePackFormatterTest < ::Test::Unit::TestCase
|
124
|
+
include FormatterTest
|
125
|
+
|
126
|
+
def setup
|
127
|
+
@formatter = TextFormatter::MessagePackFormatter.new
|
128
|
+
@time = Engine.now
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_format
|
132
|
+
@formatter.configure({})
|
133
|
+
formatted = @formatter.format(tag, @time, record)
|
134
|
+
|
135
|
+
assert_equal(record.to_msgpack, formatted)
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_format_with_include_tag
|
139
|
+
@formatter.configure('include_tag_key' => 'true', 'tag_key' => 'foo')
|
140
|
+
formatted = @formatter.format(tag, @time, record.dup)
|
141
|
+
|
142
|
+
r = record
|
143
|
+
r['foo'] = tag
|
144
|
+
assert_equal(r.to_msgpack, formatted)
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_format_with_include_time
|
148
|
+
@formatter.configure('include_time_key' => 'true', 'localtime' => '')
|
149
|
+
formatted = @formatter.format(tag, @time, record.dup)
|
150
|
+
|
151
|
+
r = record
|
152
|
+
r['time'] = time2str(@time, true)
|
153
|
+
assert_equal(r.to_msgpack, formatted)
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_format_with_include_time_as_number
|
157
|
+
@formatter.configure('include_time_key' => 'true', 'time_as_epoch' => 'true', 'time_key' => 'epoch')
|
158
|
+
formatted = @formatter.format(tag, @time, record.dup)
|
159
|
+
|
160
|
+
r = record
|
161
|
+
r['epoch'] = @time
|
162
|
+
assert_equal(r.to_msgpack, formatted)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
123
166
|
class LabeledTSVFormatterTest < ::Test::Unit::TestCase
|
124
167
|
include FormatterTest
|
125
168
|
|
@@ -174,6 +217,118 @@ module FormatterTest
|
|
174
217
|
end
|
175
218
|
end
|
176
219
|
|
220
|
+
class CsvFormatterTest < ::Test::Unit::TestCase
|
221
|
+
include FormatterTest
|
222
|
+
|
223
|
+
def setup
|
224
|
+
@formatter = TextFormatter::CsvFormatter.new
|
225
|
+
@time = Engine.now
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_config_params
|
229
|
+
assert_equal ',', @formatter.delimiter
|
230
|
+
assert_equal true, @formatter.force_quotes
|
231
|
+
assert_equal [], @formatter.fields
|
232
|
+
end
|
233
|
+
|
234
|
+
data(
|
235
|
+
'tab_char' => ["\t", '\t'],
|
236
|
+
'tab_string' => ["\t", 'TAB'],
|
237
|
+
'pipe' => ['|', '|'])
|
238
|
+
def test_config_params_with_customized_delimiters(data)
|
239
|
+
expected, target = data
|
240
|
+
@formatter.configure('delimiter' => target)
|
241
|
+
assert_equal expected, @formatter.delimiter
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_format
|
245
|
+
@formatter.configure('fields' => 'message,message2')
|
246
|
+
formatted = @formatter.format(tag, @time, {
|
247
|
+
'message' => 'awesome',
|
248
|
+
'message2' => 'awesome2'
|
249
|
+
})
|
250
|
+
assert_equal("\"awesome\",\"awesome2\"\n", formatted)
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_format_with_tag
|
254
|
+
@formatter.configure(
|
255
|
+
'fields' => 'tag,message,message2',
|
256
|
+
'include_tag_key' => 'true'
|
257
|
+
)
|
258
|
+
formatted = @formatter.format(tag, @time, {
|
259
|
+
'message' => 'awesome',
|
260
|
+
'message2' => 'awesome2'
|
261
|
+
})
|
262
|
+
assert_equal("\"tag\",\"awesome\",\"awesome2\"\n", formatted)
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_format_with_time
|
266
|
+
@formatter.configure(
|
267
|
+
'fields' => 'time,message,message2',
|
268
|
+
'include_time_key' => 'true',
|
269
|
+
'time_format' => '%Y'
|
270
|
+
)
|
271
|
+
formatted = @formatter.format(tag, @time, {
|
272
|
+
'message' => 'awesome',
|
273
|
+
'message2' => 'awesome2'
|
274
|
+
})
|
275
|
+
assert_equal("\"#{Time.now.year}\",\"awesome\",\"awesome2\"\n",
|
276
|
+
formatted)
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_format_with_customized_delimiters
|
280
|
+
@formatter.configure(
|
281
|
+
'fields' => 'message,message2',
|
282
|
+
'delimiter' => '\t'
|
283
|
+
)
|
284
|
+
formatted = @formatter.format(tag, @time, {
|
285
|
+
'message' => 'awesome',
|
286
|
+
'message2' => 'awesome2'
|
287
|
+
})
|
288
|
+
assert_equal("\"awesome\"\t\"awesome2\"\n", formatted)
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_format_with_non_quote
|
292
|
+
@formatter.configure(
|
293
|
+
'fields' => 'message,message2',
|
294
|
+
'force_quotes' => 'false'
|
295
|
+
)
|
296
|
+
formatted = @formatter.format(tag, @time, {
|
297
|
+
'message' => 'awesome',
|
298
|
+
'message2' => 'awesome2'
|
299
|
+
})
|
300
|
+
assert_equal("awesome,awesome2\n", formatted)
|
301
|
+
end
|
302
|
+
|
303
|
+
data(
|
304
|
+
'nil' => {
|
305
|
+
'message' => 'awesome',
|
306
|
+
'message2' => nil,
|
307
|
+
'message3' => 'awesome3'
|
308
|
+
},
|
309
|
+
'blank' => {
|
310
|
+
'message' => 'awesome',
|
311
|
+
'message2' => '',
|
312
|
+
'message3' => 'awesome3'
|
313
|
+
})
|
314
|
+
def test_format_with_empty_fields(data)
|
315
|
+
@formatter.configure(
|
316
|
+
'fields' => 'message,message2,message3'
|
317
|
+
)
|
318
|
+
formatted = @formatter.format(tag, @time, data)
|
319
|
+
assert_equal("\"awesome\",\"\",\"awesome3\"\n", formatted)
|
320
|
+
end
|
321
|
+
|
322
|
+
data(
|
323
|
+
'normally' => 'one,two,three',
|
324
|
+
'white_space' => 'one , two , three',
|
325
|
+
'blank' => 'one,,two,three')
|
326
|
+
def test_config_params_with_fields(data)
|
327
|
+
@formatter.configure('fields' => data)
|
328
|
+
assert_equal %w(one two three), @formatter.fields
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
177
332
|
class SingleValueFormatterTest < ::Test::Unit::TestCase
|
178
333
|
include FormatterTest
|
179
334
|
|
@@ -216,11 +371,13 @@ module FormatterTest
|
|
216
371
|
end
|
217
372
|
end
|
218
373
|
|
219
|
-
|
374
|
+
data('register_formatter' => 'known', 'register_template' => 'known_old')
|
375
|
+
def test_find_formatter(data)
|
220
376
|
$LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), 'scripts'))
|
221
377
|
assert_nothing_raised ConfigError do
|
222
|
-
TextFormatter::TEMPLATE_REGISTRY.lookup(
|
378
|
+
TextFormatter::TEMPLATE_REGISTRY.lookup(data)
|
223
379
|
end
|
380
|
+
$LOAD_PATH.shift
|
224
381
|
end
|
225
382
|
end
|
226
383
|
|