fluentd 0.14.3 → 0.14.4

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.

Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +59 -1131
  3. data/Rakefile +15 -0
  4. data/appveyor.yml +2 -2
  5. data/example/multi_filters.conf +61 -0
  6. data/fluentd.gemspec +19 -16
  7. data/lib/fluent/agent.rb +3 -0
  8. data/lib/fluent/command/debug.rb +4 -4
  9. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +2 -0
  10. data/lib/fluent/compat/output.rb +5 -2
  11. data/lib/fluent/config/configure_proxy.rb +26 -5
  12. data/lib/fluent/config/error.rb +3 -0
  13. data/lib/fluent/config/section.rb +15 -0
  14. data/lib/fluent/event_router.rb +77 -4
  15. data/lib/fluent/plugin/base.rb +12 -3
  16. data/lib/fluent/plugin/filter.rb +48 -6
  17. data/lib/fluent/plugin/filter_record_transformer.rb +3 -1
  18. data/lib/fluent/plugin/filter_stdout.rb +0 -4
  19. data/lib/fluent/plugin/in_debug_agent.rb +5 -5
  20. data/lib/fluent/plugin/in_dummy.rb +9 -1
  21. data/lib/fluent/plugin/in_forward.rb +32 -14
  22. data/lib/fluent/plugin/in_monitor_agent.rb +31 -77
  23. data/lib/fluent/plugin/in_tail.rb +37 -9
  24. data/lib/fluent/plugin/out_forward.rb +2 -13
  25. data/lib/fluent/plugin/output.rb +16 -1
  26. data/lib/fluent/plugin/storage_local.rb +16 -0
  27. data/lib/fluent/plugin_helper/timer.rb +6 -1
  28. data/lib/fluent/root_agent.rb +3 -0
  29. data/lib/fluent/supervisor.rb +62 -9
  30. data/lib/fluent/test/base.rb +3 -0
  31. data/lib/fluent/test/driver/base.rb +5 -0
  32. data/lib/fluent/test/formatter_test.rb +2 -0
  33. data/lib/fluent/test/parser_test.rb +2 -0
  34. data/lib/fluent/version.rb +1 -1
  35. data/lib/fluent/winsvc.rb +1 -2
  36. data/test/compat/test_calls_super.rb +2 -0
  37. data/test/config/test_configurable.rb +88 -0
  38. data/test/config/test_types.rb +7 -3
  39. data/test/plugin/test_filter.rb +121 -23
  40. data/test/plugin/test_filter_record_transformer.rb +22 -6
  41. data/test/plugin/test_in_debug_agent.rb +2 -2
  42. data/test/plugin/test_in_forward.rb +54 -6
  43. data/test/plugin/test_in_monitor_agent.rb +329 -0
  44. data/test/plugin/test_in_tail.rb +73 -0
  45. data/test/plugin/test_out_forward.rb +1 -0
  46. data/test/plugin/test_output.rb +53 -0
  47. data/test/plugin/test_output_as_buffered.rb +13 -0
  48. data/test/plugin/test_output_as_buffered_overflow.rb +3 -0
  49. data/test/plugin/test_output_as_buffered_retries.rb +11 -0
  50. data/test/plugin/test_output_as_buffered_secondary.rb +12 -0
  51. data/test/plugin/test_output_as_standard.rb +12 -0
  52. data/test/plugin_helper/test_compat_parameters.rb +2 -0
  53. data/test/plugin_helper/test_timer.rb +31 -0
  54. data/test/test_event_router.rb +87 -0
  55. data/test/test_filter.rb +48 -6
  56. data/test/test_log.rb +5 -2
  57. data/test/test_output.rb +41 -1
  58. data/test/test_plugin_classes.rb +17 -9
  59. data/test/test_root_agent.rb +146 -0
  60. metadata +51 -67
@@ -145,6 +145,7 @@ class BufferedOutputTest < Test::Unit::TestCase
145
145
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_keys,@hash)]))
146
146
  logs = @i.log.out.logs.dup
147
147
  @i.start
