fluentd 0.14.4 → 0.14.5
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 +18 -0
- data/example/in_forward.conf +3 -0
- data/example/in_forward_client.conf +37 -0
- data/example/in_forward_shared_key.conf +15 -0
- data/example/in_forward_users.conf +24 -0
- data/example/out_forward.conf +13 -13
- data/example/out_forward_client.conf +109 -0
- data/example/out_forward_shared_key.conf +36 -0
- data/example/out_forward_users.conf +65 -0
- data/example/{out_buffered_null.conf → out_null.conf} +10 -6
- data/example/secondary_file.conf +41 -0
- data/lib/fluent/agent.rb +3 -1
- data/lib/fluent/plugin/buffer.rb +5 -1
- data/lib/fluent/plugin/in_forward.rb +300 -50
- data/lib/fluent/plugin/in_tail.rb +41 -85
- data/lib/fluent/plugin/multi_output.rb +4 -0
- data/lib/fluent/plugin/out_forward.rb +326 -209
- data/lib/fluent/plugin/out_null.rb +37 -0
- data/lib/fluent/plugin/out_secondary_file.rb +128 -0
- data/lib/fluent/plugin/out_stdout.rb +38 -2
- data/lib/fluent/plugin/output.rb +13 -5
- data/lib/fluent/root_agent.rb +1 -1
- data/lib/fluent/test/startup_shutdown.rb +33 -0
- data/lib/fluent/version.rb +1 -1
- data/test/plugin/test_in_forward.rb +906 -441
- data/test/plugin/test_in_monitor_agent.rb +4 -0
- data/test/plugin/test_in_tail.rb +681 -663
- data/test/plugin/test_out_forward.rb +150 -208
- data/test/plugin/test_out_null.rb +85 -9
- data/test/plugin/test_out_secondary_file.rb +432 -0
- data/test/plugin/test_out_stdout.rb +143 -45
- data/test/test_root_agent.rb +42 -0
- metadata +14 -9
- data/lib/fluent/plugin/out_buffered_null.rb +0 -59
- data/lib/fluent/plugin/out_buffered_stdout.rb +0 -70
- data/test/plugin/test_out_buffered_null.rb +0 -79
- data/test/plugin/test_out_buffered_stdout.rb +0 -122
@@ -1,14 +1,17 @@
|
|
1
1
|
require_relative '../helper'
|
2
2
|
require 'fluent/test'
|
3
|
+
require 'fluent/test/startup_shutdown'
|
3
4
|
require 'fluent/plugin/out_forward'
|
4
5
|
|
5
6
|
class ForwardOutputTest < Test::Unit::TestCase
|
7
|
+
extend Fluent::Test::StartupShutdown
|
8
|
+
|
6
9
|
def setup
|
7
10
|
Fluent::Test.setup
|
8
11
|
end
|
9
12
|
|
10
13
|
TARGET_HOST = '127.0.0.1'
|
11
|
-
TARGET_PORT =
|
14
|
+
TARGET_PORT = unused_port
|
12
15
|
CONFIG = %[
|
13
16
|
send_timeout 51
|
14
17
|
heartbeat_type udp
|
@@ -25,7 +28,7 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
25
28
|
]
|
26
29
|
|
27
30
|
def create_driver(conf=CONFIG)
|
28
|
-
Fluent::Test::BufferedOutputTestDriver.new(Fluent::ForwardOutput) {
|
31
|
+
d = Fluent::Test::BufferedOutputTestDriver.new(Fluent::ForwardOutput) {
|
29
32
|
attr_reader :responses, :exceptions
|
30
33
|
|
31
34
|
def initialize
|
@@ -34,18 +37,32 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
34
37
|
@exceptions = []
|
35
38
|
end
|
36
39
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
def configure(conf)
|
41
|
+
super
|
42
|
+
m = Module.new do
|
43
|
+
def send_data(tag, chunk)
|
44
|
+
@sender.responses << super
|
45
|
+
rescue => e
|
46
|
+
@sender.exceptions << e
|
47
|
+
raise e
|
48
|
+
end
|
49
|
+
end
|
50
|
+
@nodes.each do |node|
|
51
|
+
node.singleton_class.prepend(m)
|
52
|
+
end
|
43
53
|
end
|
44
54
|
}.configure(conf)
|
55
|
+
router = Object.new
|
56
|
+
def router.method_missing(name, *args, **kw_args, &block)
|
57
|
+
Engine.root_agent.event_router.__send__(name, *args, **kw_args, &block)
|
58
|
+
end
|
59
|
+
d.instance.router = router
|
60
|
+
d
|
45
61
|
end
|
46
62
|
|
47
63
|
def test_configure
|
48
64
|
d = create_driver(%[
|
65
|
+
self_hostname localhost
|
49
66
|
<server>
|
50
67
|
name test
|
51
68
|
host #{TARGET_HOST}
|
@@ -59,7 +76,7 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
59
76
|
node = nodes.first
|
60
77
|
assert_equal "test", node.name
|
61
78
|
assert_equal '127.0.0.1', node.host
|
62
|
-
assert_equal
|
79
|
+
assert_equal TARGET_PORT, node.port
|
63
80
|
end
|
64
81
|
|
65
82
|
def test_configure_udp_heartbeat
|
@@ -79,11 +96,9 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
79
96
|
|
80
97
|
d = create_driver(CONFIG + "\nheartbeat_type tcp\ndns_round_robin true")
|
81
98
|
assert_equal true, d.instance.dns_round_robin
|
82
|
-
assert_equal true, d.instance.nodes.first.conf.dns_round_robin
|
83
99
|
|
84
100
|
d = create_driver(CONFIG + "\nheartbeat_type none\ndns_round_robin true")
|
85
101
|
assert_equal true, d.instance.dns_round_robin
|
86
|
-
assert_equal true, d.instance.nodes.first.conf.dns_round_robin
|
87
102
|
end
|
88
103
|
|
89
104
|
def test_configure_no_server
|
@@ -118,70 +133,6 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
118
133
|
assert_equal 2, d.instance.ack_response_timeout
|
119
134
|
end
|
120
135
|
|
121
|
-
def test_sending_contains_with_ack
|
122
|
-
target_input_driver = create_target_input_driver(true)
|
123
|
-
|
124
|
-
d = create_driver(CONFIG + %[
|
125
|
-
ack_response_timeout 1s
|
126
|
-
])
|
127
|
-
|
128
|
-
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
129
|
-
|
130
|
-
records = [
|
131
|
-
{"a" => 1},
|
132
|
-
{"a" => 2}
|
133
|
-
]
|
134
|
-
d.register_run_post_condition do
|
135
|
-
d.instance.responses.length == 1
|
136
|
-
end
|
137
|
-
|
138
|
-
target_input_driver.run do
|
139
|
-
d.run do
|
140
|
-
records.each do |record|
|
141
|
-
d.emit record, time
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
emits = target_input_driver.emits
|
147
|
-
assert_equal ['test', time, records[0]], emits[0]
|
148
|
-
assert_equal ['test', time, records[1]], emits[1]
|
149
|
-
|
150
|
-
assert_equal target_input_driver.instance.received_options[0]['size'], 2
|
151
|
-
end
|
152
|
-
|
153
|
-
def test_sending_contains_without_ack
|
154
|
-
target_input_driver = create_target_input_driver(true)
|
155
|
-
|
156
|
-
d = create_driver(CONFIG + %[
|
157
|
-
ack_response_timeout 1s
|
158
|
-
])
|
159
|
-
|
160
|
-
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
161
|
-
|
162
|
-
records = [
|
163
|
-
{"a" => 1},
|
164
|
-
{"a" => 2}
|
165
|
-
]
|
166
|
-
d.register_run_post_condition do
|
167
|
-
d.instance.responses.length == 1
|
168
|
-
end
|
169
|
-
|
170
|
-
target_input_driver.run do
|
171
|
-
d.run do
|
172
|
-
records.each do |record|
|
173
|
-
d.emit record, time
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
emits = target_input_driver.emits
|
179
|
-
assert_equal ['test', time, records[0]], emits[0]
|
180
|
-
assert_equal ['test', time, records[1]], emits[1]
|
181
|
-
|
182
|
-
assert_equal target_input_driver.instance.received_options[0]['size'], 2
|
183
|
-
end
|
184
|
-
|
185
136
|
def test_send_with_time_as_integer
|
186
137
|
target_input_driver = create_target_input_driver
|
187
138
|
|
@@ -252,7 +203,7 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
252
203
|
end
|
253
204
|
|
254
205
|
def test_send_to_a_node_supporting_responses
|
255
|
-
target_input_driver = create_target_input_driver(true)
|
206
|
+
target_input_driver = create_target_input_driver(response_stub: true)
|
256
207
|
|
257
208
|
d = create_driver(CONFIG + %[flush_interval 1s])
|
258
209
|
|
@@ -314,7 +265,7 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
314
265
|
end
|
315
266
|
|
316
267
|
def test_require_a_node_supporting_responses_to_respond_with_ack
|
317
|
-
target_input_driver = create_target_input_driver
|
268
|
+
target_input_driver = create_target_input_driver
|
318
269
|
|
319
270
|
d = create_driver(CONFIG + %[
|
320
271
|
flush_interval 1s
|
@@ -350,8 +301,7 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
350
301
|
end
|
351
302
|
|
352
303
|
def test_require_a_node_not_supporting_responses_to_respond_with_ack
|
353
|
-
|
354
|
-
target_input_driver = create_target_input_driver
|
304
|
+
target_input_driver = create_target_input_driver(response_stub: ->(_option) { nil }, disconnect: true)
|
355
305
|
|
356
306
|
d = create_driver(CONFIG + %[
|
357
307
|
flush_interval 1s
|
@@ -394,7 +344,7 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
394
344
|
# bdf1f4f104c00a791aa94dc20087fe2011e1fd83
|
395
345
|
def test_require_a_node_not_supporting_responses_2_to_respond_with_ack
|
396
346
|
# in_forward, that doesn't support ack feature, and disconnect immediately
|
397
|
-
target_input_driver = create_target_input_driver(
|
347
|
+
target_input_driver = create_target_input_driver(response_stub: ->(_option) { nil }, disconnect: true)
|
398
348
|
|
399
349
|
d = create_driver(CONFIG + %[
|
400
350
|
flush_interval 1s
|
@@ -413,7 +363,7 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
413
363
|
end
|
414
364
|
d.run_timeout = 2
|
415
365
|
|
416
|
-
assert_raise Fluent::
|
366
|
+
assert_raise Fluent::ForwardOutputACKTimeoutError do
|
417
367
|
target_input_driver.run do
|
418
368
|
d.run do
|
419
369
|
records.each do |record|
|
@@ -434,85 +384,136 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
434
384
|
assert_equal false, node.available # node is regarded as unavailable when unexpected EOF
|
435
385
|
end
|
436
386
|
|
437
|
-
def
|
438
|
-
|
387
|
+
def test_authentication_with_shared_key
|
388
|
+
input_conf = TARGET_CONFIG + %[
|
389
|
+
<security>
|
390
|
+
self_hostname in.localhost
|
391
|
+
shared_key fluentd-sharedkey
|
392
|
+
<client>
|
393
|
+
host 127.0.0.1
|
394
|
+
</client>
|
395
|
+
</security>
|
396
|
+
]
|
397
|
+
target_input_driver = create_target_input_driver(conf: input_conf)
|
398
|
+
|
399
|
+
output_conf = %[
|
400
|
+
send_timeout 51
|
401
|
+
<security>
|
402
|
+
self_hostname localhost
|
403
|
+
shared_key fluentd-sharedkey
|
404
|
+
</security>
|
405
|
+
<server>
|
406
|
+
name test
|
407
|
+
host #{TARGET_HOST}
|
408
|
+
port #{TARGET_PORT}
|
409
|
+
shared_key fluentd-sharedkey
|
410
|
+
</server>
|
411
|
+
]
|
412
|
+
d = create_driver(output_conf)
|
439
413
|
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
option = on_message.call(msg, chunk_size, source)
|
453
|
-
@received_options << option
|
454
|
-
option
|
455
|
-
}
|
456
|
-
@source = nil
|
457
|
-
@peeraddr = nil
|
414
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
415
|
+
records = [
|
416
|
+
{"a" => 1},
|
417
|
+
{"a" => 2}
|
418
|
+
]
|
419
|
+
|
420
|
+
target_input_driver.run do
|
421
|
+
sleep 0.1 until target_input_driver.instance.instance_eval{ @thread } && target_input_driver.instance.instance_eval{ @thread }.status
|
422
|
+
|
423
|
+
d.run do
|
424
|
+
records.each do |record|
|
425
|
+
d.emit(record, time)
|
458
426
|
end
|
459
427
|
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
@sock.close_write
|
465
|
-
@sock.close
|
466
|
-
end
|
467
|
-
else
|
468
|
-
def write(data)
|
469
|
-
# do nothing
|
470
|
-
end
|
428
|
+
# run_post_condition of Fluent::Test::*Driver are buggy:
|
429
|
+
t = Time.now
|
430
|
+
while Time.now < t + 15 && target_input_driver.emits.size < 2
|
431
|
+
sleep 0.1
|
471
432
|
end
|
433
|
+
end
|
434
|
+
end
|
472
435
|
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
436
|
+
emits = target_input_driver.emits
|
437
|
+
assert{ emits != [] }
|
438
|
+
assert_equal(['test', time, records[0]], emits[0])
|
439
|
+
assert_equal(['test', time, records[1]], emits[1])
|
440
|
+
end
|
441
|
+
|
442
|
+
def test_authentication_with_user_auth
|
443
|
+
input_conf = TARGET_CONFIG + %[
|
444
|
+
<security>
|
445
|
+
self_hostname in.localhost
|
446
|
+
shared_key fluentd-sharedkey
|
447
|
+
user_auth true
|
448
|
+
<user>
|
449
|
+
username fluentd
|
450
|
+
password fluentd
|
451
|
+
</user>
|
452
|
+
<client>
|
453
|
+
host 127.0.0.1
|
454
|
+
</client>
|
455
|
+
</security>
|
456
|
+
]
|
457
|
+
target_input_driver = create_target_input_driver(conf: input_conf)
|
458
|
+
|
459
|
+
output_conf = %[
|
460
|
+
send_timeout 51
|
461
|
+
<security>
|
462
|
+
self_hostname localhost
|
463
|
+
shared_key fluentd-sharedkey
|
464
|
+
</security>
|
465
|
+
<server>
|
466
|
+
name test
|
467
|
+
host #{TARGET_HOST}
|
468
|
+
port #{TARGET_PORT}
|
469
|
+
shared_key fluentd-sharedkey
|
470
|
+
username fluentd
|
471
|
+
password fluentd
|
472
|
+
</server>
|
473
|
+
]
|
474
|
+
d = create_driver(output_conf)
|
475
|
+
|
476
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
477
|
+
records = [
|
478
|
+
{"a" => 1},
|
479
|
+
{"a" => 2}
|
480
|
+
]
|
481
|
+
|
482
|
+
target_input_driver.run do
|
483
|
+
sleep 0.1 until target_input_driver.instance.instance_eval{ @thread } && target_input_driver.instance.instance_eval{ @thread }.status
|
484
|
+
|
485
|
+
d.run do
|
486
|
+
records.each do |record|
|
487
|
+
d.emit(record, time)
|
478
488
|
end
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
begin
|
485
|
-
handler = handler_class.new(sock, @log, method(:on_message))
|
486
|
-
loop do
|
487
|
-
raw_data = sock.recv(1024)
|
488
|
-
handler.on_read(raw_data)
|
489
|
-
# chunk_counter is reset to zero only after all the data have been received and successfully deserialized.
|
490
|
-
break if handler.chunk_counter == 0
|
491
|
-
break if sock.closed?
|
492
|
-
end
|
493
|
-
if disconnect
|
494
|
-
handler.close
|
495
|
-
sock = nil
|
496
|
-
end
|
497
|
-
sleep # wait for connection to be closed by client
|
498
|
-
ensure
|
499
|
-
if sock && !sock.closed?
|
500
|
-
sock.close_write
|
501
|
-
sock.close
|
502
|
-
end
|
503
|
-
@received_options = handler.received_options
|
504
|
-
end
|
505
|
-
end
|
489
|
+
|
490
|
+
# run_post_condition of Fluent::Test::*Driver are buggy:
|
491
|
+
t = Time.now
|
492
|
+
while Time.now < t + 15 && target_input_driver.emits.size < 2
|
493
|
+
sleep 0.1
|
506
494
|
end
|
507
495
|
end
|
496
|
+
end
|
508
497
|
|
509
|
-
|
498
|
+
emits = target_input_driver.emits
|
499
|
+
assert{ emits != [] }
|
500
|
+
assert_equal(['test', time, records[0]], emits[0])
|
501
|
+
assert_equal(['test', time, records[1]], emits[1])
|
502
|
+
end
|
503
|
+
|
504
|
+
def create_target_input_driver(response_stub: nil, disconnect: false, conf: TARGET_CONFIG)
|
505
|
+
require 'fluent/plugin/in_forward'
|
510
506
|
|
511
|
-
|
512
|
-
|
513
|
-
|
507
|
+
# TODO: Support actual TCP heartbeat test
|
508
|
+
Fluent::Test::InputTestDriver.new(Fluent::ForwardInput) {
|
509
|
+
if response_stub.nil?
|
510
|
+
# do nothing because in_forward responds for ack option in default
|
511
|
+
else
|
512
|
+
define_method(:response) do |options|
|
513
|
+
return response_stub.(options)
|
514
|
+
end
|
514
515
|
end
|
515
|
-
}.configure(conf)
|
516
|
+
}.configure(conf)
|
516
517
|
end
|
517
518
|
|
518
519
|
def test_heartbeat_type_none
|
@@ -528,63 +529,4 @@ class ForwardOutputTest < Test::Unit::TestCase
|
|
528
529
|
node.tick
|
529
530
|
assert_equal node.available, true
|
530
531
|
end
|
531
|
-
|
532
|
-
# To suppress calling `ForwardInput#start` in `DummyEngineDriver`,
|
533
|
-
# `DummyEnigneDriver` should avoid calling CallSuperMixin.prepend at `Fluent::Compat::Input#initialize`.
|
534
|
-
module SuppressCallSuperMixin
|
535
|
-
def start
|
536
|
-
_start
|
537
|
-
end
|
538
|
-
|
539
|
-
def before_shutdown
|
540
|
-
# nothing
|
541
|
-
end
|
542
|
-
|
543
|
-
def shutdown
|
544
|
-
_shutdown
|
545
|
-
end
|
546
|
-
end
|
547
|
-
|
548
|
-
class DummyEngineDriver < Fluent::Test::TestDriver
|
549
|
-
def initialize(klass, &block)
|
550
|
-
super(klass, &block)
|
551
|
-
@instance.class.prepend(SuppressCallSuperMixin)
|
552
|
-
@engine = DummyEngineClass.new
|
553
|
-
end
|
554
|
-
|
555
|
-
def inject_router
|
556
|
-
@instance.router = @engine
|
557
|
-
self
|
558
|
-
end
|
559
|
-
|
560
|
-
def run(&block)
|
561
|
-
super(&block)
|
562
|
-
end
|
563
|
-
|
564
|
-
def emits
|
565
|
-
all = []
|
566
|
-
@engine.emit_streams.each {|tag,events|
|
567
|
-
events.each {|time,record|
|
568
|
-
all << [tag, time, record]
|
569
|
-
}
|
570
|
-
}
|
571
|
-
all
|
572
|
-
end
|
573
|
-
|
574
|
-
class DummyEngineClass
|
575
|
-
attr_reader :emit_streams
|
576
|
-
|
577
|
-
def initialize
|
578
|
-
@emit_streams ||= []
|
579
|
-
end
|
580
|
-
|
581
|
-
def clear!
|
582
|
-
@emit_streams = []
|
583
|
-
end
|
584
|
-
|
585
|
-
def emit_stream(tag, es)
|
586
|
-
@emit_streams << [tag, es.to_a]
|
587
|
-
end
|
588
|
-
end
|
589
|
-
end
|
590
532
|
end
|