fluentd 1.9.2 → 1.9.3

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/CHANGELOG.md +37 -0
  4. data/lib/fluent/env.rb +2 -0
  5. data/lib/fluent/plugin/buf_file.rb +12 -4
  6. data/lib/fluent/plugin/buf_file_single.rb +1 -2
  7. data/lib/fluent/plugin/buffer.rb +19 -3
  8. data/lib/fluent/plugin/buffer/chunk.rb +1 -1
  9. data/lib/fluent/plugin/buffer/file_chunk.rb +3 -3
  10. data/lib/fluent/plugin/buffer/file_single_chunk.rb +2 -3
  11. data/lib/fluent/plugin/in_tail.rb +162 -131
  12. data/lib/fluent/plugin/in_unix.rb +0 -6
  13. data/lib/fluent/plugin/out_file.rb +6 -28
  14. data/lib/fluent/plugin/out_secondary_file.rb +2 -4
  15. data/lib/fluent/plugin/output.rb +1 -1
  16. data/lib/fluent/plugin/parser_multiline.rb +48 -2
  17. data/lib/fluent/plugin_helper/server.rb +5 -1
  18. data/lib/fluent/plugin_id.rb +1 -1
  19. data/lib/fluent/supervisor.rb +11 -3
  20. data/lib/fluent/version.rb +1 -1
  21. data/test/command/test_fluentd.rb +31 -2
  22. data/test/plugin/test_buf_file.rb +84 -4
  23. data/test/plugin/test_buf_file_single.rb +2 -2
  24. data/test/plugin/test_buffer.rb +18 -2
  25. data/test/plugin/test_buffer_file_chunk.rb +13 -12
  26. data/test/plugin/test_buffer_file_single_chunk.rb +1 -1
  27. data/test/plugin/test_in_tail.rb +82 -29
  28. data/test/plugin/test_out_copy.rb +3 -0
  29. data/test/plugin/test_output_as_buffered_backup.rb +48 -0
  30. data/test/plugin/test_parser_multiline.rb +11 -0
  31. data/test/plugin_helper/data/cert/generate_cert.rb +2 -2
  32. data/test/plugin_helper/data/cert/with_ca/ca-cert-key-pass.pem +26 -26
  33. data/test/plugin_helper/data/cert/with_ca/ca-cert-key.pem +25 -25
  34. data/test/plugin_helper/data/cert/with_ca/ca-cert-pass.pem +18 -18
  35. data/test/plugin_helper/data/cert/with_ca/ca-cert.pem +18 -18
  36. data/test/plugin_helper/data/cert/with_ca/cert-key-pass.pem +26 -26
  37. data/test/plugin_helper/data/cert/with_ca/cert-key.pem +25 -25
  38. data/test/plugin_helper/data/cert/with_ca/cert-pass.pem +19 -19
  39. data/test/plugin_helper/data/cert/with_ca/cert.pem +18 -18
  40. data/test/plugin_helper/data/cert/without_ca/cert-key-pass.pem +26 -26
  41. data/test/plugin_helper/data/cert/without_ca/cert-key.pem +25 -25
  42. data/test/plugin_helper/data/cert/without_ca/cert-pass.pem +17 -17
  43. data/test/plugin_helper/data/cert/without_ca/cert.pem +17 -17
  44. data/test/plugin_helper/test_http_server_helper.rb +1 -9
  45. data/test/test_logger_initializer.rb +20 -0
  46. data/test/test_plugin_id.rb +18 -0
  47. data/test/test_supervisor.rb +1 -1
  48. metadata +2 -2
@@ -900,13 +900,29 @@ class BufferTest < Test::Unit::TestCase
900
900
  es = Fluent::ArrayEventStream.new([ [event_time('2016-04-11 16:00:02 +0000'), {"message" => "x" * (128 - 22)}] ] * 45000)
901
901
  @p.write({@dm0 => es}, format: @format)
