fluentd 0.14.11-x86-mingw32 → 0.14.12-x86-mingw32
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/.travis.yml +1 -5
- data/ChangeLog +54 -2
- data/example/in_dummy_blocks.conf +17 -0
- data/example/in_forward_tls.conf +14 -0
- data/example/in_forward_workers.conf +21 -0
- data/example/logevents.conf +25 -0
- data/example/out_forward_heartbeat_none.conf +16 -0
- data/example/out_forward_tls.conf +18 -0
- data/example/suppress_config_dump.conf +7 -0
- data/lib/fluent/agent.rb +3 -32
- data/lib/fluent/clock.rb +62 -0
- data/lib/fluent/command/fluentd.rb +12 -0
- data/lib/fluent/compat/input.rb +10 -1
- data/lib/fluent/compat/output.rb +40 -1
- data/lib/fluent/config/configure_proxy.rb +30 -7
- data/lib/fluent/config/section.rb +4 -0
- data/lib/fluent/config/types.rb +2 -2
- data/lib/fluent/configurable.rb +31 -5
- data/lib/fluent/engine.rb +61 -12
- data/lib/fluent/event_router.rb +6 -0
- data/lib/fluent/load.rb +0 -1
- data/lib/fluent/log.rb +118 -42
- data/lib/fluent/match.rb +37 -0
- data/lib/fluent/plugin.rb +25 -3
- data/lib/fluent/plugin/base.rb +4 -0
- data/lib/fluent/plugin/buf_file.rb +38 -14
- data/lib/fluent/plugin/buffer.rb +20 -20
- data/lib/fluent/plugin/buffer/file_chunk.rb +2 -2
- data/lib/fluent/plugin/compressable.rb +1 -0
- data/lib/fluent/plugin/filter_record_transformer.rb +3 -6
- data/lib/fluent/plugin/formatter_csv.rb +4 -1
- data/lib/fluent/plugin/formatter_hash.rb +5 -1
- data/lib/fluent/plugin/formatter_json.rb +10 -0
- data/lib/fluent/plugin/formatter_ltsv.rb +2 -1
- data/lib/fluent/plugin/in_dummy.rb +4 -0
- data/lib/fluent/plugin/in_exec.rb +4 -0
- data/lib/fluent/plugin/in_forward.rb +11 -3
- data/lib/fluent/plugin/in_gc_stat.rb +4 -0
- data/lib/fluent/plugin/in_http.rb +4 -0
- data/lib/fluent/plugin/in_monitor_agent.rb +29 -2
- data/lib/fluent/plugin/in_object_space.rb +4 -1
- data/lib/fluent/plugin/in_syslog.rb +4 -0
- data/lib/fluent/plugin/in_tail.rb +193 -116
- data/lib/fluent/plugin/in_tcp.rb +5 -1
- data/lib/fluent/plugin/in_udp.rb +4 -0
- data/lib/fluent/plugin/input.rb +4 -0
- data/lib/fluent/plugin/out_copy.rb +4 -0
- data/lib/fluent/plugin/out_exec.rb +4 -0
- data/lib/fluent/plugin/out_exec_filter.rb +4 -0
- data/lib/fluent/plugin/out_file.rb +70 -30
- data/lib/fluent/plugin/out_forward.rb +132 -28
- data/lib/fluent/plugin/out_null.rb +10 -0
- data/lib/fluent/plugin/out_relabel.rb +4 -0
- data/lib/fluent/plugin/out_roundrobin.rb +4 -0
- data/lib/fluent/plugin/out_secondary_file.rb +5 -0
- data/lib/fluent/plugin/out_stdout.rb +5 -0
- data/lib/fluent/plugin/output.rb +18 -9
- data/lib/fluent/plugin/storage_local.rb +25 -2
- data/lib/fluent/plugin_helper/cert_option.rb +159 -0
- data/lib/fluent/plugin_helper/child_process.rb +6 -6
- data/lib/fluent/plugin_helper/compat_parameters.rb +1 -1
- data/lib/fluent/plugin_helper/event_loop.rb +29 -4
- data/lib/fluent/plugin_helper/inject.rb +14 -1
- data/lib/fluent/plugin_helper/server.rb +275 -31
- data/lib/fluent/plugin_helper/socket.rb +144 -4
- data/lib/fluent/plugin_helper/socket_option.rb +2 -17
- data/lib/fluent/plugin_helper/storage.rb +7 -1
- data/lib/fluent/plugin_helper/thread.rb +16 -4
- data/lib/fluent/registry.rb +26 -9
- data/lib/fluent/root_agent.rb +7 -3
- data/lib/fluent/supervisor.rb +37 -15
- data/lib/fluent/system_config.rb +37 -10
- data/lib/fluent/test.rb +2 -0
- data/lib/fluent/test/driver/base.rb +24 -26
- data/lib/fluent/test/helpers.rb +21 -0
- data/lib/fluent/version.rb +1 -1
- data/test/command/test_fluentd.rb +274 -4
- data/test/config/test_configurable.rb +154 -0
- data/test/config/test_configure_proxy.rb +180 -1
- data/test/config/test_system_config.rb +10 -0
- data/test/config/test_types.rb +1 -0
- data/test/plugin/test_base.rb +4 -0
- data/test/plugin/test_buf_file.rb +241 -9
- data/test/plugin/test_buffer.rb +11 -11
- data/test/plugin/test_buffer_file_chunk.rb +6 -6
- data/test/plugin/test_compressable.rb +3 -0
- data/test/plugin/test_filter.rb +4 -0
- data/test/plugin/test_filter_record_transformer.rb +20 -0
- data/test/plugin/test_formatter_csv.rb +9 -0
- data/test/plugin/test_formatter_hash.rb +35 -0
- data/test/plugin/test_formatter_json.rb +8 -0
- data/test/plugin/test_formatter_ltsv.rb +7 -0
- data/test/plugin/test_in_dummy.rb +7 -3
- data/test/plugin/test_in_monitor_agent.rb +43 -5
- data/test/plugin/test_in_tail.rb +97 -4
- data/test/plugin/test_input.rb +4 -0
- data/test/plugin/test_out_file.rb +46 -7
- data/test/plugin/test_out_forward.rb +59 -7
- data/test/plugin/test_output.rb +10 -4
- data/test/plugin/test_output_as_buffered.rb +37 -25
- data/test/plugin/test_output_as_buffered_compress.rb +1 -1
- data/test/plugin/test_output_as_buffered_retries.rb +6 -6
- data/test/plugin/test_output_as_buffered_secondary.rb +91 -31
- data/test/plugin/test_storage_local.rb +40 -1
- data/test/plugin_helper/test_child_process.rb +29 -28
- data/test/plugin_helper/test_compat_parameters.rb +1 -1
- data/test/plugin_helper/test_inject.rb +27 -9
- data/test/plugin_helper/test_server.rb +822 -50
- data/test/plugin_helper/test_storage.rb +11 -0
- data/test/plugin_helper/test_timer.rb +1 -0
- data/test/test_clock.rb +164 -0
- data/test/test_log.rb +146 -15
- data/test/test_plugin.rb +251 -0
- data/test/test_supervisor.rb +65 -57
- data/test/test_test_drivers.rb +2 -2
- metadata +18 -7
- data/lib/fluent/process.rb +0 -504
- data/test/test_process.rb +0 -48
@@ -135,6 +135,17 @@ class StorageHelperTest < Test::Unit::TestCase
|
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
+
test 'raises config error if config argument has invalid characters' do
|
139
|
+
d = Dummy.new
|
140
|
+
assert_raise Fluent::ConfigError.new("Argument in <storage ARG> uses invalid characters: 'yaa y'") do
|
141
|
+
d.configure(config_element('root', '', {}, [config_element('storage', 'yaa y', {'@type' => 'local'})]))
|
142
|
+
end
|
143
|
+
d.configure(config_element())
|
144
|
+
assert_raise Fluent::ConfigError.new("Argument in <storage ARG> uses invalid characters: 'a,b'") do
|
145
|
+
d.storage_create(usage: 'a,b', type: 'local')
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
138
149
|
test 'can be configured without storage sections' do
|
139
150
|
d = Dummy.new
|
140
151
|
assert_nothing_raised do
|
@@ -122,6 +122,7 @@ class TimerTest < Test::Unit::TestCase
|
|
122
122
|
sleep(0.1) while waiting_timer
|
123
123
|
|
124
124
|
assert_equal(1, counter)
|
125
|
+
waiting(4){ sleep 0.1 while watchers.first.attached? }
|
125
126
|
assert_false(watchers.first.attached?)
|
126
127
|
watchers = d1._event_loop.watchers.reject {|w| w.is_a?(Fluent::PluginHelper::EventLoop::DefaultWatcher) }
|
127
128
|
assert_equal(0, watchers.size)
|
data/test/test_clock.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'fluent/clock'
|
3
|
+
|
4
|
+
require 'timecop'
|
5
|
+
|
6
|
+
class ClockTest < ::Test::Unit::TestCase
|
7
|
+
teardown do
|
8
|
+
Fluent::Clock.return # call it always not to affect other tests
|
9
|
+
end
|
10
|
+
|
11
|
+
sub_test_case 'without any pre-operation' do
|
12
|
+
test 'clock can provides incremental floating point number based on second' do
|
13
|
+
c1 = Fluent::Clock.now
|
14
|
+
assert_kind_of Float, c1
|
15
|
+
sleep 1.1
|
16
|
+
c2 = Fluent::Clock.now
|
17
|
+
assert{ c2 >= c1 + 1.0 && c2 < c1 + 9.0 } # if clock returns deci-second (fantastic!), c2 should be larger than c1 + 10
|
18
|
+
end
|
19
|
+
|
20
|
+
test 'clock value will proceed even if timecop freezes Time' do
|
21
|
+
Timecop.freeze(Time.now) do
|
22
|
+
c1 = Fluent::Clock.now
|
23
|
+
assert_kind_of Float, c1
|
24
|
+
sleep 1.1
|
25
|
+
c2 = Fluent::Clock.now
|
26
|
+
assert{ c2 >= c1 + 1.0 && c2 < c1 + 9.0 }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
sub_test_case 'using #freeze without any arguments' do
|
32
|
+
test 'Clock.freeze without arguments freezes clock with current clock value' do
|
33
|
+
c0 = Fluent::Clock.now
|
34
|
+
Fluent::Clock.freeze
|
35
|
+
c1 = Fluent::Clock.now
|
36
|
+
Fluent::Clock.return
|
37
|
+
c2 = Fluent::Clock.now
|
38
|
+
assert{ c0 <= c1 && c1 <= c2 }
|
39
|
+
end
|
40
|
+
|
41
|
+
test 'Clock.return raises an error if it is called in block' do
|
42
|
+
assert_raise RuntimeError.new("invalid return while running code in blocks") do
|
43
|
+
Fluent::Clock.freeze do
|
44
|
+
Fluent::Clock.return
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
sub_test_case 'using #freeze with clock value' do
|
51
|
+
test 'Clock.now always returns frozen time until #return called' do
|
52
|
+
c0 = Fluent::Clock.now
|
53
|
+
Fluent::Clock.freeze(c0)
|
54
|
+
assert_equal c0, Fluent::Clock.now
|
55
|
+
sleep 0.5
|
56
|
+
assert_equal c0, Fluent::Clock.now
|
57
|
+
sleep 0.6
|
58
|
+
assert_equal c0, Fluent::Clock.now
|
59
|
+
|
60
|
+
Fluent::Clock.return
|
61
|
+
c1 = Fluent::Clock.now
|
62
|
+
assert{ c1 >= c0 + 1.0 }
|
63
|
+
end
|
64
|
+
|
65
|
+
test 'Clock.now returns frozen time in the block argument of #freeze' do
|
66
|
+
c0 = Fluent::Clock.now
|
67
|
+
Fluent::Clock.freeze(c0) do
|
68
|
+
assert_equal c0, Fluent::Clock.now
|
69
|
+
sleep 0.5
|
70
|
+
assert_equal c0, Fluent::Clock.now
|
71
|
+
sleep 0.6
|
72
|
+
assert_equal c0, Fluent::Clock.now
|
73
|
+
end
|
74
|
+
c1 = Fluent::Clock.now
|
75
|
+
assert{ c1 >= c0 + 1.0 }
|
76
|
+
end
|
77
|
+
|
78
|
+
test 'Clock.now returns unfrozen value after jumping out from block by raising errors' do
|
79
|
+
c0 = Fluent::Clock.now
|
80
|
+
rescued_error = nil
|
81
|
+
begin
|
82
|
+
Fluent::Clock.freeze(c0) do
|
83
|
+
assert_equal c0, Fluent::Clock.now
|
84
|
+
sleep 0.5
|
85
|
+
assert_equal c0, Fluent::Clock.now
|
86
|
+
sleep 0.6
|
87
|
+
assert_equal c0, Fluent::Clock.now
|
88
|
+
raise "bye!"
|
89
|
+
end
|
90
|
+
rescue => e
|
91
|
+
rescued_error = e
|
92
|
+
end
|
93
|
+
assert rescued_error # ensure to rescue an error
|
94
|
+
c1 = Fluent::Clock.now
|
95
|
+
assert{ c1 >= c0 + 1.0 }
|
96
|
+
end
|
97
|
+
|
98
|
+
test 'Clock.return cancels all Clock.freeze effects by just once' do
|
99
|
+
c0 = Fluent::Clock.now
|
100
|
+
sleep 0.1
|
101
|
+
c1 = Fluent::Clock.now
|
102
|
+
sleep 0.1
|
103
|
+
c2 = Fluent::Clock.now
|
104
|
+
Fluent::Clock.freeze(c0)
|
105
|
+
sleep 0.1
|
106
|
+
assert_equal c0, Fluent::Clock.now
|
107
|
+
Fluent::Clock.freeze(c1)
|
108
|
+
sleep 0.1
|
109
|
+
assert_equal c1, Fluent::Clock.now
|
110
|
+
Fluent::Clock.freeze(c2)
|
111
|
+
sleep 0.1
|
112
|
+
assert_equal c2, Fluent::Clock.now
|
113
|
+
|
114
|
+
Fluent::Clock.return
|
115
|
+
assert{ Fluent::Clock.now > c2 }
|
116
|
+
end
|
117
|
+
|
118
|
+
test 'Clock.freeze allows nested blocks by itself' do
|
119
|
+
c0 = Fluent::Clock.now
|
120
|
+
sleep 0.1
|
121
|
+
c1 = Fluent::Clock.now
|
122
|
+
sleep 0.1
|
123
|
+
c2 = Fluent::Clock.now
|
124
|
+
Fluent::Clock.freeze(c0) do
|
125
|
+
sleep 0.1
|
126
|
+
assert_equal c0, Fluent::Clock.now
|
127
|
+
Fluent::Clock.freeze(c1) do
|
128
|
+
sleep 0.1
|
129
|
+
assert_equal c1, Fluent::Clock.now
|
130
|
+
Fluent::Clock.freeze(c2) do
|
131
|
+
sleep 0.1
|
132
|
+
assert_equal c2, Fluent::Clock.now
|
133
|
+
end
|
134
|
+
assert_equal c1, Fluent::Clock.now
|
135
|
+
end
|
136
|
+
assert_equal c0, Fluent::Clock.now
|
137
|
+
end
|
138
|
+
assert{ Fluent::Clock.now > c0 }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
sub_test_case 'using #freeze with Time argument' do
|
143
|
+
test 'Clock.freeze returns the clock value which should be produced when the time is at the specified time' do
|
144
|
+
c0 = Fluent::Clock.now
|
145
|
+
t0 = Time.now
|
146
|
+
t1 = t0 - 30
|
147
|
+
assert_kind_of Time, t1
|
148
|
+
t2 = t0 + 30
|
149
|
+
assert_kind_of Time, t2
|
150
|
+
|
151
|
+
# 31 is for error of floating point value
|
152
|
+
Fluent::Clock.freeze(t1) do
|
153
|
+
c1 = Fluent::Clock.now
|
154
|
+
assert{ c1 >= c0 - 31 && c1 <= c0 - 31 + 10 } # +10 is for threading schedule error
|
155
|
+
end
|
156
|
+
|
157
|
+
# 29 is for error of floating point value
|
158
|
+
Fluent::Clock.freeze(t2) do
|
159
|
+
c2 = Fluent::Clock.now
|
160
|
+
assert{ c2 >= c0 + 29 && c2 <= c0 + 29 + 10 } # +10 is for threading schedule error
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
data/test/test_log.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'helper'
|
2
|
+
require 'fluent/test/driver/input'
|
2
3
|
require 'fluent/engine'
|
3
4
|
require 'fluent/log'
|
4
5
|
require 'timecop'
|
@@ -374,12 +375,8 @@ class LogTest < Test::Unit::TestCase
|
|
374
375
|
log1 = Fluent::Log.new(logger)
|
375
376
|
log2 = log1.dup
|
376
377
|
log1.level = Fluent::Log::LEVEL_DEBUG
|
377
|
-
original_tag = log1.tag
|
378
|
-
log1.tag = "changed"
|
379
378
|
assert_equal(Fluent::Log::LEVEL_DEBUG, log1.level)
|
380
379
|
assert_equal(Fluent::Log::LEVEL_TRACE, log2.level)
|
381
|
-
assert_equal("changed", log1.tag)
|
382
|
-
assert_equal(original_tag, log2.tag)
|
383
380
|
end
|
384
381
|
|
385
382
|
def test_disable_events
|
@@ -388,6 +385,7 @@ class LogTest < Test::Unit::TestCase
|
|
388
385
|
logdev = @log_device
|
389
386
|
logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
|
390
387
|
log = Fluent::Log.new(logger)
|
388
|
+
log.enable_event(true)
|
391
389
|
engine = log.instance_variable_get("@engine")
|
392
390
|
mock(engine).push_log_event(anything, anything, anything).once
|
393
391
|
log.trace "trace log"
|
@@ -535,6 +533,146 @@ class PluginLoggerTest < Test::Unit::TestCase
|
|
535
533
|
assert_equal(true, @logger.enable_color?)
|
536
534
|
end
|
537
535
|
|
536
|
+
def test_log_type_in_default
|
537
|
+
mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_TRACE).once
|
538
|
+
mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_DEBUG).once
|
539
|
+
mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_INFO).once
|
540
|
+
mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_WARN).once
|
541
|
+
mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_ERROR).once
|
542
|
+
mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_FATAL).once
|
543
|
+
|
544
|
+
@logger.trace "trace log 1"
|
545
|
+
@logger.debug "debug log 2"
|
546
|
+
@logger.info "info log 3"
|
547
|
+
@logger.warn "warn log 4"
|
548
|
+
@logger.error "error log 5"
|
549
|
+
@logger.fatal "fatal log 6"
|
550
|
+
end
|
551
|
+
|
552
|
+
def test_log_types
|
553
|
+
mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_TRACE).once
|
554
|
+
mock(@logger).caller_line(:supervisor, Time.now, 1, Fluent::Log::LEVEL_DEBUG).once
|
555
|
+
mock(@logger).caller_line(:worker0, Time.now, 1, Fluent::Log::LEVEL_INFO).once
|
556
|
+
mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_WARN).once
|
557
|
+
mock(@logger).caller_line(:supervisor, Time.now, 1, Fluent::Log::LEVEL_ERROR).once
|
558
|
+
mock(@logger).caller_line(:worker0, Time.now, 1, Fluent::Log::LEVEL_FATAL).once
|
559
|
+
|
560
|
+
@logger.trace :default, "trace log 1"
|
561
|
+
@logger.debug :supervisor, "debug log 2"
|
562
|
+
@logger.info :worker0, "info log 3"
|
563
|
+
@logger.warn :default, "warn log 4"
|
564
|
+
@logger.error :supervisor, "error log 5"
|
565
|
+
@logger.fatal :worker0, "fatal log 6"
|
566
|
+
end
|
567
|
+
|
568
|
+
sub_test_case "supervisor process type" do
|
569
|
+
setup do
|
570
|
+
dl_opts = {}
|
571
|
+
dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
|
572
|
+
logdev = @log_device
|
573
|
+
logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
|
574
|
+
@logger = Fluent::Log.new(logger, process_type: :supervisor)
|
575
|
+
end
|
576
|
+
|
577
|
+
test 'default type logs are shown w/o worker id' do
|
578
|
+
@logger.info "yaaay"
|
579
|
+
@logger.info :default, "booo"
|
580
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
581
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: booo\n") }
|
582
|
+
end
|
583
|
+
|
584
|
+
test 'supervisor type logs are shown w/o worker id' do
|
585
|
+
@logger.info :supervisor, "yaaay"
|
586
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
587
|
+
end
|
588
|
+
|
589
|
+
test 'worker0 type logs are not shown' do
|
590
|
+
@logger.info :worker0, "yaaay"
|
591
|
+
assert{ !@log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
sub_test_case "worker0 process type" do
|
596
|
+
setup do
|
597
|
+
dl_opts = {}
|
598
|
+
dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
|
599
|
+
logdev = @log_device
|
600
|
+
logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
|
601
|
+
@logger = Fluent::Log.new(logger, process_type: :worker0, worker_id: 10)
|
602
|
+
end
|
603
|
+
|
604
|
+
test 'default type logs are shown w/ worker id' do
|
605
|
+
@logger.info "yaaay"
|
606
|
+
@logger.info :default, "booo"
|
607
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: #10 yaaay\n") }
|
608
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: #10 booo\n") }
|
609
|
+
end
|
610
|
+
|
611
|
+
test 'supervisor type logs are not shown' do
|
612
|
+
@logger.info :supervisor, "yaaay"
|
613
|
+
assert{ !@log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
614
|
+
end
|
615
|
+
|
616
|
+
test 'worker0 type logs are shown w/o worker id' do
|
617
|
+
@logger.info :worker0, "yaaay"
|
618
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
sub_test_case "workers process type" do
|
623
|
+
setup do
|
624
|
+
dl_opts = {}
|
625
|
+
dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
|
626
|
+
logdev = @log_device
|
627
|
+
logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
|
628
|
+
@logger = Fluent::Log.new(logger, process_type: :workers, worker_id: 7)
|
629
|
+
end
|
630
|
+
|
631
|
+
test 'default type logs are shown w/ worker id' do
|
632
|
+
@logger.info "yaaay"
|
633
|
+
@logger.info :default, "booo"
|
634
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: #7 yaaay\n") }
|
635
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: #7 booo\n") }
|
636
|
+
end
|
637
|
+
|
638
|
+
test 'supervisor type logs are not shown' do
|
639
|
+
@logger.info :supervisor, "yaaay"
|
640
|
+
assert{ !@log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
641
|
+
end
|
642
|
+
|
643
|
+
test 'worker0 type logs are not shown' do
|
644
|
+
@logger.info :worker0, "yaaay"
|
645
|
+
assert{ !@log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
649
|
+
sub_test_case "standalone process type" do
|
650
|
+
setup do
|
651
|
+
dl_opts = {}
|
652
|
+
dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
|
653
|
+
logdev = @log_device
|
654
|
+
logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
|
655
|
+
@logger = Fluent::Log.new(logger, process_type: :standalone, worker_id: 0)
|
656
|
+
end
|
657
|
+
|
658
|
+
test 'default type logs are shown w/o worker id' do
|
659
|
+
@logger.info "yaaay"
|
660
|
+
@logger.info :default, "booo"
|
661
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
662
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: booo\n") }
|
663
|
+
end
|
664
|
+
|
665
|
+
test 'supervisor type logs are shown w/o worker id' do
|
666
|
+
@logger.info :supervisor, "yaaay"
|
667
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
668
|
+
end
|
669
|
+
|
670
|
+
test 'worker0 type logs are shown w/o worker id' do
|
671
|
+
@logger.info :worker0, "yaaay"
|
672
|
+
assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
|
673
|
+
end
|
674
|
+
end
|
675
|
+
|
538
676
|
sub_test_case "delegators" do
|
539
677
|
def setup
|
540
678
|
super
|
@@ -556,12 +694,6 @@ class PluginLoggerTest < Test::Unit::TestCase
|
|
556
694
|
@log.disable_events(Thread.current)
|
557
695
|
end
|
558
696
|
|
559
|
-
def test_tag
|
560
|
-
assert_equal(@log.tag, @logger.tag)
|
561
|
-
@log.tag = "dummy"
|
562
|
-
assert_equal(@log.tag, @logger.tag)
|
563
|
-
end
|
564
|
-
|
565
697
|
def test_time_format
|
566
698
|
assert_equal(@log.time_format, @logger.time_format)
|
567
699
|
@log.time_format = "time_format"
|
@@ -609,12 +741,11 @@ class PluginLoggerTest < Test::Unit::TestCase
|
|
609
741
|
end
|
610
742
|
|
611
743
|
class PluginLoggerMixinTest < Test::Unit::TestCase
|
612
|
-
class DummyPlugin < Fluent::Plugin::
|
613
|
-
include Fluent::PluginHelper::EventEmitter
|
744
|
+
class DummyPlugin < Fluent::Plugin::Input
|
614
745
|
end
|
615
746
|
|
616
747
|
def create_driver(conf)
|
617
|
-
Fluent::Test::
|
748
|
+
Fluent::Test::Driver::Input.new(DummyPlugin).configure(conf)
|
618
749
|
end
|
619
750
|
|
620
751
|
def setup
|
@@ -635,9 +766,9 @@ class PluginLoggerMixinTest < Test::Unit::TestCase
|
|
635
766
|
end
|
636
767
|
|
637
768
|
def test_optional_header
|
638
|
-
d = create_driver(%[
|
769
|
+
d = create_driver(%[@id myplugin])
|
639
770
|
log = d.instance.log
|
640
|
-
assert_equal("[
|
771
|
+
assert_equal("[myplugin] ", log.optional_header)
|
641
772
|
assert_equal({}, log.optional_attrs)
|
642
773
|
end
|
643
774
|
|
data/test/test_plugin.rb
ADDED
@@ -0,0 +1,251 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
require 'fluent/plugin'
|
4
|
+
require 'fluent/plugin/input'
|
5
|
+
require 'fluent/plugin/filter'
|
6
|
+
require 'fluent/plugin/output'
|
7
|
+
require 'fluent/plugin/buffer'
|
8
|
+
require 'fluent/plugin/parser'
|
9
|
+
require 'fluent/plugin/formatter'
|
10
|
+
require 'fluent/plugin/storage'
|
11
|
+
|
12
|
+
class PluginTest < Test::Unit::TestCase
|
13
|
+
class Dummy1Input < Fluent::Plugin::Input
|
14
|
+
Fluent::Plugin.register_input('plugin_test_dummy1', self)
|
15
|
+
end
|
16
|
+
class Dummy2Input < Fluent::Plugin::Input
|
17
|
+
Fluent::Plugin.register_input('plugin_test_dummy2', self)
|
18
|
+
helpers :storage
|
19
|
+
config_section :storage do
|
20
|
+
config_set_default :@type, 'plugin_test_dummy1'
|
21
|
+
end
|
22
|
+
def multi_workers_ready?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
class DummyFilter < Fluent::Plugin::Filter
|
27
|
+
Fluent::Plugin.register_filter('plugin_test_dummy', self)
|
28
|
+
helpers :parser, :formatter
|
29
|
+
config_section :parse do
|
30
|
+
config_set_default :@type, 'plugin_test_dummy'
|
31
|
+
end
|
32
|
+
config_section :format do
|
33
|
+
config_set_default :@type, 'plugin_test_dummy'
|
34
|
+
end
|
35
|
+
def filter(tag, time, record)
|
36
|
+
record
|
37
|
+
end
|
38
|
+
end
|
39
|
+
class Dummy1Output < Fluent::Plugin::Output
|
40
|
+
Fluent::Plugin.register_output('plugin_test_dummy1', self)
|
41
|
+
def write(chunk)
|
42
|
+
# drop
|
43
|
+
end
|
44
|
+
end
|
45
|
+
class Dummy2Output < Fluent::Plugin::Output
|
46
|
+
Fluent::Plugin.register_output('plugin_test_dummy2', self)
|
47
|
+
config_section :buffer do
|
48
|
+
config_set_default :@type, 'plugin_test_dummy1'
|
49
|
+
end
|
50
|
+
def multi_workers_ready?
|
51
|
+
true
|
52
|
+
end
|
53
|
+
def write(chunk)
|
54
|
+
# drop
|
55
|
+
end
|
56
|
+
end
|
57
|
+
class Dummy1Buffer < Fluent::Plugin::Buffer
|
58
|
+
Fluent::Plugin.register_buffer('plugin_test_dummy1', self)
|
59
|
+
end
|
60
|
+
class Dummy2Buffer < Fluent::Plugin::Buffer
|
61
|
+
Fluent::Plugin.register_buffer('plugin_test_dummy2', self)
|
62
|
+
def multi_workers_ready?
|
63
|
+
false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
class DummyParser < Fluent::Plugin::Parser
|
67
|
+
Fluent::Plugin.register_parser('plugin_test_dummy', self)
|
68
|
+
end
|
69
|
+
class DummyFormatter < Fluent::Plugin::Formatter
|
70
|
+
Fluent::Plugin.register_formatter('plugin_test_dummy', self)
|
71
|
+
end
|
72
|
+
class Dummy1Storage < Fluent::Plugin::Storage
|
73
|
+
Fluent::Plugin.register_storage('plugin_test_dummy1', self)
|
74
|
+
end
|
75
|
+
class Dummy2Storage < Fluent::Plugin::Storage
|
76
|
+
Fluent::Plugin.register_storage('plugin_test_dummy2', self)
|
77
|
+
def multi_workers_ready?
|
78
|
+
false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
class DummyOwner < Fluent::Plugin::Base
|
82
|
+
include Fluent::PluginId
|
83
|
+
include Fluent::PluginLoggerMixin
|
84
|
+
end
|
85
|
+
class DummyEventRouter
|
86
|
+
def emit(tag, time, record); end
|
87
|
+
def emit_array(tag, array); end
|
88
|
+
def emit_stream(tag, es); end
|
89
|
+
def emit_error_event(tag, time, record, error); end
|
90
|
+
end
|
91
|
+
|
92
|
+
sub_test_case '#new_* methods' do
|
93
|
+
data(
|
94
|
+
input1: ['plugin_test_dummy1', Dummy1Input, :new_input],
|
95
|
+
input2: ['plugin_test_dummy2', Dummy2Input, :new_input],
|
96
|
+
filter: ['plugin_test_dummy', DummyFilter, :new_filter],
|
97
|
+
output1: ['plugin_test_dummy1', Dummy1Output, :new_output],
|
98
|
+
output2: ['plugin_test_dummy2', Dummy2Output, :new_output],
|
99
|
+
)
|
100
|
+
test 'retruns plugin instances of registered plugin classes' do |(type, klass, m)|
|
101
|
+
instance = Fluent::Plugin.__send__(m, type)
|
102
|
+
assert_kind_of klass, instance
|
103
|
+
end
|
104
|
+
|
105
|
+
data(
|
106
|
+
buffer1: ['plugin_test_dummy1', Dummy1Buffer, :new_buffer],
|
107
|
+
buffer2: ['plugin_test_dummy2', Dummy2Buffer, :new_buffer],
|
108
|
+
parser: ['plugin_test_dummy', DummyParser, :new_parser],
|
109
|
+
formatter: ['plugin_test_dummy', DummyFormatter, :new_formatter],
|
110
|
+
storage1: ['plugin_test_dummy1', Dummy1Storage, :new_storage],
|
111
|
+
storage2: ['plugin_test_dummy2', Dummy2Storage, :new_storage],
|
112
|
+
)
|
113
|
+
test 'returns plugin instances of registered owned plugin classes' do |(type, klass, m)|
|
114
|
+
owner = DummyOwner.new
|
115
|
+
instance = Fluent::Plugin.__send__(m, type, parent: owner)
|
116
|
+
assert_kind_of klass, instance
|
117
|
+
end
|
118
|
+
|
119
|
+
data(
|
120
|
+
input1: ['plugin_test_dummy1', Dummy1Input, :new_input, nil],
|
121
|
+
input2: ['plugin_test_dummy2', Dummy2Input, :new_input, nil],
|
122
|
+
filter: ['plugin_test_dummy', DummyFilter, :new_filter, nil],
|
123
|
+
output1: ['plugin_test_dummy1', Dummy1Output, :new_output, nil],
|
124
|
+
output2: ['plugin_test_dummy2', Dummy2Output, :new_output, nil],
|
125
|
+
buffer1: ['plugin_test_dummy1', Dummy1Buffer, :new_buffer, {parent: DummyOwner.new}],
|
126
|
+
buffer2: ['plugin_test_dummy2', Dummy2Buffer, :new_buffer, {parent: DummyOwner.new}],
|
127
|
+
parser: ['plugin_test_dummy', DummyParser, :new_parser, {parent: DummyOwner.new}],
|
128
|
+
formatter: ['plugin_test_dummy', DummyFormatter, :new_formatter, {parent: DummyOwner.new}],
|
129
|
+
storage1: ['plugin_test_dummy1', Dummy1Storage, :new_storage, {parent: DummyOwner.new}],
|
130
|
+
storage2: ['plugin_test_dummy2', Dummy2Storage, :new_storage, {parent: DummyOwner.new}],
|
131
|
+
)
|
132
|
+
test 'returns plugin instances which are extended by FeatureAvailabilityChecker module' do |(type, _, m, kwargs)|
|
133
|
+
instance = if kwargs
|
134
|
+
Fluent::Plugin.__send__(m, type, **kwargs)
|
135
|
+
else
|
136
|
+
Fluent::Plugin.__send__(m, type)
|
137
|
+
end
|
138
|
+
assert_kind_of Fluent::Plugin::FeatureAvailabilityChecker, instance
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
sub_test_case 'with default system configuration' do
|
143
|
+
data(
|
144
|
+
input1: ['plugin_test_dummy1', Dummy1Input, :new_input, nil],
|
145
|
+
input2: ['plugin_test_dummy2', Dummy2Input, :new_input, nil],
|
146
|
+
filter: ['plugin_test_dummy', DummyFilter, :new_filter, nil],
|
147
|
+
output1: ['plugin_test_dummy1', Dummy1Output, :new_output, nil],
|
148
|
+
output2: ['plugin_test_dummy2', Dummy2Output, :new_output, nil],
|
149
|
+
buffer1: ['plugin_test_dummy1', Dummy1Buffer, :new_buffer, {parent: DummyOwner.new}],
|
150
|
+
buffer2: ['plugin_test_dummy2', Dummy2Buffer, :new_buffer, {parent: DummyOwner.new}],
|
151
|
+
parser: ['plugin_test_dummy', DummyParser, :new_parser, {parent: DummyOwner.new}],
|
152
|
+
formatter: ['plugin_test_dummy', DummyFormatter, :new_formatter, {parent: DummyOwner.new}],
|
153
|
+
storage1: ['plugin_test_dummy1', Dummy1Storage, :new_storage, {parent: DummyOwner.new}],
|
154
|
+
storage2: ['plugin_test_dummy2', Dummy2Storage, :new_storage, {parent: DummyOwner.new}],
|
155
|
+
)
|
156
|
+
test '#configure does not raise anything' do |(type, _, m, kwargs)|
|
157
|
+
instance = if kwargs
|
158
|
+
Fluent::Plugin.__send__(m, type, **kwargs)
|
159
|
+
else
|
160
|
+
Fluent::Plugin.__send__(m, type)
|
161
|
+
end
|
162
|
+
if instance.respond_to?(:context_router=)
|
163
|
+
instance.context_router = DummyEventRouter.new
|
164
|
+
end
|
165
|
+
assert_nothing_raised do
|
166
|
+
instance.configure(config_element())
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
sub_test_case 'with single worker configuration' do
|
172
|
+
data(
|
173
|
+
input1: ['plugin_test_dummy1', Dummy1Input, :new_input, nil],
|
174
|
+
input2: ['plugin_test_dummy2', Dummy2Input, :new_input, nil],
|
175
|
+
filter: ['plugin_test_dummy', DummyFilter, :new_filter, nil],
|
176
|
+
output1: ['plugin_test_dummy1', Dummy1Output, :new_output, nil],
|
177
|
+
output2: ['plugin_test_dummy2', Dummy2Output, :new_output, nil],
|
178
|
+
buffer1: ['plugin_test_dummy1', Dummy1Buffer, :new_buffer, {parent: DummyOwner.new}],
|
179
|
+
buffer2: ['plugin_test_dummy2', Dummy2Buffer, :new_buffer, {parent: DummyOwner.new}],
|
180
|
+
parser: ['plugin_test_dummy', DummyParser, :new_parser, {parent: DummyOwner.new}],
|
181
|
+
formatter: ['plugin_test_dummy', DummyFormatter, :new_formatter, {parent: DummyOwner.new}],
|
182
|
+
storage1: ['plugin_test_dummy1', Dummy1Storage, :new_storage, {parent: DummyOwner.new}],
|
183
|
+
storage2: ['plugin_test_dummy2', Dummy2Storage, :new_storage, {parent: DummyOwner.new}],
|
184
|
+
)
|
185
|
+
test '#configure does not raise anything' do |(type, _, m, kwargs)|
|
186
|
+
instance = if kwargs
|
187
|
+
Fluent::Plugin.__send__(m, type, **kwargs)
|
188
|
+
else
|
189
|
+
Fluent::Plugin.__send__(m, type)
|
190
|
+
end
|
191
|
+
if instance.respond_to?(:context_router=)
|
192
|
+
instance.context_router = DummyEventRouter.new
|
193
|
+
end
|
194
|
+
assert_nothing_raised do
|
195
|
+
instance.system_config_override('workers' => 1)
|
196
|
+
instance.configure(config_element())
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
sub_test_case 'with multi workers configuration' do
|
202
|
+
data(
|
203
|
+
input1: ['plugin_test_dummy1', Dummy1Input, :new_input],
|
204
|
+
output1: ['plugin_test_dummy1', Dummy1Output, :new_output],
|
205
|
+
)
|
206
|
+
test '#configure raise configuration error if plugins are not ready for multi workers' do |(type, klass, new_method)|
|
207
|
+
conf = config_element()
|
208
|
+
instance = Fluent::Plugin.__send__(new_method, type)
|
209
|
+
if instance.respond_to?(:context_router=)
|
210
|
+
instance.context_router = DummyEventRouter.new
|
211
|
+
end
|
212
|
+
assert_raise Fluent::ConfigError.new("Plugin '#{type}' does not support multi workers configuration (#{klass})") do
|
213
|
+
instance.system_config_override('workers' => 3)
|
214
|
+
instance.configure(conf)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
data(
|
219
|
+
input2: ['plugin_test_dummy2', Dummy2Input, :new_input], # with Dummy1Storage
|
220
|
+
filter: ['plugin_test_dummy', DummyFilter, :new_filter], # with DummyParser and DummyFormatter
|
221
|
+
output2: ['plugin_test_dummy2', Dummy2Output, :new_output], # with Dummy1Buffer
|
222
|
+
)
|
223
|
+
test '#configure does not raise any errors if plugins and its owned plugins are ready for multi workers' do |(type, _klass, new_method)|
|
224
|
+
conf = config_element()
|
225
|
+
instance = Fluent::Plugin.__send__(new_method, type)
|
226
|
+
if instance.respond_to?(:context_router=)
|
227
|
+
instance.context_router = DummyEventRouter.new
|
228
|
+
end
|
229
|
+
assert_nothing_raised do
|
230
|
+
instance.system_config_override('workers' => 3)
|
231
|
+
instance.configure(conf)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
data(
|
236
|
+
input2: ['plugin_test_dummy2', Dummy2Input, :new_input, 'storage', 'plugin_test_dummy2', Dummy2Storage],
|
237
|
+
output2: ['plugin_test_dummy2', Dummy2Output, :new_output, 'buffer', 'plugin_test_dummy2', Dummy2Buffer],
|
238
|
+
)
|
239
|
+
test '#configure raise configuration error if configured owned plugins are not ready for multi workers' do |(type, _klass, new_method, subsection, subsection_type, problematic)|
|
240
|
+
conf = config_element('root', '', {}, [config_element(subsection, '', {'@type' => subsection_type})])
|
241
|
+
instance = Fluent::Plugin.__send__(new_method, type)
|
242
|
+
if instance.respond_to?(:context_router=)
|
243
|
+
instance.context_router = DummyEventRouter.new
|
244
|
+
end
|
245
|
+
assert_raise Fluent::ConfigError.new("Plugin '#{subsection_type}' does not support multi workers configuration (#{problematic})") do
|
246
|
+
instance.system_config_override('workers' => 3)
|
247
|
+
instance.configure(conf)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|