fluentd 1.16.8-x86-mingw32 → 1.17.0-x86-mingw32

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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.github/DISCUSSION_TEMPLATE/q-a-japanese.yml +50 -0
  3. data/.github/DISCUSSION_TEMPLATE/q-a.yml +47 -0
  4. data/.github/workflows/test-ruby-head.yml +31 -0
  5. data/.github/workflows/test.yml +2 -13
  6. data/CHANGELOG.md +33 -69
  7. data/README.md +3 -1
  8. data/Rakefile +1 -1
  9. data/fluentd.gemspec +9 -10
  10. data/lib/fluent/command/binlog_reader.rb +1 -1
  11. data/lib/fluent/command/fluentd.rb +1 -1
  12. data/lib/fluent/compat/formatter.rb +0 -6
  13. data/lib/fluent/config/configure_proxy.rb +2 -2
  14. data/lib/fluent/config/parser.rb +3 -15
  15. data/lib/fluent/config/types.rb +1 -1
  16. data/lib/fluent/config/v1_parser.rb +1 -1
  17. data/lib/fluent/config/yaml_parser/parser.rb +0 -4
  18. data/lib/fluent/configurable.rb +2 -2
  19. data/lib/fluent/counter/mutex_hash.rb +1 -1
  20. data/lib/fluent/fluent_log_event_router.rb +0 -2
  21. data/lib/fluent/plugin/buf_file.rb +1 -1
  22. data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
  23. data/lib/fluent/plugin/buffer/file_single_chunk.rb +2 -3
  24. data/lib/fluent/plugin/filter_parser.rb +26 -8
  25. data/lib/fluent/plugin/formatter_csv.rb +4 -18
  26. data/lib/fluent/plugin/in_http.rb +17 -52
  27. data/lib/fluent/plugin/in_tail.rb +35 -3
  28. data/lib/fluent/plugin/out_file.rb +0 -8
  29. data/lib/fluent/plugin/out_http.rb +125 -13
  30. data/lib/fluent/plugin/owned_by_mixin.rb +0 -1
  31. data/lib/fluent/plugin/parser_json.rb +34 -9
  32. data/lib/fluent/plugin/parser_msgpack.rb +24 -3
  33. data/lib/fluent/plugin_helper/metrics.rb +2 -2
  34. data/lib/fluent/registry.rb +6 -6
  35. data/lib/fluent/supervisor.rb +3 -3
  36. data/lib/fluent/test/output_test.rb +1 -1
  37. data/lib/fluent/unique_id.rb +1 -1
  38. data/lib/fluent/version.rb +1 -1
  39. data/lib/fluent/winsvc.rb +8 -38
  40. data/test/command/test_cat.rb +2 -2
  41. data/test/command/test_fluentd.rb +10 -57
  42. data/test/config/test_plugin_configuration.rb +6 -6
  43. data/test/helper.rb +7 -27
  44. data/test/log/test_console_adapter.rb +10 -3
  45. data/test/plugin/data/log_numeric/01.log +0 -0
  46. data/test/plugin/data/log_numeric/02.log +0 -0
  47. data/test/plugin/data/log_numeric/12.log +0 -0
  48. data/test/plugin/data/log_numeric/14.log +0 -0
  49. data/test/plugin/in_tail/test_io_handler.rb +14 -13
  50. data/test/plugin/in_tail/test_position_file.rb +7 -6
  51. data/test/plugin/out_forward/test_ack_handler.rb +3 -3
  52. data/test/plugin/out_forward/test_socket_cache.rb +3 -3
  53. data/test/plugin/test_buffer.rb +2 -2
  54. data/test/plugin/test_filter_grep.rb +1 -1
  55. data/test/plugin/test_in_forward.rb +1 -2
  56. data/test/plugin/test_in_http.rb +23 -1
  57. data/test/plugin/test_in_monitor_agent.rb +6 -6
  58. data/test/plugin/test_in_syslog.rb +18 -25
  59. data/test/plugin/test_in_tail.rb +153 -5
  60. data/test/plugin/test_in_tcp.rb +1 -1
  61. data/test/plugin/test_in_udp.rb +10 -16
  62. data/test/plugin/test_out_exec_filter.rb +7 -12
  63. data/test/plugin/test_out_file.rb +2 -22
  64. data/test/plugin/test_out_forward.rb +3 -2
  65. data/test/plugin/test_out_http.rb +128 -0
  66. data/test/plugin/test_out_stream.rb +1 -1
  67. data/test/plugin/test_output.rb +1 -1
  68. data/test/plugin/test_output_as_buffered.rb +2 -2
  69. data/test/plugin/test_output_as_buffered_retries.rb +2 -2
  70. data/test/plugin/test_owned_by.rb +0 -1
  71. data/test/plugin/test_parser_csv.rb +1 -1
  72. data/test/plugin/test_parser_json.rb +106 -31
  73. data/test/plugin/test_parser_msgpack.rb +127 -0
  74. data/test/plugin/test_storage.rb +0 -1
  75. data/test/plugin_helper/test_child_process.rb +4 -4
  76. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  77. data/test/plugin_helper/test_server.rb +41 -64
  78. data/test/plugin_helper/test_socket.rb +1 -1
  79. data/test/test_config.rb +0 -6
  80. data/test/test_event_router.rb +2 -2
  81. data/test/test_supervisor.rb +21 -30
  82. data/test/test_tls.rb +1 -1
  83. metadata +85 -30