148
+ @i.after_start
148
149
  assert{ logs.select{|log| log.include?('[warn]') }.size == 0 }
149
150
  end
150
151
 
@@ -154,6 +155,7 @@ class BufferedOutputTest < Test::Unit::TestCase
154
155
  logs = @i.log.out.logs.dup
155
156
 
156
157
  @i.start # this calls `log.reset`... capturing logs about configure must be done before this line
158
+ @i.after_start
157
159
  assert_equal ['key1', 'key2', 'key3', 'key4'], @i.chunk_keys
158
160
 
159
161
  assert{ logs.select{|log| log.include?('[warn]: many chunk keys specified, and it may cause too many chunks on your system.') }.size == 1 }
@@ -164,6 +166,7 @@ class BufferedOutputTest < Test::Unit::TestCase
164
166
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_keys,@hash)]))
165
167
  logs = @i.log.out.logs.dup
166
168
  @i.start # this calls `log.reset`... capturing logs about configure must be done before this line
169
+ @i.after_start
167
170
  assert{ logs.select{|log| log.include?('[warn]: many chunk keys specified, and it may cause too many chunks on your system.') }.size == 1 }
168
171
  end
169
172
 
@@ -172,6 +175,7 @@ class BufferedOutputTest < Test::Unit::TestCase
172
175
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_keys,@hash)]))
173
176
  logs = @i.log.out.logs.dup
174
177
  @i.start
178
+ @i.after_start
175
179
  assert{ logs.select{|log| log.include?('[warn]') }.size == 0 }
176
180
  end
177
181
  end
@@ -187,6 +191,7 @@ class BufferedOutputTest < Test::Unit::TestCase
187
191
  @i = create_output(:buffered)
188
192
  @i.configure(config_element('ROOT','',{},[config_element('buffer','',hash)]))
189
193
  @i.start
194
+ @i.after_start
190
195
  end
191
196
 
192
197
  test '#start does not create enqueue thread, but creates flush threads' do
@@ -289,6 +294,7 @@ class BufferedOutputTest < Test::Unit::TestCase
289
294
  @i = create_output(:buffered)
290
295
  @i.configure(config_element('ROOT','',{},[config_element('buffer','',hash)]))
291
296
  @i.start
297
+ @i.after_start
292
298
  end
293
299
 
294
300
  test '#start creates enqueue thread and flush threads' do
@@ -398,6 +404,7 @@ class BufferedOutputTest < Test::Unit::TestCase
398
404
  @i = create_output(:buffered)
399
405
  @i.configure(config_element('ROOT','',{},[config_element('buffer','',hash)]))
400
406
  @i.start
407
+ @i.after_start
401
408
  end
402
409
 
403
410
  test '#start does not create enqueue thread, but creates flush threads' do
@@ -491,6 +498,7 @@ class BufferedOutputTest < Test::Unit::TestCase
491
498
  @i = create_output(:buffered)
492
499
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
493
500
  @i.start
501
+ @i.after_start
494
502
  end
495
503
 
496
504
  test '#configure raises config error if timekey is not specified' do
@@ -706,6 +714,7 @@ class BufferedOutputTest < Test::Unit::TestCase
706
714
  @i = create_output(:buffered)
707
715
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
708
716
  @i.start
717
+ @i.after_start
709
718
  end
710
719
 
711
720
  test 'default flush_mode is set to :interval' do
@@ -922,6 +931,7 @@ class BufferedOutputTest < Test::Unit::TestCase
922
931
  @i = create_output(:buffered)
923
932
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
924
933
  @i.start
934
+ @i.after_start
925
935
  end
926
936
 
927
937
  test 'default flush_mode is set to :interval' do
@@ -1134,6 +1144,7 @@ class BufferedOutputTest < Test::Unit::TestCase
1134
1144
  @i = create_output(:buffered)
1135
1145
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
1136
1146
  @i.start
1147
+ @i.after_start
1137
1148
 
1138
1149
  assert_equal :interval, @i.instance_eval{ @flush_mode }
1139
1150
  end
