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.
- checksums.yaml +4 -4
- data/.github/DISCUSSION_TEMPLATE/q-a-japanese.yml +50 -0
- data/.github/DISCUSSION_TEMPLATE/q-a.yml +47 -0
- data/.github/workflows/test-ruby-head.yml +31 -0
- data/.github/workflows/test.yml +2 -13
- data/CHANGELOG.md +33 -69
- data/README.md +3 -1
- data/Rakefile +1 -1
- data/fluentd.gemspec +9 -10
- data/lib/fluent/command/binlog_reader.rb +1 -1
- data/lib/fluent/command/fluentd.rb +1 -1
- data/lib/fluent/compat/formatter.rb +0 -6
- data/lib/fluent/config/configure_proxy.rb +2 -2
- data/lib/fluent/config/parser.rb +3 -15
- data/lib/fluent/config/types.rb +1 -1
- data/lib/fluent/config/v1_parser.rb +1 -1
- data/lib/fluent/config/yaml_parser/parser.rb +0 -4
- data/lib/fluent/configurable.rb +2 -2
- data/lib/fluent/counter/mutex_hash.rb +1 -1
- data/lib/fluent/fluent_log_event_router.rb +0 -2
- data/lib/fluent/plugin/buf_file.rb +1 -1
- data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
- data/lib/fluent/plugin/buffer/file_single_chunk.rb +2 -3
- data/lib/fluent/plugin/filter_parser.rb +26 -8
- data/lib/fluent/plugin/formatter_csv.rb +4 -18
- data/lib/fluent/plugin/in_http.rb +17 -52
- data/lib/fluent/plugin/in_tail.rb +35 -3
- data/lib/fluent/plugin/out_file.rb +0 -8
- data/lib/fluent/plugin/out_http.rb +125 -13
- data/lib/fluent/plugin/owned_by_mixin.rb +0 -1
- data/lib/fluent/plugin/parser_json.rb +34 -9
- data/lib/fluent/plugin/parser_msgpack.rb +24 -3
- data/lib/fluent/plugin_helper/metrics.rb +2 -2
- data/lib/fluent/registry.rb +6 -6
- data/lib/fluent/supervisor.rb +3 -3
- data/lib/fluent/test/output_test.rb +1 -1
- data/lib/fluent/unique_id.rb +1 -1
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +8 -38
- data/test/command/test_cat.rb +2 -2
- data/test/command/test_fluentd.rb +10 -57
- data/test/config/test_plugin_configuration.rb +6 -6
- data/test/helper.rb +7 -27
- data/test/log/test_console_adapter.rb +10 -3
- data/test/plugin/data/log_numeric/01.log +0 -0
- data/test/plugin/data/log_numeric/02.log +0 -0
- data/test/plugin/data/log_numeric/12.log +0 -0
- data/test/plugin/data/log_numeric/14.log +0 -0
- data/test/plugin/in_tail/test_io_handler.rb +14 -13
- data/test/plugin/in_tail/test_position_file.rb +7 -6
- data/test/plugin/out_forward/test_ack_handler.rb +3 -3
- data/test/plugin/out_forward/test_socket_cache.rb +3 -3
- data/test/plugin/test_buffer.rb +2 -2
- data/test/plugin/test_filter_grep.rb +1 -1
- data/test/plugin/test_in_forward.rb +1 -2
- data/test/plugin/test_in_http.rb +23 -1
- data/test/plugin/test_in_monitor_agent.rb +6 -6
- data/test/plugin/test_in_syslog.rb +18 -25
- data/test/plugin/test_in_tail.rb +153 -5
- data/test/plugin/test_in_tcp.rb +1 -1
- data/test/plugin/test_in_udp.rb +10 -16
- data/test/plugin/test_out_exec_filter.rb +7 -12
- data/test/plugin/test_out_file.rb +2 -22
- data/test/plugin/test_out_forward.rb +3 -2
- data/test/plugin/test_out_http.rb +128 -0
- data/test/plugin/test_out_stream.rb +1 -1
- data/test/plugin/test_output.rb +1 -1
- data/test/plugin/test_output_as_buffered.rb +2 -2
- data/test/plugin/test_output_as_buffered_retries.rb +2 -2
- data/test/plugin/test_owned_by.rb +0 -1
- data/test/plugin/test_parser_csv.rb +1 -1
- data/test/plugin/test_parser_json.rb +106 -31
- data/test/plugin/test_parser_msgpack.rb +127 -0
- data/test/plugin/test_storage.rb +0 -1
- data/test/plugin_helper/test_child_process.rb +4 -4
- data/test/plugin_helper/test_http_server_helper.rb +1 -1
- data/test/plugin_helper/test_server.rb +41 -64
- data/test/plugin_helper/test_socket.rb +1 -1
- data/test/test_config.rb +0 -6
- data/test/test_event_router.rb +2 -2
- data/test/test_supervisor.rb +21 -30
- data/test/test_tls.rb +1 -1
- metadata +85 -30
data/test/plugin/test_output.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
data/test/plugin/test_storage.rb
CHANGED
@@ -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 = (
|
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 +=
|
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 =
|
649
|
-
mytmpdir =
|
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
|