@@ -1111,7 +1111,7 @@ class OutputTest < Test::Unit::TestCase
1111
1111
  config: config_element(
1112
1112
  "ROOT", "", {},
1113
1113
  [
1114
- config_element("buffer", "", {}),
1114
+ config_element("buffer", "", {}),
1115
1115
  config_element("secondary", "", {"@type" => "test", "name" => "test"}),
1116
1116
  ]
1117
1117
  ),
@@ -1343,7 +1343,6 @@ class BufferedOutputTest < Test::Unit::TestCase
1343
1343
  hash = {
1344
1344
  'flush_interval' => 10,
1345
1345
  'flush_thread_count' => 1,
1346
- 'flush_thread_interval' => 0.1,
1347
1346
  'flush_thread_burst_interval' => 0.1,
1348
1347
  'chunk_limit_size' => 1024,
1349
1348
  }
@@ -1446,7 +1445,7 @@ class BufferedOutputTest < Test::Unit::TestCase
1446
1445
 
1447
1446
  assert{ @i.buffer.stage.size == 3 }
1448
1447
 
1449
- # to trigger try_flush with flush_thread_interval
1448
+ # to trigger try_flush with flush_thread_burst_interval
1450
1449
  Timecop.freeze( Time.parse('2016-04-13 14:04:11 +0900') )
1451
1450
  @i.enqueue_thread_wait
1452
1451
  Timecop.freeze( Time.parse('2016-04-13 14:04:12 +0900') )
@@ -1455,6 +1454,7 @@ class BufferedOutputTest < Test::Unit::TestCase
1455
1454
  @i.enqueue_thread_wait
1456
1455
  Timecop.freeze( Time.parse('2016-04-13 14:04:14 +0900') )
1457
1456
  @i.enqueue_thread_wait
1457
+ @i.flush_thread_wakeup
1458
1458
 
1459
1459
  assert{ @i.buffer.stage.size == 0 }
1460
1460
 
@@ -941,7 +941,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
941
941
  @i.enqueue_thread_wait
942
942
 
943
943
  @i.flush_thread_wakeup
944
- waiting(4){ Thread.pass until @i.write_count > 0 && @i.num_errors > 0 }
944
+ waiting(4){ Thread.pass until @i.write_count > 0 }
945
945
  waiting(4) do
946
946
  state = @i.instance_variable_get(:@output_flush_threads).first
947
947
  state.thread.status == 'sleep'
@@ -953,7 +953,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase
953
953
  now = @i.next_flush_time
954
954
  Timecop.freeze( now )
955
955
  @i.flush_thread_wakeup
956
- waiting(4){ Thread.pass until @i.write_count > 1 && @i.num_errors > 1 }
956
+ waiting(4){ Thread.pass until @i.write_count > 1 }
957
957
  waiting(4) do
958
958
  state = @i.instance_variable_get(:@output_flush_threads).first
959
959
  state.thread.status == 'sleep'
@@ -26,7 +26,6 @@ class OwnedByMixinTest < Test::Unit::TestCase
26
26
 
27
27
  assert_equal parent.object_id, child.owner.object_id
28
28
 
29
- assert child.instance_eval{ @_plugin_id_configured }
30
29
  assert_equal 'my_parent_id', child.instance_eval{ @_plugin_id }
31
30
 
32
31
  assert_equal Fluent::Log::LEVEL_TRACE, child.log.level