902
902
 
903
+ # metadata whose seq is 4 is created, but overwrite with original metadata(seq=0) for next use of this chunk https://github.com/fluent/fluentd/blob/9d113029d4550ce576d8825bfa9612aa3e55bff0/lib/fluent/plugin/buffer.rb#L357
903
904
  assert_equal [@dm0], @p.stage.keys
904
905
  assert_equal 5400, @p.stage[@dm0].size
905
- assert_equal [@dm0,@dm0,@dm0,@dm0,@dm0], @p.queue.map(&:metadata)
906
+ assert_equal [@dm0, @dm0, @dm0, @dm0, @dm0], @p.queue.map(&:metadata)
906
907
  assert_equal [5000, 9900, 9900, 9900, 9900], @p.queue.map(&:size) # splits: 45000 / 100 => 450 * ...
907
908
  # 9900 * 4 + 5400 == 45000
908
909
  end
909
910
 
911
+ test '#dequeue_chunk succeeds when chunk is splited' do
912
+ assert_equal [@dm0], @p.stage.keys
913
+ assert_equal [], @p.queue.map(&:metadata)
914
+
915
+ assert_equal 1_280_000, @p.chunk_limit_size
916
+
917
+ es = Fluent::ArrayEventStream.new([ [event_time('2016-04-11 16:00:02 +0000'), {"message" => "x" * (128 - 22)}] ] * 45000)
918
+ @p.write({@dm0 => es}, format: @format)
919
+ @p.enqueue_all(true)
920
+
921
+ dequeued_chunks = 6.times.map { |e| @p.dequeue_chunk } # splits: 45000 / 100 => 450 * ...
922
+ assert_equal [5000, 9900, 9900, 9900, 9900, 5400], dequeued_chunks.map(&:size)
923
+ assert_equal [@dm0, @dm0, @dm0, @dm0, @dm0, @dm0], dequeued_chunks.map(&:metadata)
924
+ end
925
+
910
926
  test '#write raises BufferChunkOverflowError if a record is biggar than chunk limit size' do
911
927
  assert_equal [@dm0], @p.stage.keys
912
928
  assert_equal [], @p.queue.map(&:metadata)
@@ -990,7 +1006,7 @@ class BufferTest < Test::Unit::TestCase
990
1006
 
991
1007
  assert_equal [@dm0], @p.stage.keys
992
1008
  assert_equal 900, @p.stage[@dm0].size
993
- assert_equal [@dm0,@dm0,@dm0,@dm0,@dm0], @p.queue.map(&:metadata)
1009
+ assert_equal [@dm0, @dm0, @dm0, @dm0, @dm0], @p.queue.map(&:metadata)
994
1010
  assert_equal [9500, 9900, 9900, 9900, 9900], @p.queue.map(&:size) # splits: 45000 / 100 => 450 * ...
995
1011
  ##### 900 + 9500 + 9900 * 4 == 5000 + 45000
996
1012
  end
@@ -21,7 +21,8 @@ class BufferFileChunkTest < Test::Unit::TestCase
21
21
  Timecop.return
22
22
  end
23
23
 
24
- Metadata = Struct.new(:timekey, :tag, :variables)
24
+ Metadata = Fluent::Plugin::Buffer::Metadata
25
+
25
26
  def gen_metadata(timekey: nil, tag: nil, variables: nil)
26
27
  Metadata.new(timekey, tag, variables)
27
28
  end
@@ -139,10 +140,10 @@ class BufferFileChunkTest < Test::Unit::TestCase
139
140
  assert_equal gen_chunk_path('b', @c.unique_id), @c.path
140
141
 
141
142
  assert File.exist?(gen_chunk_path('b', @c.unique_id))
142
- assert{ File.stat(gen_chunk_path('b', @c.unique_id)).mode.to_s(8).end_with?(@klass.const_get('FILE_PERMISSION').to_s(8)) }
143
+ assert{ File.stat(gen_chunk_path('b', @c.unique_id)).mode.to_s(8).end_with?(Fluent::DEFAULT_FILE_PERMISSION.to_s(8)) }
143
144
 
