fluentd 0.14.9 → 0.14.10

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.

Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/ChangeLog +44 -0
  4. data/appveyor.yml +1 -0
  5. data/code-of-conduct.md +3 -0
  6. data/fluentd.gemspec +1 -1
  7. data/lib/fluent/command/cat.rb +11 -3
  8. data/lib/fluent/compat/output.rb +6 -3
  9. data/lib/fluent/compat/parser.rb +2 -0
  10. data/lib/fluent/config/section.rb +1 -1
  11. data/lib/fluent/env.rb +1 -1
  12. data/lib/fluent/plugin/filter_record_transformer.rb +12 -30
  13. data/lib/fluent/plugin/in_forward.rb +50 -169
  14. data/lib/fluent/plugin/in_monitor_agent.rb +8 -4
  15. data/lib/fluent/plugin/in_syslog.rb +13 -7
  16. data/lib/fluent/plugin/in_tail.rb +29 -14
  17. data/lib/fluent/plugin/in_tcp.rb +54 -14
  18. data/lib/fluent/plugin/in_udp.rb +49 -13
  19. data/lib/fluent/plugin/out_file.rb +30 -14
  20. data/lib/fluent/plugin/out_forward.rb +199 -173
  21. data/lib/fluent/plugin/output.rb +71 -46
  22. data/lib/fluent/plugin/parser_json.rb +1 -1
  23. data/lib/fluent/plugin_helper.rb +2 -0
  24. data/lib/fluent/plugin_helper/event_loop.rb +24 -6
  25. data/lib/fluent/plugin_helper/inject.rb +12 -1
  26. data/lib/fluent/plugin_helper/server.rb +494 -0
  27. data/lib/fluent/plugin_helper/socket.rb +101 -0
  28. data/lib/fluent/plugin_helper/socket_option.rb +84 -0
  29. data/lib/fluent/plugin_helper/timer.rb +1 -0
  30. data/lib/fluent/test/driver/base.rb +45 -13
  31. data/lib/fluent/version.rb +1 -1
  32. data/lib/fluent/winsvc.rb +1 -1
  33. data/test/compat/test_parser.rb +10 -0
  34. data/test/config/test_configurable.rb +20 -0
  35. data/test/helper.rb +36 -1
  36. data/test/plugin/test_filter_record_transformer.rb +31 -103
  37. data/test/plugin/test_in_forward.rb +13 -75
  38. data/test/plugin/test_in_monitor_agent.rb +65 -35
  39. data/test/plugin/test_in_syslog.rb +39 -3
  40. data/test/plugin/test_in_tcp.rb +78 -62
  41. data/test/plugin/test_in_udp.rb +101 -80
  42. data/test/plugin/test_out_file.rb +17 -0
  43. data/test/plugin/test_out_forward.rb +155 -125
  44. data/test/plugin/test_output_as_buffered.rb +4 -2
  45. data/test/plugin_helper/test_inject.rb +21 -0
  46. data/test/plugin_helper/test_server.rb +905 -0
  47. data/test/test_event_time.rb +3 -1
  48. data/test/test_output.rb +30 -1
  49. data/test/test_test_drivers.rb +5 -2
  50. metadata +19 -6
@@ -59,13 +59,6 @@ class ForwardInputTest < Test::Unit::TestCase
59
59
  end
60
60
 
61
61
  sub_test_case '#configure' do
62
- setup do
63
- Fluent::Test::StartupShutdown.setup
64
- end
65
- teardown do
66
- Fluent::Test::StartupShutdown.teardown
67
- end
68
-
69
62
  test 'simple' do
70
63
  @d = d = create_driver
71
64
  assert_equal PORT, d.instance.port
@@ -88,18 +81,7 @@ class ForwardInputTest < Test::Unit::TestCase
88
81
  end
89
82
  end
90
83
 
91
- def connect
92
- TCPSocket.new('127.0.0.1', PORT)
93
- end
94
-
95
84
  sub_test_case 'message' do
