fluentd 0.14.0 → 0.14.1
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/example/copy_roundrobin.conf +39 -0
- data/example/filter_stdout.conf +5 -5
- data/example/in_forward.conf +2 -2
- data/example/in_http.conf +2 -2
- data/example/in_syslog.conf +2 -2
- data/example/in_tail.conf +2 -2
- data/example/in_tcp.conf +2 -2
- data/example/in_udp.conf +2 -2
- data/example/out_buffered_null.conf +32 -0
- data/example/out_copy.conf +4 -4
- data/example/out_file.conf +2 -2
- data/example/out_forward.conf +2 -2
- data/example/v0_12_filter.conf +8 -8
- data/fluentd.gemspec +1 -1
- data/lib/fluent/command/fluentd.rb +6 -1
- data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
- data/lib/fluent/compat/input.rb +1 -0
- data/lib/fluent/compat/output.rb +1 -0
- data/lib/fluent/compat/record_filter_mixin.rb +34 -0
- data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
- data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
- data/lib/fluent/compat/type_converter.rb +90 -0
- data/lib/fluent/config/configure_proxy.rb +24 -4
- data/lib/fluent/config/dsl.rb +18 -1
- data/lib/fluent/config/v1_parser.rb +3 -2
- data/lib/fluent/configurable.rb +1 -1
- data/lib/fluent/event.rb +37 -9
- data/lib/fluent/mixin.rb +12 -286
- data/lib/fluent/plugin/buffer.rb +2 -2
- data/lib/fluent/plugin/in_dummy.rb +5 -1
- data/lib/fluent/plugin/in_gc_stat.rb +7 -37
- data/lib/fluent/plugin/in_http.rb +2 -0
- data/lib/fluent/plugin/{in_stream.rb → in_unix.rb} +0 -0
- data/lib/fluent/plugin/out_buffered_stdout.rb +60 -0
- data/lib/fluent/plugin/out_copy.rb +8 -51
- data/lib/fluent/plugin/out_null.rb +5 -5
- data/lib/fluent/plugin/out_relabel.rb +5 -5
- data/lib/fluent/plugin/out_roundrobin.rb +13 -40
- data/lib/fluent/plugin/output.rb +9 -0
- data/lib/fluent/plugin_helper.rb +2 -0
- data/lib/fluent/plugin_helper/formatter.rb +138 -0
- data/lib/fluent/plugin_helper/inject.rb +112 -0
- data/lib/fluent/plugin_helper/parser.rb +138 -0
- data/lib/fluent/plugin_helper/storage.rb +64 -50
- data/lib/fluent/process.rb +6 -1
- data/lib/fluent/registry.rb +1 -1
- data/lib/fluent/supervisor.rb +20 -2
- data/lib/fluent/test.rb +30 -5
- data/lib/fluent/test/base.rb +2 -66
- data/lib/fluent/test/driver/base.rb +3 -0
- data/lib/fluent/test/driver/base_owned.rb +106 -0
- data/lib/fluent/test/driver/formatter.rb +30 -0
- data/lib/fluent/test/driver/multi_output.rb +52 -0
- data/lib/fluent/test/driver/owner.rb +32 -0
- data/lib/fluent/test/driver/parser.rb +30 -0
- data/lib/fluent/test/helpers.rb +54 -0
- data/lib/fluent/test/log.rb +73 -0
- data/lib/fluent/time.rb +71 -0
- data/lib/fluent/version.rb +1 -1
- data/test/compat/test_parser.rb +82 -0
- data/test/config/test_configure_proxy.rb +15 -0
- data/test/config/test_dsl.rb +180 -2
- data/test/helper.rb +2 -24
- data/test/plugin/test_in_gc_stat.rb +6 -6
- data/test/plugin/test_in_http.rb +49 -32
- data/test/plugin/{test_in_stream.rb → test_in_unix.rb} +1 -1
- data/test/plugin/test_out_buffered_stdout.rb +108 -0
- data/test/plugin/test_out_copy.rb +88 -127
- data/test/plugin/test_out_null.rb +29 -0
- data/test/plugin/test_out_relabel.rb +28 -0
- data/test/plugin/test_out_roundrobin.rb +35 -29
- data/test/plugin/test_out_stdout.rb +4 -4
- data/test/plugin/test_output_as_buffered.rb +51 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +13 -0
- data/test/plugin/test_parser_apache.rb +38 -0
- data/test/plugin/test_parser_apache2.rb +38 -0
- data/test/plugin/test_parser_apache_error.rb +40 -0
- data/test/plugin/test_parser_base.rb +32 -0
- data/test/plugin/test_parser_csv.rb +94 -0
- data/test/plugin/test_parser_json.rb +107 -0
- data/test/plugin/test_parser_labeled_tsv.rb +129 -0
- data/test/plugin/test_parser_multiline.rb +100 -0
- data/test/plugin/test_parser_nginx.rb +42 -0
- data/test/plugin/test_parser_none.rb +53 -0
- data/test/plugin/test_parser_regexp.rb +110 -0
- data/test/plugin/test_parser_syslog.rb +66 -0
- data/test/plugin/test_parser_time.rb +46 -0
- data/test/plugin/test_parser_tsv.rb +125 -0
- data/test/plugin_helper/test_child_process.rb +11 -2
- data/test/plugin_helper/test_formatter.rb +212 -0
- data/test/plugin_helper/test_inject.rb +388 -0
- data/test/plugin_helper/test_parser.rb +223 -0
- data/test/plugin_helper/test_retry_state.rb +40 -40
- data/test/plugin_helper/test_storage.rb +77 -10
- data/test/scripts/fluent/plugin/out_test.rb +22 -17
- data/test/scripts/fluent/plugin/out_test2.rb +80 -0
- data/test/test_event.rb +57 -0
- data/test/test_formatter.rb +0 -178
- data/test/test_output.rb +2 -152
- data/test/test_root_agent.rb +3 -2
- data/test/test_supervisor.rb +93 -26
- data/test/test_time_formatter.rb +186 -0
- metadata +69 -7
- data/test/test_parser.rb +0 -1087
data/test/helper.rb
CHANGED
@@ -42,6 +42,7 @@ require 'fileutils'
|
|
42
42
|
require 'fluent/config/element'
|
43
43
|
require 'fluent/log'
|
44
44
|
require 'fluent/test'
|
45
|
+
require 'fluent/test/helpers'
|
45
46
|
require 'fluent/plugin/base'
|
46
47
|
require 'fluent/log'
|
47
48
|
require 'fluent/plugin_id'
|
@@ -67,30 +68,7 @@ unless defined?(Test::Unit::AssertionFailedError)
|
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
70
|
-
|
71
|
-
Fluent::Config::Element.new(name, argument, params, elements)
|
72
|
-
end
|
73
|
-
|
74
|
-
def event_time(str=nil)
|
75
|
-
if str
|
76
|
-
Fluent::EventTime.parse(str)
|
77
|
-
else
|
78
|
-
Fluent::EventTime.now
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def msgpack(type)
|
83
|
-
case type
|
84
|
-
when :factory
|
85
|
-
Fluent::MessagePackFactory.factory
|
86
|
-
when :packer
|
87
|
-
Fluent::MessagePackFactory.packer
|
88
|
-
when :unpacker
|
89
|
-
Fluent::MessagePackFactory.unpacker
|
90
|
-
else
|
91
|
-
raise ArgumentError, "unknown msgpack object type '#{type}'"
|
92
|
-
end
|
93
|
-
end
|
71
|
+
include Fluent::Test::Helpers
|
94
72
|
|
95
73
|
def unused_port(num = 1)
|
96
74
|
ports = []
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require_relative '../helper'
|
2
|
-
require 'fluent/test'
|
2
|
+
require 'fluent/test/driver/input'
|
3
3
|
require 'fluent/plugin/in_gc_stat'
|
4
4
|
|
5
5
|
class GCStatInputTest < Test::Unit::TestCase
|
@@ -13,7 +13,7 @@ class GCStatInputTest < Test::Unit::TestCase
|
|
13
13
|
]
|
14
14
|
|
15
15
|
def create_driver(conf=CONFIG)
|
16
|
-
Fluent::Test::
|
16
|
+
Fluent::Test::Driver::Input.new(Fluent::Plugin::GCStatInput).configure(conf)
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_configure
|
@@ -31,9 +31,9 @@ class GCStatInputTest < Test::Unit::TestCase
|
|
31
31
|
sleep 2
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
assert(
|
36
|
-
assert_equal(stat,
|
37
|
-
assert(
|
34
|
+
events = d.events
|
35
|
+
assert(events.length > 0)
|
36
|
+
assert_equal(stat, events[0][2])
|
37
|
+
assert(events[0][1].is_a?(Fluent::EventTime))
|
38
38
|
end
|
39
39
|
end
|
data/test/plugin/test_in_http.rb
CHANGED
@@ -147,6 +147,39 @@ class HttpInputTest < Test::Unit::TestCase
|
|
147
147
|
|
148
148
|
end
|
149
149
|
|
150
|
+
def test_json_with_add_remote_addr_given_x_forwarded_for
|
151
|
+
d = create_driver(CONFIG + "add_remote_addr true")
|
152
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
153
|
+
|
154
|
+
d.expect_emit "tag1", time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>1}
|
155
|
+
d.expect_emit "tag2", time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>1}
|
156
|
+
|
157
|
+
d.run do
|
158
|
+
d.expected_emits.each {|tag,_time,record|
|
159
|
+
res = post("/#{tag}", {"json"=>record.to_json, "time"=>_time.to_s}, {"X-Forwarded-For"=>"129.78.138.66, 127.0.0.1"})
|
160
|
+
assert_equal "200", res.code
|
161
|
+
}
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_multi_json_with_add_remote_addr_given_x_forwarded_for
|
167
|
+
d = create_driver(CONFIG + "add_remote_addr true")
|
168
|
+
|
169
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
170
|
+
events = [{"a"=>1},{"a"=>2}]
|
171
|
+
tag = "tag1"
|
172
|
+
|
173
|
+
d.expect_emit "tag1", time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>1}
|
174
|
+
d.expect_emit "tag1", time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>2}
|
175
|
+
|
176
|
+
d.run do
|
177
|
+
res = post("/#{tag}", {"json"=>events.to_json, "time"=>time.to_s}, {"X-Forwarded-For"=>"129.78.138.66, 127.0.0.1"})
|
178
|
+
assert_equal "200", res.code
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
150
183
|
def test_multi_json_with_add_http_headers
|
151
184
|
d = create_driver(CONFIG + "add_http_headers true")
|
152
185
|
|
@@ -302,50 +335,34 @@ class HttpInputTest < Test::Unit::TestCase
|
|
302
335
|
d = create_driver(CONFIG + "cors_allow_origins [\"http://foo.com\"]")
|
303
336
|
assert_equal ["http://foo.com"], d.instance.cors_allow_origins
|
304
337
|
|
305
|
-
|
306
|
-
acao = nil
|
338
|
+
time = Fluent::EventTime.new(Time.parse("2011-01-02 13:14:15 UTC").to_i)
|
307
339
|
|
308
|
-
|
309
|
-
|
310
|
-
Net::HTTP.start("127.0.0.1", PORT) do |http|
|
311
|
-
req = Net::HTTP::Post.new("/foo/bar", {"Origin" => "http://foo.com", "Content-Type" => "application/octet-stream"})
|
312
|
-
res = http.request(req)
|
340
|
+
d.expect_emit "tag1", time, {"a"=>1}
|
341
|
+
d.expect_emit "tag2", time, {"a"=>1}
|
313
342
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
343
|
+
d.run do
|
344
|
+
d.expected_emits.each {|tag,_time,record|
|
345
|
+
res = post("/#{tag}", {"json"=>record.to_json, "time"=>_time.to_s}, {"Origin"=>"http://foo.com"})
|
346
|
+
assert_equal "200", res.code
|
347
|
+
assert_equal "http://foo.com", res["Access-Control-Allow-Origin"]
|
348
|
+
}
|
320
349
|
end
|
321
|
-
|
322
|
-
assert_equal true, test_in_http_cros_allowed
|
323
|
-
assert_equal "http://foo.com", acao
|
324
350
|
end
|
325
351
|
|
326
352
|
def test_cors_disallowed
|
327
353
|
d = create_driver(CONFIG + "cors_allow_origins [\"http://foo.com\"]")
|
328
354
|
assert_equal ["http://foo.com"], d.instance.cors_allow_origins
|
329
355
|
|
330
|
-
|
331
|
-
response_code = nil
|
356
|
+
time = Fluent::EventTime.new(Time.parse("2011-01-02 13:14:15 UTC").to_i)
|
332
357
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
res = http.request(req)
|
358
|
+
d.expected_emits_length = 0
|
359
|
+
d.run do
|
360
|
+
res = post("/tag1", {"json"=>{"a"=>1}.to_json, "time"=>time.to_s}, {"Origin"=>"http://bar.com"})
|
361
|
+
assert_equal "403", res.code
|
338
362
|
|
339
|
-
|
340
|
-
|
341
|
-
end
|
342
|
-
test_in_http_cros_disallowed = true
|
343
|
-
rescue
|
344
|
-
test_in_http_cros_disallowed = false
|
363
|
+
res = post("/tag2", {"json"=>{"a"=>1}.to_json, "time"=>time.to_s}, {"Origin"=>"http://bar.com"})
|
364
|
+
assert_equal "403", res.code
|
345
365
|
end
|
346
|
-
|
347
|
-
assert_equal true, test_in_http_cros_disallowed
|
348
|
-
assert_equal "403", response_code
|
349
366
|
end
|
350
367
|
|
351
368
|
$test_in_http_connection_object_ids = []
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require 'fluent/test/driver/output'
|
3
|
+
require 'fluent/plugin/out_buffered_stdout'
|
4
|
+
|
5
|
+
class BufferedStdoutOutputTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
Fluent::Test.setup
|
8
|
+
end
|
9
|
+
|
10
|
+
CONFIG = %[
|
11
|
+
]
|
12
|
+
|
13
|
+
def create_driver(conf = CONFIG)
|
14
|
+
Fluent::Test::Driver::Output.new(Fluent::Plugin::BufferedStdoutOutput).configure(conf)
|
15
|
+
end
|
16
|
+
|
17
|
+
test 'default configure' do
|
18
|
+
d = create_driver
|
19
|
+
assert_equal 'json', d.instance.output_type
|
20
|
+
assert_equal 10 * 1024, d.instance.buffer_config.chunk_limit_size
|
21
|
+
assert d.instance.buffer_config.flush_at_shutdown
|
22
|
+
assert_equal ['tag'], d.instance.buffer_config.chunk_keys
|
23
|
+
assert d.instance.chunk_key_tag
|
24
|
+
assert !d.instance.chunk_key_time
|
25
|
+
assert_equal [], d.instance.chunk_keys
|
26
|
+
end
|
27
|
+
|
28
|
+
test 'configure with output_type' do
|
29
|
+
d = create_driver(CONFIG + "\noutput_type json")
|
30
|
+
assert_equal 'json', d.instance.output_type
|
31
|
+
|
32
|
+
d = create_driver(CONFIG + "\noutput_type hash")
|
33
|
+
assert_equal 'hash', d.instance.output_type
|
34
|
+
|
35
|
+
assert_raise(Fluent::ConfigError) do
|
36
|
+
d = create_driver(CONFIG + "\noutput_type foo")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
sub_test_case "emit json" do
|
41
|
+
data('oj' => 'oj', 'yajl' => 'yajl')
|
42
|
+
test '#write(synchronous)' do |data|
|
43
|
+
d = create_driver(CONFIG + "\noutput_type json\njson_parser #{data}")
|
44
|
+
time = event_time()
|
45
|
+
|
46
|
+
out = capture_log do
|
47
|
+
d.run(default_tag: 'test', flush: true) do
|
48
|
+
d.feed(time, {'test' => 'test'})
|
49
|
+
end
|
50
|
+
end
|
51
|
+
assert_equal "#{Time.at(time).localtime} test: {\"test\":\"test\"}\n", out
|
52
|
+
end
|
53
|
+
|
54
|
+
data('oj' => 'oj', 'yajl' => 'yajl')
|
55
|
+
test '#try_write(asynchronous)' do |data|
|
56
|
+
d = create_driver(CONFIG + "\noutput_type json\njson_parser #{data}")
|
57
|
+
time = event_time()
|
58
|
+
d.instance.delayed = true
|
59
|
+
|
60
|
+
out = capture_log do
|
61
|
+
d.run(default_tag: 'test', flush: true, shutdown: false) do
|
62
|
+
d.feed(time, {'test' => 'test'})
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
assert_equal "#{Time.at(time).localtime} test: {\"test\":\"test\"}\n", out
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
sub_test_case 'emit hash' do
|
71
|
+
test '#write(synchronous)' do
|
72
|
+
d = create_driver(CONFIG + "\noutput_type hash")
|
73
|
+
time = event_time()
|
74
|
+
|
75
|
+
out = capture_log do
|
76
|
+
d.run(default_tag: 'test', flush: true) do
|
77
|
+
d.feed(time, {'test' => 'test'})
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
assert_equal "#{Time.at(time).localtime} test: {\"test\"=>\"test\"}\n", out
|
82
|
+
end
|
83
|
+
|
84
|
+
test '#try_write(asynchronous)' do
|
85
|
+
d = create_driver(CONFIG + "\noutput_type hash")
|
86
|
+
time = event_time()
|
87
|
+
d.instance.delayed = true
|
88
|
+
|
89
|
+
out = capture_log do
|
90
|
+
d.run(default_tag: 'test', flush: true, shutdown: false) do
|
91
|
+
d.feed(time, {'test' => 'test'})
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
assert_equal "#{Time.at(time).localtime} test: {\"test\"=>\"test\"}\n", out
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Capture the log output of the block given
|
100
|
+
def capture_log(&block)
|
101
|
+
tmp = $log
|
102
|
+
$log = StringIO.new
|
103
|
+
yield
|
104
|
+
return $log.string
|
105
|
+
ensure
|
106
|
+
$log = tmp
|
107
|
+
end
|
108
|
+
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require_relative '../helper'
|
2
|
-
require 'fluent/test'
|
2
|
+
require 'fluent/test/driver/multi_output'
|
3
3
|
require 'fluent/plugin/out_copy'
|
4
|
+
require 'fluent/event'
|
4
5
|
|
5
6
|
class CopyOutputTest < Test::Unit::TestCase
|
6
7
|
class << self
|
7
8
|
def startup
|
8
9
|
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'scripts'))
|
9
10
|
require 'fluent/plugin/out_test'
|
11
|
+
require 'fluent/plugin/out_test2'
|
10
12
|
end
|
11
13
|
|
12
14
|
def shutdown
|
@@ -20,21 +22,21 @@ class CopyOutputTest < Test::Unit::TestCase
|
|
20
22
|
|
21
23
|
CONFIG = %[
|
22
24
|
<store>
|
23
|
-
type test
|
25
|
+
@type test
|
24
26
|
name c0
|
25
27
|
</store>
|
26
28
|
<store>
|
27
|
-
type
|
29
|
+
@type test2
|
28
30
|
name c1
|
29
31
|
</store>
|
30
32
|
<store>
|
31
|
-
type test
|
33
|
+
@type test
|
32
34
|
name c2
|
33
35
|
</store>
|
34
36
|
]
|
35
37
|
|
36
38
|
def create_driver(conf = CONFIG)
|
37
|
-
Fluent::Test::
|
39
|
+
Fluent::Test::Driver::MultiOutput.new(Fluent::Plugin::CopyOutput).configure(conf)
|
38
40
|
end
|
39
41
|
|
40
42
|
def test_configure
|
@@ -42,158 +44,117 @@ class CopyOutputTest < Test::Unit::TestCase
|
|
42
44
|
|
43
45
|
outputs = d.instance.outputs
|
44
46
|
assert_equal 3, outputs.size
|
45
|
-
assert_equal Fluent::TestOutput, outputs[0].class
|
46
|
-
assert_equal Fluent::
|
47
|
-
assert_equal Fluent::TestOutput, outputs[2].class
|
47
|
+
assert_equal Fluent::Plugin::TestOutput, outputs[0].class
|
48
|
+
assert_equal Fluent::Plugin::Test2Output, outputs[1].class
|
49
|
+
assert_equal Fluent::Plugin::TestOutput, outputs[2].class
|
48
50
|
assert_equal "c0", outputs[0].name
|
49
51
|
assert_equal "c1", outputs[1].name
|
50
52
|
assert_equal "c2", outputs[2].name
|
51
53
|
end
|
52
54
|
|
53
|
-
def
|
55
|
+
def test_feed_events
|
54
56
|
d = create_driver
|
55
57
|
|
56
|
-
|
57
|
-
d.
|
58
|
-
d.
|
58
|
+
assert !d.instance.outputs[0].has_router?
|
59
|
+
assert_not_nil d.instance.outputs[1].router
|
60
|
+
assert !d.instance.outputs[2].has_router?
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
}
|
62
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
63
|
+
d.run(default_tag: 'test') do
|
64
|
+
d.feed(time, {"a" => 1})
|
65
|
+
d.feed(time, {"a" => 2})
|
66
|
+
end
|
66
67
|
|
67
68
|
d.instance.outputs.each {|o|
|
68
|
-
|
69
|
+
assert_equal [ [time, {"a"=>1}], [time, {"a"=>2}] ], o.events
|
69
70
|
}
|
70
71
|
end
|
71
72
|
|
72
|
-
def
|
73
|
-
d =
|
74
|
-
|
75
|
-
outputs = %w(p1 p2).map do |pname|
|
76
|
-
p = Fluent::Plugin.new_output('test')
|
77
|
-
p.configure('name' => pname)
|
78
|
-
p.define_singleton_method(:emit) do |tag, es, chain|
|
79
|
-
es.each do |time, record|
|
80
|
-
super(tag, [[time, record]], chain)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
p
|
84
|
-
end
|
85
|
-
|
86
|
-
d.instance.instance_eval { @outputs = outputs }
|
73
|
+
def test_msgpack_unpacker_cache_bug_for_msgpack_event_stream
|
74
|
+
d = create_driver
|
87
75
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
packer.pack([time, {"a" => 1}])
|
92
|
-
packer.pack([time, {"a" => 2}])
|
93
|
-
Fluent::MessagePackEventStream.new(packer.to_s)
|
94
|
-
else
|
95
|
-
events = "#{[time, {"a" => 1}].to_msgpack}#{[time, {"a" => 2}].to_msgpack}"
|
96
|
-
Fluent::MessagePackEventStream.new(events)
|
97
|
-
end
|
76
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
77
|
+
source = Fluent::ArrayEventStream.new([ [time, {"a" => 1}], [time, {"a" => 2}] ])
|
78
|
+
es = Fluent::MessagePackEventStream.new(source.to_msgpack_stream)
|
98
79
|
|
99
|
-
d.
|
80
|
+
d.run(default_tag: 'test') do
|
81
|
+
d.feed(es)
|
82
|
+
end
|
100
83
|
|
101
84
|
d.instance.outputs.each { |o|
|
102
|
-
assert_equal [
|
103
|
-
[time, {"a"=>1}],
|
104
|
-
[time, {"a"=>2}],
|
105
|
-
], o.events
|
85
|
+
assert_equal [ [time, {"a"=>1}], [time, {"a"=>2}] ], o.events
|
106
86
|
}
|
107
87
|
end
|
108
88
|
|
109
|
-
def create_event_test_driver(
|
110
|
-
|
111
|
-
deep_copy #{
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
]
|
125
|
-
|
126
|
-
output1 = Fluent::Plugin.new_output('test')
|
127
|
-
output1.configure('name' => 'output1')
|
128
|
-
output1.define_singleton_method(:emit) do |tag, es, chain|
|
89
|
+
def create_event_test_driver(does_deep_copy = false)
|
90
|
+
config = %[
|
91
|
+
deep_copy #{does_deep_copy}
|
92
|
+
<store>
|
93
|
+
@type test
|
94
|
+
name output1
|
95
|
+
</store>
|
96
|
+
<store>
|
97
|
+
@type test
|
98
|
+
name output2
|
99
|
+
</store>
|
100
|
+
]
|
101
|
+
|
102
|
+
d = Fluent::Test::Driver::MultiOutput.new(Fluent::Plugin::CopyOutput).configure(config)
|
103
|
+
d.instance.outputs[0].define_singleton_method(:process) do |tag, es|
|
129
104
|
es.each do |time, record|
|
130
105
|
record['foo'] = 'bar'
|
131
|
-
super(tag, [[time, record]], chain)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
output2 = Fluent::Plugin.new_output('test')
|
136
|
-
output2.configure('name' => 'output2')
|
137
|
-
output2.define_singleton_method(:emit) do |tag, es, chain|
|
138
|
-
es.each do |time, record|
|
139
|
-
super(tag, [[time, record]], chain)
|
140
106
|
end
|
107
|
+
super(tag, es)
|
141
108
|
end
|
142
|
-
|
143
|
-
outputs = [output1, output2]
|
144
|
-
|
145
|
-
d = Fluent::Test::OutputTestDriver.new(Fluent::CopyOutput)
|
146
|
-
d = d.configure(deep_copy_config)
|
147
|
-
d.instance.instance_eval { @outputs = outputs }
|
148
109
|
d
|
149
110
|
end
|
150
111
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
112
|
+
time = event_time("2013-05-26 06:37:22 UTC")
|
113
|
+
mes0 = Fluent::MultiEventStream.new
|
114
|
+
mes0.add(time, {"a" => 1})
|
115
|
+
mes0.add(time, {"b" => 1})
|
116
|
+
mes1 = Fluent::MultiEventStream.new
|
117
|
+
mes1.add(time, {"a" => 1})
|
118
|
+
mes1.add(time, {"b" => 1})
|
119
|
+
|
120
|
+
data(
|
121
|
+
"OneEventStream without deep_copy" => [false, Fluent::OneEventStream.new(time, {"a" => 1})],
|
122
|
+
"OneEventStream with deep_copy" => [true, Fluent::OneEventStream.new(time, {"a" => 1})],
|
123
|
+
"ArrayEventStream without deep_copy" => [false, Fluent::ArrayEventStream.new([ [time, {"a" => 1}], [time, {"b" => 2}] ])],
|
124
|
+
"ArrayEventStream with deep_copy" => [true, Fluent::ArrayEventStream.new([ [time, {"a" => 1}], [time, {"b" => 2}] ])],
|
125
|
+
"MultiEventStream without deep_copy" => [false, mes0],
|
126
|
+
"MultiEventStream with deep_copy" => [true, mes1],
|
127
|
+
)
|
128
|
+
def test_deep_copy_controls_shallow_or_deep_copied(data)
|
129
|
+
does_deep_copy, es = data
|
130
|
+
|
131
|
+
d = create_event_test_driver(does_deep_copy)
|
132
|
+
|
133
|
+
d.run(default_tag: 'test') do
|
134
|
+
d.feed(es)
|
135
|
+
end
|
162
136
|
|
163
|
-
|
164
|
-
es = Fluent::OneEventStream.new(time, {"a" => 1})
|
165
|
-
d.instance.emit('test', es, Fluent::NullOutputChain.instance)
|
137
|
+
events = d.instance.outputs.map(&:events)
|
166
138
|
|
167
|
-
|
168
|
-
[
|
169
|
-
|
170
|
-
|
171
|
-
end
|
139
|
+
if does_deep_copy
|
140
|
+
events[0].each_with_index do |entry0, i|
|
141
|
+
record0 = entry0.last
|
142
|
+
record1 = events[1][i].last
|
172
143
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
d = create_event_test_driver(true)
|
188
|
-
es = Fluent::MultiEventStream.new
|
189
|
-
es.add(time, {"a" => 1})
|
190
|
-
es.add(time, {"b" => 2})
|
191
|
-
d.instance.emit('test', es, Fluent::NullOutputChain.instance)
|
192
|
-
|
193
|
-
assert_equal [
|
194
|
-
[[time, {"a"=>1, "foo"=>"bar"}], [time, {"b"=>2, "foo"=>"bar"}]],
|
195
|
-
[[time, {"a"=>1}], [time, {"b"=>2}]]
|
196
|
-
], d.instance.outputs.map{ |o| o.events }
|
144
|
+
assert{ record0.object_id != record1.object_id }
|
145
|
+
assert_equal "bar", record0["foo"]
|
146
|
+
assert !record1.has_key?("foo")
|
147
|
+
end
|
148
|
+
else
|
149
|
+
events[0].each_with_index do |entry0, i|
|
150
|
+
record0 = entry0.last
|
151
|
+
record1 = events[1][i].last
|
152
|
+
|
153
|
+
assert{ record0.object_id == record1.object_id }
|
154
|
+
assert_equal "bar", record0["foo"]
|
155
|
+
assert_equal "bar", record1["foo"]
|
156
|
+
end
|
157
|
+
end
|
197
158
|
end
|
198
159
|
end
|
199
160
|
|