@@ -1150,6 +1161,7 @@ class BufferedOutputTest < Test::Unit::TestCase
1150
1161
  @i = create_output(:buffered)
1151
1162
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
1152
1163
  @i.start
1164
+ @i.after_start
1153
1165
 
1154
1166
  assert_equal :lazy, @i.instance_eval{ @flush_mode }
1155
1167
  end
@@ -1168,6 +1180,7 @@ class BufferedOutputTest < Test::Unit::TestCase
1168
1180
  @i = create_output(:delayed)
1169
1181
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
1170
1182
  @i.start
1183
+ @i.after_start
1171
1184
  end
1172
1185
 
1173
1186
  test '#format is called for each event streams' do
@@ -70,6 +70,7 @@ class BufferedOutputOverflowTest < Test::Unit::TestCase
70
70
  @i = create_output()
71
71
  @i.configure(config_element('ROOT','',{},[config_element('buffer','tag',hash)]))
72
72
  @i.start
73
+ @i.after_start
73
74
  end
74
75
 
75
76
  test '#emit_events raises error when buffer is full' do
@@ -108,6 +109,7 @@ class BufferedOutputOverflowTest < Test::Unit::TestCase
108
109
  @i = create_output()
109
110
  @i.configure(config_element('ROOT','',{'log_level' => 'debug'},[config_element('buffer','tag',hash)]))
110
111
  @i.start
112
+ @i.after_start
111
113
  end
112
114
 
113
115
  test '#emit_events blocks until any queues are flushed' do
@@ -169,6 +171,7 @@ class BufferedOutputOverflowTest < Test::Unit::TestCase
169
171
  @i = create_output()
170
172
  @i.configure(config_element('ROOT','',{'log_level' => 'debug'},[config_element('buffer','tag',hash)]))
171
173
  @i.start
174
+ @i.after_start
172
175
  end
173
176
 
174
177
  test '#emit_events will success by dropping oldest chunk' do
@@ -127,6 +127,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
127
127
  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
128
128
  @i.register(:prefer_buffered_processing){ true }
129
129
  @i.start
130
+ @i.after_start
130
131
 
131
132
  assert_equal :exponential_backoff, @i.buffer_config.retry_type
132
133
  assert_equal 1, @i.buffer_config.retry_wait
@@ -160,6 +161,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
160
161
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
161
162
  @i.register(:write){|chunk| raise "yay, your #write must fail" }
162
163
  @i.start
164
+ @i.after_start
163
165
 
164
166
  @i.interrupt_flushes
165
167
 
@@ -201,6 +203,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
201
203
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
202
204
  @i.register(:write){|chunk| raise "yay, your #write must fail" }
203
205
  @i.start
206
+ @i.after_start
204
207
 
205
208
  @i.interrupt_flushes
206
209
 
@@ -255,6 +258,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
255
258
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
256
259
  @i.register(:write){|chunk| written_tags << chunk.metadata.tag; raise "yay, your #write must fail" }
257
260
  @i.start
261
+ @i.after_start
258
262
 
259
263
  @i.interrupt_flushes
260
264
 
@@ -344,6 +348,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
344
348
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
345
349
  @i.register(:write){|chunk| written_tags << chunk.metadata.tag; raise "yay, your #write must fail" }
346
350
  @i.start
351
+ @i.after_start
347
352
 
348
353
  @i.interrupt_flushes
349
354
 
@@ -424,6 +429,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
424
429
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
425
430
  @i.register(:write){|chunk| raise "yay, your #write must fail" }
426
431
  @i.start
432
+ @i.after_start
427
433
 
428
434
  @i.interrupt_flushes
429
435
 
@@ -469,6 +475,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
469
475
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
470
476
  @i.register(:write){|chunk| written_tags << chunk.metadata.tag; raise "yay, your #write must fail" }
471
477
  @i.start
478
+ @i.after_start
472
479
 
473
480
  @i.interrupt_flushes
474
481
 
@@ -563,6 +570,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
563
570
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
564
571
  @i.register(:write){|chunk| written_tags << chunk.metadata.tag; raise "yay, your #write must fail" }