@@ -164,7 +164,7 @@ class CSVParserTest < ::Test::Unit::TestCase
164
164
  text = 'a"b,"a"""c"'
165
165
  assert_raise(CSV::MalformedCSVError) {
166
166
  normal.instance.parse(text) { |t, r| }
167
- }
167
+ }
168
168
  assert_nothing_raised {
169
169
  # generate broken record
170
170
  fast.instance.parse(text) { |t, r| }
@@ -8,37 +8,6 @@ class JsonParserTest < ::Test::Unit::TestCase
8
8
  @parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::JSONParser)
9
9
  end
10
10
 
11
- sub_test_case "configure_json_parser" do
12
- data("oj", [:oj, [Oj.method(:load), Oj::ParseError]])
13
- data("json", [:json, [JSON.method(:load), JSON::ParserError]])
14
- data("yajl", [:yajl, [Yajl.method(:load), Yajl::ParseError]])
15
- def test_return_each_loader((input, expected_return))
16
- result = @parser.instance.configure_json_parser(input)
17
- assert_equal expected_return, result
18
- end
19
-
20
- def test_raise_exception_for_unknown_input
21
- assert_raise RuntimeError do
22
- @parser.instance.configure_json_parser(:unknown)
23
- end
24
- end
25
-
26
- def test_fall_back_oj_to_yajl_if_oj_not_available
27
- stub(Fluent::OjOptions).available? { false }
28
-
29
- result = @parser.instance.configure_json_parser(:oj)
30
-
31
- assert_equal [Yajl.method(:load), Yajl::ParseError], result
32
- logs = @parser.logs.collect do |log|
33
- log.gsub(/\A\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]\d{4} /, "")
34
- end
35
- assert_equal(
36
- ["[info]: Oj is not installed, and failing back to Yajl for json parser\n"],
37
- logs
38
- )
39
- end
40
- end
41
-
42
11
  data('oj' => 'oj', 'yajl' => 'yajl')
43
12
  def test_parse(data)
44
13
  @parser.configure('json_parser' => data)
@@ -166,4 +135,110 @@ class JsonParserTest < ::Test::Unit::TestCase
166
135
  end
167
136
  end
168
137
  end
138
+
139
+ sub_test_case "various record pattern" do
140
+ data("Only string", { record: '"message"', expected: [nil] }, keep: true)
141
+ data("Only string without quotation", { record: "message", expected: [nil] }, keep: true)
142
+ data("Only number", { record: "0", expected: [nil] }, keep: true)
143
+ data(
144
+ "Array of Hash",
145
+ {
146
+ record: '[{"k1": 1}, {"k2": 2}]',
147
+ expected: [{"k1" => 1}, {"k2" => 2}]
148
+ },
149
+ keep: true,
150
+ )
151
+ data(
152
+ "Array of both Hash and invalid",
153
+ {
154
+ record: '[{"k1": 1}, "string", {"k2": 2}, 0]',
155
+ expected: [{"k1" => 1}, nil, {"k2" => 2}, nil]
156
+ },
157
+ keep: true,
158
+ )
159
+ data(
160
+ "Array of all invalid",
161
+ {
162
+ record: '["string", 0, [{"k": 0}]]',
163
+ expected: [nil, nil, nil]
164
+ },
165
+ keep: true,
166
+ )
167
+
168
+ def test_oj(data)
169
+ parsed_records = []
170
+ @parser.configure("json_parser" => "oj")
171
+ @parser.instance.parse(data[:record]) { |time, record|
172
+ parsed_records.append(record)
173
+ }
174
+ assert_equal(data[:expected], parsed_records)
175
+ end
176
+
177
+ def test_yajl(data)
178
+ parsed_records = []
179
+ @parser.configure("json_parser" => "yajl")
180
+ @parser.instance.parse(data[:record]) { |time, record|
181
+ parsed_records.append(record)
182
+ }
183
+ assert_equal(data[:expected], parsed_records)
184
+ end
185
+
186
+ def test_json(json)
187
+ parsed_records = []
188
+ @parser.configure("json_parser" => "json")
189
+ @parser.instance.parse(data[:record]) { |time, record|
190
+ parsed_records.append(record)
191
+ }
192
+ assert_equal(data[:expected], parsed_records)
193
+ end
194
+ end
195
+
196
+ # This becomes NoMethodError if a non-Hash object is passed to convert_values.
197
+ # https://github.com/fluent/fluentd/issues/4100
198
+ sub_test_case "execute_convert_values with null_empty_string" do
199
+ data("Only string", { record: '"message"', expected: [nil] }, keep: true)
200
+ data(
201
+ "Hash",
202
+ {
203
+ record: '{"k1": 1, "k2": ""}',
204
+ expected: [{"k1" => 1, "k2" => nil}]
205
+ },
206
+ keep: true,
207
+ )
208
+ data(
209
+ "Array of Hash",
210
+ {
211
+ record: '[{"k1": 1}, {"k2": ""}]',
212
+ expected: [{"k1" => 1}, {"k2" => nil}]
213
+ },
214
+ keep: true,
215
+ )
216
+
217
+ def test_oj(data)
218
+ parsed_records = []
219
+ @parser.configure("json_parser" => "oj", "null_empty_string" => true)
220
+ @parser.instance.parse(data[:record]) { |time, record|
221
+ parsed_records.append(record)
222
+ }
223
+ assert_equal(data[:expected], parsed_records)
224
+ end
225
+
226
+ def test_yajl(data)
227
+ parsed_records = []
228
+ @parser.configure("json_parser" => "yajl", "null_empty_string" => true)
229
+ @parser.instance.parse(data[:record]) { |time, record|
230
+ parsed_records.append(record)
231
+ }
232
+ assert_equal(data[:expected], parsed_records)
233
+ end
234
+
235
+ def test_json(json)
236
+ parsed_records = []
237
+ @parser.configure("json_parser" => "json", "null_empty_string" => true)
238
+ @parser.instance.parse(data[:record]) { |time, record|
239
+ parsed_records.append(record)
240
+ }
241
+ assert_equal(data[:expected], parsed_records)
242
+ end
243
+ end
169
244
  end