96
- setup do
97
- Fluent::Test::StartupShutdown.setup
98
- end
99
- teardown do
100
- Fluent::Test::StartupShutdown.teardown
101
- end
102
-
103
85
  test 'time' do
104
86
  time = event_time("2011-01-02 13:14:15 UTC")
105
87
  begin
@@ -221,6 +203,7 @@ class ForwardInputTest < Test::Unit::TestCase
221
203
  d.run(expect_records: records.length, timeout: 20) do
222
204
  records.each {|tag, _time, record|
223
205
  send_data [tag, _time, record].to_json + "\n"
206
+ sleep 1
224
207
  }
225
208
  end
226
209
 
@@ -229,13 +212,6 @@ class ForwardInputTest < Test::Unit::TestCase
229
212
  end
230
213
 
231
214
  sub_test_case 'forward' do
232
- setup do
233
- Fluent::Test::StartupShutdown.setup
234
- end
235
- teardown do
236
- Fluent::Test::StartupShutdown.teardown
237
- end
238
-
239
215
  data(tcp: {
240
216
  config: CONFIG,
241
217
  options: {
@@ -345,13 +321,6 @@ class ForwardInputTest < Test::Unit::TestCase
345
321
  end
346
322
 
347
323
  sub_test_case 'packed forward' do
348
- setup do
349
- Fluent::Test::StartupShutdown.setup
350
- end
351
- teardown do
352
- Fluent::Test::StartupShutdown.teardown
353
- end
354
-
355
324
  data(tcp: {
356
325
  config: CONFIG,
357
326
  options: {
@@ -464,13 +433,6 @@ class ForwardInputTest < Test::Unit::TestCase
464
433
  end
465
434
 
466
435
  sub_test_case 'compressed packed forward' do
467
- setup do
468
- Fluent::Test::StartupShutdown.setup
469
- end
470
- teardown do
471
- Fluent::Test::StartupShutdown.teardown
472
- end
473
-
474
436
  test 'set_compress_to_option' do
475
437
  @d = d = create_driver
476
438
 
@@ -528,13 +490,6 @@ class ForwardInputTest < Test::Unit::TestCase
528
490
  end
529
491
 
530
492
  sub_test_case 'warning' do
531
- setup do
532
- Fluent::Test::StartupShutdown.setup
533
- end
534
- teardown do
535
- Fluent::Test::StartupShutdown.teardown
536
- end
537
-
538
493
  test 'send_large_chunk_warning' do
539
494
  @d = d = create_driver(CONFIG + %[
540
495
  chunk_size_warn_limit 16M
@@ -551,7 +506,7 @@ class ForwardInputTest < Test::Unit::TestCase
551
506
 
552
507
  d.run(shutdown: false) do
553
508
  Fluent::Engine.msgpack_factory.unpacker.feed_each(chunk) do |obj|
554
- d.instance.send(:on_message, obj, chunk.size, PEERADDR)
509
+ d.instance.send(:on_message, obj, chunk.size, '127.0.0.1')
555
510
  end
556
511
  end
557
512
 
@@ -565,7 +520,7 @@ class ForwardInputTest < Test::Unit::TestCase
565
520
  logs = d.instance.log.logs
566
521
  assert_equal 1, logs.select{|line|
567
522
  line =~ / \[warn\]: Input chunk size is larger than 'chunk_size_warn_limit':/ &&
568
- line =~ / tag="test.tag" source="host: 127.0.0.1, addr: 127.0.0.1, port: \d+" limit=16777216 size=16777501/
523
+ line =~ / tag="test.tag" host="127.0.0.1" limit=16777216 size=16777501/
569
524
  }.size, "large chunk warning is not logged"
570
525
 
571
526
  d.instance_shutdown
@@ -583,7 +538,7 @@ class ForwardInputTest < Test::Unit::TestCase
583
538
 
584
539
  d.run(shutdown: false) do
585
540
  Fluent::Engine.msgpack_factory.unpacker.feed_each(chunk) do |obj|
586
- d.instance.send(:on_message, obj, chunk.size, PEERADDR)
541
+ d.instance.send(:on_message, obj, chunk.size, '127.0.0.1')
587
542
  end
588
543
  end
589
544
 
@@ -591,7 +546,7 @@ class ForwardInputTest < Test::Unit::TestCase
591
546
  logs = d.instance.log.logs
592
547
  assert_equal 1, logs.select{ |line|
593
548
  line =~ / \[warn\]: Input chunk size is larger than 'chunk_size_warn_limit':/ &&
594
- line =~ / tag="test.tag" source="host: 127.0.0.1, addr: 127.0.0.1, port: \d+" limit=16777216 size=16777501/
549
+ line =~ / tag="test.tag" host="127.0.0.1" limit=16777216 size=16777501/
595
550
  }.size, "large chunk warning is not logged"
596
551
 
597
552
  d.instance_shutdown
@@ -613,7 +568,7 @@ class ForwardInputTest < Test::Unit::TestCase
613
568
  # d.run => send_data
614
569
  d.run(shutdown: false) do
615
570
  Fluent::Engine.msgpack_factory.unpacker.feed_each(chunk) do |obj|
616
- d.instance.send(:on_message, obj, chunk.size, PEERADDR)
571
+ d.instance.send(:on_message, obj, chunk.size, '127.0.0.1')
617
572
  end
618
573
  end
619
574
 
@@ -625,7 +580,7 @@ class ForwardInputTest < Test::Unit::TestCase
625
580
  logs = d.instance.log.logs
626
581
  assert_equal 1, logs.select{|line|
627
582
  line =~ / \[warn\]: Input chunk size is larger than 'chunk_size_limit', dropped:/ &&
628
- line =~ / tag="test.tag" source="host: 127.0.0.1, addr: 127.0.0.1, port: \d+" limit=33554432 size=33554989/
583
+ line =~ / tag="test.tag" host="127.0.0.1" limit=33554432 size=33554989/
629
584
  }.size, "large chunk warning is not logged"
630
585
 
631
586
  d.instance_shutdown
@@ -638,7 +593,7 @@ class ForwardInputTest < Test::Unit::TestCase
638
593
 
639
594
  # d.run => send_data
640
595
  d.run(shutdown: false) do
641
- d.instance.send(:on_message, data, 1000000000, PEERADDR)
596
+ d.instance.send(:on_message, data, 1000000000, '127.0.0.1')
642
597
  end
643
598
 
644
599
  # check emitted data
@@ -647,7 +602,7 @@ class ForwardInputTest < Test::Unit::TestCase
647
602
  # check log
648
603
  logs = d.instance.log.logs
649
604
  assert_equal 1, logs.select{|line|
650
- line =~ / \[warn\]: incoming chunk is broken: source="host: 127.0.0.1, addr: 127.0.0.1, port: \d+" msg=#{data.inspect}/
605
+ line =~ / \[warn\]: incoming chunk is broken: host="127.0.0.1" msg=#{data.inspect}/
651
606
  }.size, "should not accept broken chunk"
652
607
 
653
608
  d.instance_shutdown
@@ -655,13 +610,6 @@ class ForwardInputTest < Test::Unit::TestCase
655
610
  end
656
611
 
657
612
  sub_test_case 'respond to required ack' do
658
- setup do
659
- Fluent::Test::StartupShutdown.setup
660
- end
661
- teardown do
662
- Fluent::Test::StartupShutdown.teardown
663
- end
664
-
665
613
  data(tcp: {
666
614
  config: CONFIG,
667
615
  options: {
@@ -824,13 +772,6 @@ class ForwardInputTest < Test::Unit::TestCase
824
772
  end
825
773
 
826
774
  sub_test_case 'not respond without required ack' do
827
- setup do
828
- Fluent::Test::StartupShutdown.setup
829
- end
830
- teardown do
831
- Fluent::Test::StartupShutdown.teardown
832
- end
833
-
834
775
  data(tcp: {
835
776
  config: CONFIG,
836
777
  options: {
@@ -1068,6 +1009,10 @@ class ForwardInputTest < Test::Unit::TestCase
1068
1009
  true
1069
1010
  end
1070
1011
 
1012
+ def connect
1013
+ TCPSocket.new('127.0.0.1', PORT)
1014
+ end
1015
+
1071
1016
  # Data ordering is not assured:
1072
1017
  # Records in different sockets are processed on different thread, so its scheduling make effect
1073
1018
  # on order of emitted records.
@@ -1089,13 +1034,6 @@ class ForwardInputTest < Test::Unit::TestCase
1089
1034
  end
1090
1035
 
1091
1036
  sub_test_case 'source_hostname_key feature' do
1092
- setup do
1093
- Fluent::Test::StartupShutdown.setup
1094
- end
1095
- teardown do
1096
- Fluent::Test::StartupShutdown.teardown
1097
- end
1098
-
1099
1037
  test 'message protocol with source_hostname_key' do
1100
1038
  execute_test { |events|
1101
1039
  events.each { |tag, time, record|
@@ -30,6 +30,7 @@ class MonitorAgentInputTest < Test::Unit::TestCase
30
30
  assert_equal(24220, d.instance.port)
31
31
  assert_equal(nil, d.instance.tag)
32
32
  assert_equal(60, d.instance.emit_interval)
33
+ assert_true d.instance.include_config
33
34
  end
34
35
 
35
36
  sub_test_case "collect plugin information" do
@@ -90,48 +91,37 @@ EOC
90
91
  assert_equal("output", d.instance.plugin_category(error_label.outputs.first))
91
92
  end
92
93
 
93
- test "get_monitor_info" do
94
+ data(:with_config_yes => true,
95
+ :with_config_no => false)
96
+ test "get_monitor_info" do |with_config|
94
97
  d = create_driver
95
98
  test_label = @ra.labels['@test']
96
99
  error_label = @ra.labels['@ERROR']
97
100
  input_info = {
98
- "config" => {
99
- "@id" => "test_in",
100
- "@type" => "test_in"
101
- },
102
101
  "output_plugin" => false,
103
102
  "plugin_category"=> "input",
104
103
  "plugin_id" => "test_in",
105
104
  "retry_count" => nil,
106
105
  "type" => "test_in"
107
106
  }
107
+ input_info.merge!("config" => {"@id" => "test_in", "@type" => "test_in"}) if with_config
108
108
  filter_info = {
109
- "config" => {
110
- "@id" => "test_filter",
111
- "@type" => "test_filter"
112
- },
113
109
  "output_plugin" => false,
114
110
  "plugin_category" => "filter",
115
111
  "plugin_id" => "test_filter",
116
112
  "retry_count" => nil,
117
113
  "type" => "test_filter"
118
114
  }
115
+ filter_info.merge!("config" => {"@id" => "test_filter", "@type" => "test_filter"}) if with_config
119
116
  output_info = {
120
- "config" => {
121
- "@id" => "test_out",
122
- "@type" => "test_out"
123
- },
124
117
  "output_plugin" => true,
125
118
  "plugin_category" => "output",
126
119
  "plugin_id" => "test_out",
127
120
  "retry_count" => 0,
128
121
  "type" => "test_out"
129
122
  }
123
+ output_info.merge!("config" => {"@id" => "test_out", "@type" => "test_out"}) if with_config
130
124
  error_label_info = {
131
- "config" => {
132
- "@id"=>"null",
133
- "@type" => "null"
134
- },
135
125
  "buffer_queue_length" => 0,
136
126
  "buffer_total_queued_size" => 0,
137
127
  "output_plugin" => true,
@@ -140,10 +130,12 @@ EOC
140
130
  "retry_count" => 0,
141
131
  "type" => "null"
142
132
  }
143
- assert_equal(input_info, d.instance.get_monitor_info(@ra.inputs.first))
144
- assert_equal(filter_info, d.instance.get_monitor_info(@ra.filters.first))
145
- assert_equal(output_info, d.instance.get_monitor_info(test_label.outputs.first))
146
- assert_equal(error_label_info, d.instance.get_monitor_info(error_label.outputs.first))
133
+ error_label_info.merge!("config" => {"@id"=>"null", "@type" => "null"}) if with_config
134
+ opts = {with_config: with_config}
135
+ assert_equal(input_info, d.instance.get_monitor_info(@ra.inputs.first, opts))
136
+ assert_equal(filter_info, d.instance.get_monitor_info(@ra.filters.first, opts))
137
+ assert_equal(output_info, d.instance.get_monitor_info(test_label.outputs.first, opts))
138
+ assert_equal(error_label_info, d.instance.get_monitor_info(error_label.outputs.first, opts))
147
139
  end
148
140
 
149
141
  test "fluentd opts" do
@@ -207,7 +199,7 @@ EOC
207
199
 
208
200
  def get(uri, header = {})
209
201
  url = URI.parse(uri)
210
- req = Net::HTTP::Get.new(url.path, header)
202
+ req = Net::HTTP::Get.new(url, header)
211
203
  unless header.has_key?('Content-Type')
212
204
  header['Content-Type'] = 'application/octet-stream'
213
205
  end
@@ -258,6 +250,8 @@ EOC
258
250
  @ra = Fluent::RootAgent.new(log: $log)
259
251
  stub(Fluent::Engine).root_agent { @ra }
260
252
  @ra = configure_ra(@ra, conf)
253
+ # store Supervisor instance to avoid collected by GC
254
+ @supervisor = Fluent::Supervisor.new(Fluent::Supervisor.default_options)
261
255
  end
262
256
 
263
257
  test "/api/plugins" do
@@ -280,36 +274,36 @@ plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:f
280
274
  assert_equal(expected_test_filter_response, test_filter)
281
275
  end
282
276
 
283
- test "/api/plugins.json" do
277
+ data(:include_config_yes => [true, "include_config yes"],
278
+ :include_config_no => [false, "include_config no"])
279
+ test "/api/plugins.json" do |(with_config, include_conf)|
280
+
284
281
  d = create_driver("
285
282
  @type monitor_agent
286
283
  bind '127.0.0.1'
287
284
  port #{@port}
288
285
  tag monitor
286
+ #{include_conf}
289
287
  ")
290
288
  d.instance.start
291
- expected_test_in_response =
292
- {"config" => {
293
- "@id" => "test_in",
294
- "@type" => "test_in"
295
- },
289
+ expected_test_in_response = {
296
290
  "output_plugin" => false,
297
291
  "plugin_category" => "input",
298
292
  "plugin_id" => "test_in",
299
293
  "retry_count" => nil,
300
- "type" => "test_in"}
301
- expected_null_response =
302
- {"config" => {
303
- "@id" => "null",
304
- "@type" => "null"
305
- },
294
+ "type" => "test_in"
295
+ }
296
+ expected_test_in_response.merge!("config" => {"@id" => "test_in", "@type" => "test_in"}) if with_config
297
+ expected_null_response = {
306
298
  "buffer_queue_length" => 0,
307
299
  "buffer_total_queued_size" => 0,
308
300
  "output_plugin" => true,
309
301
  "plugin_category" => "output",
310
302
  "plugin_id" => "null",
311
303
  "retry_count" => 0,
312
- "type" => "null"}
304
+ "type" => "null"
305
+ }
306
+ expected_null_response.merge!("config" => {"@id" => "null", "@type" => "null"}) if with_config
313
307
  response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json"))
314
308
  test_in_response = response["plugins"][0]
315
309
  null_response = response["plugins"][5]
@@ -317,6 +311,42 @@ plugin_id:test_filter\tplugin_category:filter\ttype:test_filter\toutput_plugin:f
317
311
  assert_equal(expected_null_response, null_response)
318
312
  end
319
313
 
314
+ data(:with_config_yes => [true, "?with_config=yes"],
315
+ :with_config_no => [false, "?with_config=no"])
316
+ test "/api/plugins.json with query parameter. query parameter is preferred than include_config" do |(with_config, query_param)|
317
+
318
+ d = create_driver("
319
+ @type monitor_agent
320
+ bind '127.0.0.1'
321
+ port #{@port}
322
+ tag monitor
323
+ ")
324
+ d.instance.start
325
+ expected_test_in_response = {
326
+ "output_plugin" => false,
327
+ "plugin_category" => "input",
328
+ "plugin_id" => "test_in",
329
+ "retry_count" => nil,
330
+ "type" => "test_in"
331
+ }
332
+ expected_test_in_response.merge!("config" => {"@id" => "test_in", "@type" => "test_in"}) if with_config
333
+ expected_null_response = {
334
+ "buffer_queue_length" => 0,
335
+ "buffer_total_queued_size" => 0,
336
+ "output_plugin" => true,
337
+ "plugin_category" => "output",
338
+ "plugin_id" => "null",
339
+ "retry_count" => 0,
340
+ "type" => "null"
341
+ }
342
+ expected_null_response.merge!("config" => {"@id" => "null", "@type" => "null"}) if with_config
343
+ response = JSON.parse(get("http://127.0.0.1:#{@port}/api/plugins.json#{query_param}"))
344
+ test_in_response = response["plugins"][0]
345
+ null_response = response["plugins"][5]
346
+ assert_equal(expected_test_in_response, test_in_response)
347
+ assert_equal(expected_null_response, null_response)
348
+ end
349
+
320
350
  test "/api/config" do
321
351
  d = create_driver("
322
352
  @type monitor_agent
@@ -176,7 +176,41 @@ class SyslogInputTest < Test::Unit::TestCase
176
176
  end
177
177
 
178
178
  assert(d.events.size > 0)
179
- compare_test_result(d.events, tests, host)
179
+ compare_test_result(d.events, tests, {host: host})
180
+ end
181
+
182
+ def test_msg_size_with_include_priority
183
+ d = create_driver([CONFIG, 'priority_key priority'].join("\n"))
184
+ tests = create_test_case
185
+
186
+ priority = 'info'
187
+ d.run(expect_emits: 2) do
188
+ u = UDPSocket.new
189
+ u.connect('127.0.0.1', PORT)
190
+ tests.each {|test|
191
+ u.send(test['msg'], 0)
192
+ }
193
+ end
194
+
195
+ assert(d.events.size > 0)
196
+ compare_test_result(d.events, tests, {priority: priority})
197
+ end
198
+
199
+ def test_msg_size_with_include_facility
200
+ d = create_driver([CONFIG, 'facility_key facility'].join("\n"))
201
+ tests = create_test_case
202
+
203
+ facility = 'kern'
204
+ d.run(expect_emits: 2) do
205
+ u = UDPSocket.new
206
+ u.connect('127.0.0.1', PORT)
207
+ tests.each {|test|
208
+ u.send(test['msg'], 0)
209
+ }
210
+ end
211
+
212
+ assert(d.events.size > 0)
213
+ compare_test_result(d.events, tests, {facility: facility})
180
214
  end
181
215
 
182
216
  def create_test_case(large_message: false)
@@ -195,11 +229,13 @@ class SyslogInputTest < Test::Unit::TestCase
195
229
  end
196
230
  end
197
231
 
198
- def compare_test_result(events, tests, host = nil)
232
+ def compare_test_result(events, tests, options = {})
199
233
  events.each_index { |i|
200
234
  assert_equal('syslog.kern.info', events[i][0]) # <6> means kern.info
201
235
  assert_equal(tests[i]['expected'], events[i][2]['message'])
202
- assert_equal(host, events[i][2]['source_host']) if host
236
+ assert_equal(options[:host], events[i][2]['source_host']) if options[:host]
237
+ assert_equal(options[:priority], events[i][2]['priority']) if options[:priority]
238
+ assert_equal(options[:facility], events[i][2]['facility']) if options[:facility]
203
239
  }
204
240
  end
205
241
  end