565
572
  @i.start
573
+ @i.after_start
566
574
 
567
575
  @i.interrupt_flushes
568
576
 
@@ -660,6 +668,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
660
668
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
661
669
  @i.register(:write){|chunk| written_tags << chunk.metadata.tag; raise "yay, your #write must fail" }
662
670
  @i.start
671
+ @i.after_start
663
672
 
664
673
  @i.interrupt_flushes
665
674
 
@@ -730,6 +739,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
730
739
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
731
740
  @i.register(:write){|chunk| written_tags << chunk.metadata.tag; raise "yay, your #write must fail" }
732
741
  @i.start
742
+ @i.after_start
733
743
 
734
744
  @i.interrupt_flushes
735
745
 
@@ -797,6 +807,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
797
807
  @i.register(:format){|tag,time,record| [tag,time.to_i,record].to_json + "\n" }
798
808
  @i.register(:try_write){|chunk| raise "yay, your #write must fail" }
799
809
  @i.start
810
+ @i.after_start
800
811
 
801
812
  @i.interrupt_flushes
802
813
 
@@ -170,6 +170,10 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase
170
170
  i.start
171
171
  assert i.secondary.started?
172
172
 
173
+ assert !i.secondary.after_started?
174
+ i.after_start
175
+ assert i.secondary.after_started?
176
+
173
177
  assert !i.secondary.stopped?
174
178
  i.stop
175
179
  assert i.secondary.stopped?
@@ -207,6 +211,7 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase
207
211
  @i.secondary.register(:prefer_delayed_commit){ false }
208
212
  @i.secondary.register(:write){|chunk| chunk.read.split("\n").each{|line| written << JSON.parse(line) } }
209
213
  @i.start
214
+ @i.after_start
210
215
 
211
216
  @i.interrupt_flushes
212
217
 
@@ -271,6 +276,7 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase
271
276
  @i.secondary.register(:prefer_delayed_commit){ false }
272
277
  @i.secondary.register(:write){|chunk| chunk.read.split("\n").each{|line| written << JSON.parse(line) } }
273
278
  @i.start
279
+ @i.after_start
274
280
 
275
281
  @i.interrupt_flushes
276
282
 
@@ -336,6 +342,7 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase
336
342
  @i.secondary.register(:prefer_delayed_commit){ true }
337
343
  @i.secondary.register(:try_write){|chunk| chunks << chunk; chunk.read.split("\n").each{|line| written << JSON.parse(line) } }
338
344
  @i.start
345
+ @i.after_start
339
346
 
340
347
  @i.interrupt_flushes
341
348
 
@@ -412,6 +419,7 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase
412
419
  @i.secondary.register(:prefer_delayed_commit){ true }
413
420
  @i.secondary.register(:try_write){|chunk| chunks << chunk; chunk.read.split("\n").each{|line| written << JSON.parse(line) } }
414
421
  @i.start
422
+ @i.after_start
415
423
 
416
424
  @i.interrupt_flushes
417
425
 
@@ -489,6 +497,7 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase
489
497
  @i.secondary.register(:try_write){|chunk| chunks << chunk; chunk.read.split("\n").each{|line| written << JSON.parse(line) } }
490
498
  @i.secondary.register(:write){|chunk| raise "don't use this" }
491
499
  @i.start
500
+ @i.after_start
492
501
 
493
502
  @i.interrupt_flushes
494
503
 
@@ -573,6 +582,7 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase
573
582
  @i.secondary.register(:prefer_delayed_commit){ false }
574
583
  @i.secondary.register(:write){|chunk| raise "your secondary is also useless." }
575
584
  @i.start
585
+ @i.after_start
576
586
 
577
587
  @i.interrupt_flushes
578
588
 
@@ -643,6 +653,7 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase
643
653
  @i.secondary.register(:prefer_delayed_commit){ false }
644
654
  @i.secondary.register(:write){|chunk| chunk.read.split("\n").each{|line| written << JSON.parse(line) } }
645
655
  @i.start