@@ -0,0 +1,127 @@
1
+ require_relative '../helper'
2
+ require 'fluent/test/driver/parser'
3
+ require 'fluent/plugin/parser_msgpack'
4
+
5
+ class MessagePackParserTest < ::Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ end
9
+
10
+ def create_driver(conf)
11
+ Fluent::Test::Driver::Parser.new(Fluent::Plugin::MessagePackParser).configure(conf)
12
+ end
13
+
14
+ sub_test_case "simple setting" do
15
+ data(
16
+ "Normal Hash",
17
+ {
18
+ input: "\x82\xA7message\xADHello msgpack\xA3numd",
19
+ expected: [{"message" => "Hello msgpack", "num" => 100}]
20
+ },
21
+ keep: true
22
+ )
23
+ data(
24
+ "Array of multiple Hash",
25
+ {
26
+ input: "\x92\x81\xA7message\xA3foo\x81\xA7message\xA3bar",
27
+ expected: [{"message"=>"foo"}, {"message"=>"bar"}]
28
+ },
29
+ keep: true
30
+ )
31
+ data(
32
+ "String",
33
+ {
34
+ # "Hello msgpack".to_msgpack
35
+ input: "\xADHello msgpack",
36
+ expected: [nil]
37
+ },
38
+ keep: true
39
+ )
40
+ data(
41
+ "Array of String",
42
+ {
43
+ # ["foo", "bar"].to_msgpack
44
+ input: "\x92\xA3foo\xA3bar",
45
+ expected: [nil, nil]
46
+ },
47
+ keep: true
48
+ )
49
+ data(
50
+ "Array of String and Hash",
51
+ {
52
+ # ["foo", {message: "bar"}].to_msgpack
53
+ input: "\x92\xA3foo\x81\xA7message\xA3bar",
54
+ expected: [nil, {"message"=>"bar"}]
55
+ },
56
+ keep: true
57
+ )
58
+
59
+ def test_parse(data)
60
+ parsed_records = []
61
+ create_driver("").instance.parse(data[:input]) do |time, record|
62
+ parsed_records.append(record)
63
+ end
64
+ assert_equal(data[:expected], parsed_records)
65
+ end
66
+
67
+ def test_parse_io(data)
68
+ parsed_records = []
69
+ StringIO.open(data[:input]) do |io|
70
+ create_driver("").instance.parse_io(io) do |time, record|
71
+ parsed_records.append(record)
72
+ end
73
+ end
74
+ assert_equal(data[:expected], parsed_records)
75
+ end
76
+ end
77
+
78
+ # This becomes NoMethodError if a non-Hash object is passed to convert_values.
79
+ # https://github.com/fluent/fluentd/issues/4100
80
+ sub_test_case "execute_convert_values with null_empty_string" do
81
+ data(
82
+ "Normal hash",
83
+ {
84
+ # {message: "foo", empty: ""}.to_msgpack
85
+ input: "\x82\xA7message\xA3foo\xA5empty\xA0",
86
+ expected: [{"message" => "foo", "empty" => nil}]
87
+ },
88
+ keep: true
89
+ )
90
+ data(
91
+ "Array of multiple Hash",
92
+ {
93
+ # [{message: "foo", empty: ""}, {message: "bar", empty: ""}].to_msgpack
94
+ input: "\x92\x82\xA7message\xA3foo\xA5empty\xA0\x82\xA7message\xA3bar\xA5empty\xA0",
95
+ expected: [{"message"=>"foo", "empty" => nil}, {"message"=>"bar", "empty" => nil}]
96
+ },
97
+ keep: true
98
+ )
99
+ data(
100
+ "String",
101
+ {
102
+ # "Hello msgpack".to_msgpack
103
+ input: "\xADHello msgpack",
104
+ expected: [nil]
105
+ },
106
+ keep: true
107
+ )
108
+
109
+ def test_parse(data)
110
+ parsed_records = []
111
+ create_driver("null_empty_string").instance.parse(data[:input]) do |time, record|
112
+ parsed_records.append(record)
113
+ end
114
+ assert_equal(data[:expected], parsed_records)
115
+ end
116
+
117
+ def test_parse_io(data)
118
+ parsed_records = []
119
+ StringIO.open(data[:input]) do |io|
120
+ create_driver("null_empty_string").instance.parse_io(io) do |time, record|
121
+ parsed_records.append(record)
122
+ end
123
+ end
124
+ assert_equal(data[:expected], parsed_records)
125
+ end
126
+ end
127
+ end
@@ -68,7 +68,6 @@ class StorageTest < Test::Unit::TestCase
68
68
 