144
145
  assert File.exist?(gen_chunk_path('b', @c.unique_id) + '.meta')
145
- assert{ File.stat(gen_chunk_path('b', @c.unique_id) + '.meta').mode.to_s(8).end_with?(@klass.const_get('FILE_PERMISSION').to_s(8)) }
146
+ assert{ File.stat(gen_chunk_path('b', @c.unique_id) + '.meta').mode.to_s(8).end_with?(Fluent::DEFAULT_FILE_PERMISSION.to_s(8)) }
146
147
 
147
148
  assert_equal :unstaged, @c.state
148
149
  assert @c.empty?
@@ -360,7 +361,7 @@ class BufferFileChunkTest < Test::Unit::TestCase
360
361
  assert_equal content, File.open(@c.path, 'rb'){|f| f.read }
361
362
 
362
363
  stored_meta = {
363
- timekey: nil, tag: nil, variables: nil,
364
+ timekey: nil, tag: nil, variables: nil, seq: 0,
364
365
  id: unique_id,
365
366
  s: size,
366
367
  c: created_at.to_i,
@@ -424,7 +425,7 @@ class BufferFileChunkTest < Test::Unit::TestCase
424
425
  @c.commit
425
426
 
426
427
  expected = {
427
- timekey: nil, tag: nil, variables: nil,
428
+ timekey: nil, tag: nil, variables: nil, seq: 0,
428
429
  id: @c.unique_id,
429
430
  s: @c.size,
430
431
  c: @c.created_at.to_i,
@@ -442,7 +443,7 @@ class BufferFileChunkTest < Test::Unit::TestCase
442
443
  @c.write_metadata
443
444
 
444
445
  expected = {
445
- timekey: nil, tag: nil, variables: nil,
446
+ timekey: nil, tag: nil, variables: nil, seq: 0,
446
447
  id: @c.unique_id,
447
448
  s: @c.size,
448
449
  c: @c.created_at.to_i,
@@ -453,7 +454,7 @@ class BufferFileChunkTest < Test::Unit::TestCase
453
454
  @c.commit
454
455
 
455
456
  expected = {
456
- timekey: nil, tag: nil, variables: nil,
457
+ timekey: nil, tag: nil, variables: nil, seq: 0,
457
458
  id: @c.unique_id,
458
459
  s: @c.size,
459
460
  c: @c.created_at.to_i,
@@ -473,7 +474,7 @@ class BufferFileChunkTest < Test::Unit::TestCase
473
474
  assert_equal content, File.open(@c.path, 'rb'){|f| f.read }
474
475
 
475
476
  stored_meta = {
476
- timekey: nil, tag: nil, variables: nil,
477
+ timekey: nil, tag: nil, variables: nil, seq: 0,
477
478
  id: unique_id,
478
479
  s: size,
479
480
  c: created_at.to_i,
@@ -518,7 +519,7 @@ class BufferFileChunkTest < Test::Unit::TestCase
518
519
  end
519
520
 
520
521
  @metadata = {
521
- timekey: nil, tag: 'testing', variables: {k: "x"},
522
+ timekey: nil, tag: 'testing', variables: {k: "x"}, seq: 0,
522
523
  id: @chunk_id,
523
524
  s: 4,
524
525
  c: Time.parse('2016-04-07 17:44:00 +0900').to_i,
@@ -591,7 +592,7 @@ class BufferFileChunkTest < Test::Unit::TestCase
591
592
  @c.append([d5s])
592
593
 
593
594
  metadata = {
594
- timekey: nil, tag: 'testing', variables: {k: "x"},
595
+ timekey: nil, tag: 'testing', variables: {k: "x"}, seq: 0,
595
596
  id: @chunk_id,
596
597
  s: 4,
597
598
  c: Time.parse('2016-04-07 17:44:00 +0900').to_i,
@@ -602,7 +603,7 @@ class BufferFileChunkTest < Test::Unit::TestCase
602
603
  @c.write_metadata
603
604
 
604
605
  metadata = {
605
- timekey: nil, tag: 'testing', variables: {k: "x"},
606
+ timekey: nil, tag: 'testing', variables: {k: "x"}, seq: 0,
606
607
  id: @chunk_id,
607
608
  s: 5,
608
609
  c: Time.parse('2016-04-07 17:44:00 +0900').to_i,
@@ -671,7 +672,7 @@ class BufferFileChunkTest < Test::Unit::TestCase
671
672
  @dummy_timekey = Time.parse('2016-04-07 17:40:00 +0900').to_i
672
673
 
673
674
  @metadata = {
674
- timekey: @dummy_timekey, tag: 'testing', variables: {k: "x"},
675
+ timekey: @dummy_timekey, tag: 'testing', variables: {k: "x"}, seq: 0,
675
676
  id: @chunk_id,
676
677
  s: 4,
677
678
  c: Time.parse('2016-04-07 17:44:00 +0900').to_i,
@@ -117,7 +117,7 @@ class BufferFileSingleChunkTest < Test::Unit::TestCase
117
117
  assert_equal gen_chunk_path('b', @c.unique_id), @c.path
118
118
 
119
119
  assert File.exist?(gen_chunk_path('b', @c.unique_id))
120
- assert { File.stat(gen_chunk_path('b', @c.unique_id)).mode.to_s(8).end_with?(@klass.const_get('FILE_PERMISSION').to_s(8)) }
120
+ assert { File.stat(gen_chunk_path('b', @c.unique_id)).mode.to_s(8).end_with?(Fluent::DEFAULT_FILE_PERMISSION.to_s(8)) }
121
121
 
122
122
  assert_equal :unstaged, @c.state
123
123
  assert @c.empty?
@@ -60,6 +60,21 @@ class TailInputTest < Test::Unit::TestCase
60
60
  })
61
61
  ])
62
62
 
63
+ MULTILINE_CONFIG_WITH_NEWLINE = config_element(
64
+ "", "", {
65
+ "format" => "multiline",
66
+ "format1" => "/^s (?<message1>[^\\n]+)(\\nf (?<message2>[^\\n]+))?(\\nf (?<message3>.[^\\n]+))?/",
67
+ "format_firstline" => "/^[s]/"
68
+ })
69
+ PARSE_MULTILINE_CONFIG_WITH_NEWLINE = config_element(
70
+ "", "", {},
71
+ [config_element("parse", "", {
72
+ "@type" => "multiline",
73
+ "format1" => "/^s (?<message1>[^\\n]+)(\\nf (?<message2>[^\\n]+))?(\\nf (?<message3>.[^\\n]+))?/",
74
+ "format_firstline" => "/^[s]/"
75
+ })
76
+ ])
77
+
63
78
  def create_driver(conf = SINGLE_LINE_CONFIG, use_common_conf = true)
64
79
  config = use_common_conf ? COMMON_CONFIG + conf : conf
65
80
  Fluent::Test::Driver::Input.new(Fluent::Plugin::TailInput).configure(config)
@@ -741,6 +756,34 @@ class TailInputTest < Test::Unit::TestCase
741
756
  assert_equal({"message1" => "test8"}, events[4][2])
742
757
  end
743
758
 
759
+ data(
760
+ flat: MULTILINE_CONFIG_WITH_NEWLINE,
761
+ parse: PARSE_MULTILINE_CONFIG_WITH_NEWLINE)
762
+ def test_multiline_with_emit_unmatched_lines2(data)
763
+ config = data + config_element("", "", { "emit_unmatched_lines" => true })
764
+ File.open("#{TMP_DIR}/tail.txt", "wb") { |f| }
765
+
766
+ d = create_driver(config)
767
+ d.run(expect_emits: 0, timeout: 1) do
768
+ File.open("#{TMP_DIR}/tail.txt", "ab") { |f|
769
+ f.puts "s test0"
770
+ f.puts "f test1"
771
+ f.puts "f test2"
772
+
773
+ f.puts "f test3"
774
+
775
+ f.puts "s test4"
776
+ f.puts "f test5"
777
+ f.puts "f test6"
778
+ }
779
+ end
780
+
781
+ events = d.events
782
+ assert_equal({"message1" => "test0", "message2" => "test1", "message3" => "test2"}, events[0][2])
783
+ assert_equal({ 'unmatched_line' => "f test3" }, events[1][2])
784
+ assert_equal({"message1" => "test4", "message2" => "test5", "message3" => "test6"}, events[2][2])
785
+ end
786
+
744
787
  data(flat: MULTILINE_CONFIG,
745
788
  parse: PARSE_MULTILINE_CONFIG)
746
789
  def test_multiline_with_flush_interval(data)
@@ -1074,14 +1117,41 @@ class TailInputTest < Test::Unit::TestCase
1074
1117
  "read_from_head" => true,
1075
1118
  "refresh_interval" => 1
1076
1119
  })
1120
+
1121
+ assert_path_not_exist("#{TMP_DIR}/pos")
1077
1122
  d = create_driver(config, false)
1078
- d.run(expect_emits: 1, shutdown: false) do
1079
- File.open("#{TMP_DIR}/tail.txt", "ab") { |f| f.puts "test3\n" }
1080
- end
1081
- assert_path_exist("#{TMP_DIR}/pos/tail.pos")
1123
+ d.run
1124
+ assert_path_exist("#{TMP_DIR}/pos")
1125
+ assert_equal '755', File.stat("#{TMP_DIR}/pos").mode.to_s(8)[-3, 3]
1126
+ ensure
1082
1127
  cleanup_directory(TMP_DIR)
1128
+ end
1083
1129
 
1084
- d.instance_shutdown
1130
+ def test_pos_file_dir_creation_with_system_dir_permission
1131
+ config = config_element("", "", {
1132
+ "tag" => "tail",
1133
+ "path" => "#{TMP_DIR}/*.txt",
1134
+ "format" => "none",
1135
+ "pos_file" => "#{TMP_DIR}/pos/tail.pos",
1136
+ "read_from_head" => true,
1137
+ "refresh_interval" => 1
1138
+ })
1139
+
1140
+ assert_path_not_exist("#{TMP_DIR}/pos")
1141
+
1142
+ Fluent::SystemConfig.overwrite_system_config({ "dir_permission" => "744" }) do
1143
+ d = create_driver(config, false)
1144
+ d.run
1145
+ end
1146
+
1147
+ assert_path_exist("#{TMP_DIR}/pos")
1148
+ if Fluent.windows?
1149
+ assert_equal '755', File.stat("#{TMP_DIR}/pos").mode.to_s(8)[-3, 3]
1150
+ else
1151
+ assert_equal '744', File.stat("#{TMP_DIR}/pos").mode.to_s(8)[-3, 3]
1152
+ end
1153
+ ensure
1154
+ cleanup_directory(TMP_DIR)
1085
1155
  end
1086
1156
 
1087
1157
  def test_z_refresh_watchers
@@ -1093,35 +1163,18 @@ class TailInputTest < Test::Unit::TestCase
1093
1163
  end
1094
1164
 
1095
1165
  Timecop.freeze(2010, 1, 2, 3, 4, 5) do
1096
- flexstub(Fluent::Plugin::TailInput::TailWatcher) do |watcherclass|
1097
- EX_PATHS.each do |path|
1098
- watcherclass.should_receive(:new).with(path, EX_ROTATE_WAIT, Fluent::Plugin::TailInput::FilePositionEntry, any, true, true, true, 1000, any, any, any, any, any, any).once.and_return do
1099
- flexmock('TailWatcher') { |watcher|
1100
- watcher.should_receive(:attach).once
1101
- watcher.should_receive(:unwatched=).zero_or_more_times
1102
- watcher.should_receive(:line_buffer).zero_or_more_times
1103
- }
1104
- end
1105
- end
1106
- plugin.refresh_watchers
1166
+ EX_PATHS.each do |path|
1167
+ mock.proxy(Fluent::Plugin::TailInput::TailWatcher).new(path, anything, anything, true, 1000, anything, anything, anything, anything, false).once
1107
1168
  end
1108
- end
1109
1169
 
1110
- plugin.instance_eval do
1111
- @tails['test/plugin/data/2010/01/20100102-030405.log'].should_receive(:close).zero_or_more_times
1170
+ plugin.refresh_watchers
1112
1171
  end
1113
1172
 
1173
+ mock.proxy(plugin).detach_watcher_after_rotate_wait(plugin.instance_variable_get(:@tails)['test/plugin/data/2010/01/20100102-030405.log'])
1174
+
1114
1175
  Timecop.freeze(2010, 1, 2, 3, 4, 6) do
1115
- flexstub(Fluent::Plugin::TailInput::TailWatcher) do |watcherclass|
1116
- watcherclass.should_receive(:new).with('test/plugin/data/2010/01/20100102-030406.log', EX_ROTATE_WAIT, Fluent::Plugin::TailInput::FilePositionEntry, any, true, true, true, 1000, any, any, any, any, any, any).once.and_return do
1117
- flexmock('TailWatcher') do |watcher|
1118
- watcher.should_receive(:attach).once
1119
- watcher.should_receive(:unwatched=).zero_or_more_times
1120
- watcher.should_receive(:line_buffer).zero_or_more_times
1121
- end
1122
- end
1123
- plugin.refresh_watchers
1124
- end
1176
+ mock.proxy(Fluent::Plugin::TailInput::TailWatcher).new('test/plugin/data/2010/01/20100102-030406.log', anything, anything, true, 1000, anything, anything, anything, anything, false).once
1177
+ plugin.refresh_watchers
1125
1178
 
1126
1179
  flexstub(Fluent::Plugin::TailInput::TailWatcher) do |watcherclass|
1127
1180
  watcherclass.should_receive(:new).never
@@ -64,6 +64,9 @@ class CopyOutputTest < Test::Unit::TestCase
64
64
  ])
65
65
 
66
66
  outputs = d.instance.outputs
67
+ assert_equal 1, outputs.size
68
+ assert_equal Fluent::Plugin::TestOutput, outputs[0].class
69
+ assert_equal "c0", outputs[0].name
67
70
  assert_true d.instance.deep_copy
68
71
  assert_equal :shallow, d.instance.copy_mode
69
72
  end
@@ -232,6 +232,54 @@ class BufferedOutputBackupTest < Test::Unit::TestCase
232
232
  end
233
233
  end
234
234
 
235
+ test 'create directory' do
236
+ Fluent::SystemConfig.overwrite_system_config('root_dir' => TMP_DIR) do
237
+ id = 'backup_test_with_same_secondary'
238
+ hash = { 'flush_interval' => 1, 'flush_thread_burst_interval' => 0.1 }
239
+ chunk_id = nil
240
+ secconf = config_element('secondary', '', { '@type' => 'backup_output' })
241
+ @i.configure(config_element('ROOT', '', { '@id' => id }, [config_element('buffer', 'tag', hash), secconf]))
242
+ @i.register(:write) { |chunk|
243
+ chunk_id = chunk.unique_id;
244
+ raise Fluent::UnrecoverableError, "yay, your #write must fail"
245
+ }
246
+
247
+ flush_chunks
248
+
249
+ target = "#{TMP_DIR}/backup/worker0/#{id}/#{@i.dump_unique_id_hex(chunk_id)}.log"
250
+ target_dir = File.dirname(target)
251
+ wait_flush(target)
252
+
253
+ assert_path_exist(target_dir)
254
+ assert_equal '755', File.stat(target_dir).mode.to_s(8)[-3, 3]
255
+ end
256
+ end
257
+
258
+ test 'create directory with specific mode' do
259
+ omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
260
+
261
+ Fluent::SystemConfig.overwrite_system_config('root_dir' => TMP_DIR, 'dir_permission' => '744') do
262
+ id = 'backup_test_with_same_secondary'
263
+ hash = { 'flush_interval' => 1, 'flush_thread_burst_interval' => 0.1 }
264
+ chunk_id = nil
265
+ secconf = config_element('secondary', '', { '@type' => 'backup_output' })
266
+ @i.configure(config_element('ROOT', '', { '@id' => id }, [config_element('buffer', 'tag', hash), secconf]))
267
+ @i.register(:write) { |chunk|
268
+ chunk_id = chunk.unique_id;
269
+ raise Fluent::UnrecoverableError, "yay, your #write must fail"
270
+ }
271
+
272
+ flush_chunks
273
+
274
+ target = "#{TMP_DIR}/backup/worker0/#{id}/#{@i.dump_unique_id_hex(chunk_id)}.log"
275
+ target_dir = File.dirname(target)
276
+ wait_flush(target)
277
+
278
+ assert_path_exist(target_dir)
279
+ assert_equal '744', File.stat(target_dir).mode.to_s(8)[-3, 3]
280
+ end
281
+ end
282
+
235
283
  test 'backup chunk with different type secondary' do
236
284
  Fluent::SystemConfig.overwrite_system_config('root_dir' => TMP_DIR) do
237
285
  id = 'backup_test_with_diff_secondary'
@@ -97,4 +97,15 @@ EOS
97
97
  assert_equal text, record['time']
98
98
  }