656
+ @i.after_start
646
657
 
647
658
  @i.interrupt_flushes
648
659
 
@@ -713,6 +724,7 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase
713
724
  @i.secondary.register(:prefer_delayed_commit){ false }
714
725
  @i.secondary.register(:write){|chunk| raise "your secondary is also useless." }
715
726
  @i.start
727
+ @i.after_start
716
728
 
717
729
  @i.interrupt_flushes
718
730
 
@@ -85,6 +85,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
85
85
  @i = create_output(:standard)
86
86
  @i.configure(config_element())
87
87
  @i.start
88
+ @i.after_start
88
89
 
89
90
  m = create_metadata()
90
91
  es = test_event_stream
@@ -99,6 +100,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
99
100
  @i = create_output(:standard)
100
101
  @i.configure(config_element('ROOT','',{"time_as_integer"=>"true"}))
101
102
  @i.start
103
+ @i.after_start
102
104
 
103
105
  m = create_metadata()
104
106
  es = test_event_stream
@@ -115,6 +117,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
115
117
  @i = create_output(:standard)
116
118
  @i.configure(config_element('ROOT','',{},[config_element('buffer','tag',{'flush_thread_burst_interval' => 0.01})]))
117
119
  @i.start
120
+ @i.after_start
118
121
 
119
122
  m = create_metadata(tag: "mytag.test")
120
123
  es = test_event_stream
@@ -129,6 +132,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
129
132
  @i = create_output(:standard)
130
133
  @i.configure(config_element('ROOT','',{"time_as_integer"=>"true"},[config_element('buffer','tag',{'flush_thread_burst_interval' => 0.01})]))
131
134
  @i.start
135
+ @i.after_start
132
136
 
133
137
  m = create_metadata(tag: "mytag.test")
134
138
  es = test_event_stream
@@ -145,6 +149,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
145
149
  @i = create_output(:standard)
146
150
  @i.configure(config_element('ROOT','',{},[config_element('buffer','time',{"timekey" => "60",'flush_thread_burst_interval' => 0.01})]))
147
151
  @i.start
152
+ @i.after_start
148
153
 
149
154
  m1 = create_metadata(timekey: Time.parse('2016-04-21 17:19:00 -0700').to_i)
150
155
  m2 = create_metadata(timekey: Time.parse('2016-04-21 17:20:00 -0700').to_i)
@@ -177,6 +182,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
177
182
  @i = create_output(:standard)
178
183
  @i.configure(config_element('ROOT','',{"time_as_integer" => "true"},[config_element('buffer','time',{"timekey" => "60",'flush_thread_burst_interval' => 0.01})]))
179
184
  @i.start
185
+ @i.after_start
180
186
 
181
187
  m1 = create_metadata(timekey: Time.parse('2016-04-21 17:19:00 -0700').to_i)
182
188
  m2 = create_metadata(timekey: Time.parse('2016-04-21 17:20:00 -0700').to_i)
@@ -211,6 +217,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
211
217
  @i = create_output(:standard)
212
218
  @i.configure(config_element('ROOT','',{},[config_element('buffer','key,name',{'flush_thread_burst_interval' => 0.01})]))
213
219
  @i.start
220
+ @i.after_start
214
221
 
215
222
  m1 = create_metadata(variables: {key: "my value", name: "moris1"})
216
223
  es1 = Fluent::MultiEventStream.new
@@ -238,6 +245,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
238
245
  @i = create_output(:standard)
239
246
  @i.configure(config_element('ROOT','',{"time_as_integer" => "true"},[config_element('buffer','key,name',{'flush_thread_burst_interval' => 0.01})]))
240
247
  @i.start
248
+ @i.after_start
241
249
 
242
250
  m1 = create_metadata(variables: {key: "my value", name: "moris1"})
243
251
  es1 = Fluent::MultiEventStream.new
@@ -268,6 +276,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
268
276
  @i.register(:format){|tag, time, record| [time, record].to_json }
269
277
  @i.configure(config_element())
270
278
  @i.start