69
69
  assert_equal 'mytest', s.owner.system_config.process_name
70
70
  assert_equal '1', s.instance_eval{ @_plugin_id }
71
- assert_equal true, s.instance_eval{ @_plugin_id_configured }
72
71
  end
73
72
 
74
73
  test 'does NOT have features for high-performance/high-consistent storages' do
@@ -569,7 +569,7 @@ class ChildProcessTest < Test::Unit::TestCase
569
569
  unless Fluent.windows?
570
570
  test 'can specify subprocess name' do
571
571
  io = IO.popen([["cat", "caaaaaaaaaaat"], '-'])
572
- process_naming_enabled = (open("|ps opid,cmd"){|_io| _io.readlines }.count{|line| line.include?("caaaaaaaaaaat") } > 0)
572
+ process_naming_enabled = (IO.popen(["ps", "opid,cmd"]){|_io| _io.readlines }.count{|line| line.include?("caaaaaaaaaaat") } > 0)
573
573
  Process.kill(:TERM, io.pid) rescue nil
574
574
  io.close rescue nil
575
575
 
@@ -586,7 +586,7 @@ class ChildProcessTest < Test::Unit::TestCase
586
586
  m.lock
587
587
  ran = true
588
588
  pids << @d.child_process_id
589
- proc_lines += open("|ps opid,cmd"){|_io| _io.readlines }
589
+ proc_lines += IO.popen(["ps", "opid,cmd"]){|_io| _io.readlines }
590
590
  m.unlock
591
591
  readio.read
592
592
  end
@@ -645,8 +645,8 @@ class ChildProcessTest < Test::Unit::TestCase
645
645
  unless Fluent.windows?
646
646
  test 'can change working directory' do
647
647
  # check my real /tmp directory (for mac)
648
- cmd = %[|ruby -e 'Dir.chdir("/tmp"); puts Dir.pwd']
649
- mytmpdir = open(cmd){|io| io.read.chomp }
648
+ cmd = ['ruby', '-e', 'Dir.chdir("/tmp"); puts Dir.pwd']
649
+ mytmpdir = IO.popen(cmd){|io| io.read.chomp }
650
650
 
651
651
  m = Mutex.new
652
652
  str = nil
@@ -14,7 +14,7 @@ class HttpHelperTest < Test::Unit::TestCase
14
14
  CERT_CA_DIR = File.expand_path(File.dirname(__FILE__) + '/data/cert/with_ca')
15
15
 
16
16
  def setup
17
- @port = unused_port(protocol: :tcp)
17
+ @port = unused_port
18
18
  end
19
19
 
20
20
  def teardown