99
99
  end
100
+
101
+ def test_parse_unmatched_lines
102
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::MultilineParser).configure(
103
+ 'format1' => '/^message (?<message_id>\d)/',
104
+ 'unmatched_lines' => true,
105
+ )
106
+ text = "message 1\nmessage a"
107
+ r = []
108
+ parser.instance.parse(text) { |_, record| r << record }
109
+ assert_equal [{ 'message_id' => '1' }, { 'unmatched_line' => 'message a'}], r
110
+ end
100
111
  end
@@ -14,7 +14,7 @@ CA_OPTION = {
14
14
  state: 'CA',
15
15
  locality: 'Mountain View',
16
16
  common_name: 'ca.testing.fluentd.org',
17
- expiration: 30 * 86400,
17
+ expiration: 30 * 86400 * 12 * 100,
18
18
  digest: :sha256,
19
19
  }
20
20
 
@@ -24,7 +24,7 @@ SERVER_OPTION = {
24
24
  state: 'CA',
25
25
  locality: 'Mountain View',
26
26
  common_name: 'server.testing.fluentd.org',
27
- expiration: 30 * 86400,
27
+ expiration: 30 * 86400 * 12 * 100,
28
28
  digest: :sha256,
29
29
  }
30
30
 
@@ -1,30 +1,30 @@
1
1
  -----BEGIN RSA PRIVATE KEY-----
2
2
  Proc-Type: 4,ENCRYPTED
3
- DEK-Info: AES-256-CBC,8C5793DC2044D52EF3249993DB56034A
3
+ DEK-Info: AES-256-CBC,A73EC2C28AEE020735AE48A88ED5D3C2
4
4
 
5
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- MWCZhwIHzd4B4k97CllHMgm2ERhp0Trp0xOYQDgexjABYHsBdju6bi81ovr7EQnQ
26
- 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
- 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
- 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
- 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
30
30
  -----END RSA PRIVATE KEY-----