279
+ @i.after_start
271
280
 
272
281
  m = create_metadata()
273
282
  es = test_event_stream
@@ -285,6 +294,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
285
294
  @i.register(:format){|tag, time, record| [time, record].to_json }
286
295
  @i.configure(config_element('ROOT','',{},[config_element('buffer','tag',{'flush_thread_burst_interval' => 0.01})]))
287
296
  @i.start
297
+ @i.after_start
288
298
 
289
299
  m = create_metadata(tag: "mytag.test")
290
300
  es = test_event_stream
@@ -301,6 +311,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
301
311
  @i.register(:format){|tag, time, record| [time, record].to_json }
302
312
  @i.configure(config_element('ROOT','',{},[config_element('buffer','time',{"timekey" => "60",'flush_thread_burst_interval' => 0.01})]))
303
313
  @i.start
314
+ @i.after_start
304
315
 
305
316
  m1 = create_metadata(timekey: Time.parse('2016-04-21 17:19:00 -0700').to_i)
306
317
  m2 = create_metadata(timekey: Time.parse('2016-04-21 17:20:00 -0700').to_i)
@@ -336,6 +347,7 @@ class StandardBufferedOutputTest < Test::Unit::TestCase
336
347
  @i.register(:format){|tag, time, record| [time, record].to_json }
337
348
  @i.configure(config_element('ROOT','',{},[config_element('buffer','key,name',{'flush_thread_burst_interval' => 0.01})]))
338
349
  @i.start
350
+ @i.after_start
339
351
 
340
352
  m1 = create_metadata(variables: {key: "my value", name: "moris1"})
341
353
  es1 = Fluent::MultiEventStream.new
@@ -186,6 +186,7 @@ class CompatParameterTest < Test::Unit::TestCase
186
186
  @i = DummyO4.new
187
187
  @i.configure(conf)
188
188
  @i.start
189
+ @i.after_start
189
190
 
190
191
  assert_equal 'file', @i.buffer_config[:@type]
191
192
  assert_equal 10, @i.buffer_config.flush_thread_count
@@ -219,6 +220,7 @@ class CompatParameterTest < Test::Unit::TestCase
219
220
  @i = DummyO4.new
220
221
  @i.configure(conf)
221
222
  @i.start
223
+ @i.after_start
222
224
 
223
225
  assert_equal 'file', @i.buffer_config[:@type]
224
226
  assert_equal 10, @i.buffer_config.flush_thread_count
@@ -97,4 +97,35 @@ class TimerTest < Test::Unit::TestCase
97
97
 
98
98
  d1.shutdown; d1.close; d1.terminate
99
99
  end
100
+
101
+ test 'can run at once' do
102
+ d1 = Dummy.new
103
+ d1.configure(config_element())
104
+ assert !d1.timer_running?
105
+ d1.start
106
+ assert d1.timer_running?
107
+
108
+ waiting_assertion = true
109
+ waiting_timer = true
110
+ counter = 0
111
+ d1.timer_execute(:test, 1, repeat: false) do
112
+ sleep(0.1) while waiting_assertion
113
+ counter += 1
114
+ waiting_timer = false
115
+ end
116
+
117
+ watchers = d1._event_loop.watchers.reject {|w| w.is_a?(Fluent::PluginHelper::EventLoop::DefaultWatcher) }
118
+ assert_equal(1, watchers.size)
119
+ assert(watchers.first.attached?)
120
+
121
+ waiting_assertion = false
122
+ sleep(0.1) while waiting_timer
123
+
124
+ assert_equal(1, counter)
125
+ assert_false(watchers.first.attached?)
126
+ watchers = d1._event_loop.watchers.reject {|w| w.is_a?(Fluent::PluginHelper::EventLoop::DefaultWatcher) }
127
+ assert_equal(0, watchers.size)
128
+
129
+ d1.shutdown; d1.close; d1.terminate
130
+ end
100
131
  end
@@ -185,6 +185,10 @@ class EventRouterTest < ::Test::Unit::TestCase
185
185
 
186
186
  sub_test_case 'filter' do
187
187
  test 'filter should be called when tag matched' do
188
+ filter = Class.new(FluentTestFilter) { |x|
189
+ def filter_stream(_tag, es); end
190
+ }.new
191
+
188
192
  event_router.add_rule('test', filter)
189
193
 
190
194
  assert_rr do
@@ -229,6 +233,89 @@ class EventRouterTest < ::Test::Unit::TestCase
229
233
  end
230
234
  end
231
235
 
236
+ sub_test_case 'optimized filter' do
237
+ setup do
238
+ @record = { 'k' => 'v' }
239
+ @now = Engine.now
240
+ end
241
+
242
+ test 'call optimized filter when the filter plugin implements #filter without #filter_stream' do
243
+ event_router.add_rule('test', filter)
244
+
245
+ assert_rr do
246
+ mock(filter).filter('test', @now, @record) { @record }
247
+ event_router.emit('test', @now, @record)
248
+ end
249
+ end
250
+
251
+ test 'call optimized filter when the filter plugin implements #filter_with_time without #filter_stream' do
252
+ filter = Class.new(FluentTestFilter) {
253
+ undef_method :filter
254
+ def filter_with_time(tag, time, record); end
255
+ }.new
256
+
257
+ event_router.add_rule('test', filter)
258
+
259
+ assert_rr do
260
+ mock(filter).filter_with_time('test', @now, @record) { [time, @record] }
261
+ event_router.emit('test', @now, @record)
262
+ end
263
+ end
264
+
265
+ test "don't call optimized filter when filter plugins implement #filter_stream" do
266
+ filter = Class.new(FluentTestFilter) {
267
+ undef_method :filter
268
+ def filter_stream(tag, time, record); end
269
+ }.new
270
+
271
+ event_router.add_rule('test', filter)
272
+
273
+ assert_rr do
274
+ mock(filter).filter_stream('test', is_a(OneEventStream)) { OneEventStream.new(@now, @record) }
275
+ event_router.emit('test', @now, @record)
276
+ end
277
+ end
278
+
279
+ test 'call optimized filter when filter plugins have #filter_with_time instead of #filter' do
280
+ filter_with_time = Class.new(FluentTestFilter) {
281
+ undef_method :filter
282
+ def filter_with_time(tag, time, record); end
283
+ }.new
284
+
285
+ event_router.add_rule('test', filter_with_time)
286
+ event_router.add_rule('test', filter)
287
+
288
+ assert_rr do
289
+ mock(filter_with_time).filter_with_time('test', @now, @record) { [@now + 1, @record] }
290
+ mock(filter).filter('test', @now + 1, @record) { @record }
291
+ event_router.emit('test', @now, @record)
292
+ end
293
+ end
294
+
295
+ test "don't call optimized filter even if just a filter of some filters implements #filter_stream method" do
296
+ filter_stream = Class.new(FluentTestFilter) {
297
+ def filter_stream(tag, record); end
298
+ }.new
299
+
300
+ filter_with_time = Class.new(FluentTestFilter) {
301
+ undef_method :filter
302
+ def filter_with_time(tag, time, record); end
303
+ }.new
304
+
305
+ filters = [filter_stream, filter_with_time, filter]
306
+ filters.each { |f| event_router.add_rule('test', f) }
307
+
308
+ e = OneEventStream.new(@now, @record)
309
+ assert_rr do
310
+ mock($log).info("Filtering works with worse performance, because #{[filter_stream].map(&:class)} uses `#filter_stream` method.")
311
+ mock(filter_stream).filter_stream('test', is_a(OneEventStream)) { e }
312
+ mock(filter).filter_stream('test', is_a(OneEventStream)) { e }
313
+ mock(filter_with_time).filter_stream('test', is_a(OneEventStream)) { e }
314
+ event_router.emit('test', @now, @record)
315
+ end
316
+ end
317
+ end
318
+
232
319
  sub_test_case 'emit_error_handler' do
233
320
  test 'call handle_emits_error when emit failed' do
234
321
  event_router.add_rule('test', error_output)