fluentd 1.13.3 → 1.16.5
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/ISSUE_TEMPLATE/{bug_report.yaml → bug_report.yml} +2 -0
- data/.github/ISSUE_TEMPLATE/config.yml +2 -2
- data/.github/ISSUE_TEMPLATE/{feature_request.yaml → feature_request.yml} +1 -0
- data/.github/workflows/stale-actions.yml +11 -9
- data/.github/workflows/test.yml +32 -0
- data/CHANGELOG.md +490 -10
- data/CONTRIBUTING.md +2 -2
- data/MAINTAINERS.md +7 -5
- data/README.md +3 -23
- data/Rakefile +1 -1
- data/SECURITY.md +14 -0
- data/fluentd.gemspec +7 -8
- data/lib/fluent/command/cat.rb +13 -3
- data/lib/fluent/command/ctl.rb +6 -3
- data/lib/fluent/command/fluentd.rb +73 -65
- data/lib/fluent/command/plugin_config_formatter.rb +1 -1
- data/lib/fluent/compat/output.rb +9 -6
- data/lib/fluent/config/dsl.rb +1 -1
- data/lib/fluent/config/error.rb +12 -0
- data/lib/fluent/config/literal_parser.rb +2 -2
- data/lib/fluent/config/parser.rb +1 -1
- data/lib/fluent/config/v1_parser.rb +3 -3
- data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
- data/lib/fluent/config/yaml_parser/loader.rb +108 -0
- data/lib/fluent/config/yaml_parser/parser.rb +166 -0
- data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
- data/lib/fluent/config/yaml_parser.rb +56 -0
- data/lib/fluent/config.rb +14 -1
- data/lib/fluent/counter/server.rb +1 -1
- data/lib/fluent/counter/validator.rb +3 -3
- data/lib/fluent/daemon.rb +2 -4
- data/lib/fluent/engine.rb +1 -1
- data/lib/fluent/env.rb +4 -0
- data/lib/fluent/error.rb +3 -0
- data/lib/fluent/event.rb +8 -4
- data/lib/fluent/event_router.rb +47 -2
- data/lib/fluent/file_wrapper.rb +137 -0
- data/lib/fluent/log/console_adapter.rb +66 -0
- data/lib/fluent/log.rb +44 -5
- data/lib/fluent/match.rb +1 -1
- data/lib/fluent/msgpack_factory.rb +6 -1
- data/lib/fluent/oj_options.rb +1 -2
- data/lib/fluent/plugin/bare_output.rb +49 -8
- data/lib/fluent/plugin/base.rb +26 -9
- data/lib/fluent/plugin/buf_file.rb +34 -5
- data/lib/fluent/plugin/buf_file_single.rb +32 -3
- data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
- data/lib/fluent/plugin/buffer.rb +216 -70
- data/lib/fluent/plugin/filter.rb +35 -1
- data/lib/fluent/plugin/filter_record_transformer.rb +1 -1
- data/lib/fluent/plugin/in_forward.rb +2 -2
- data/lib/fluent/plugin/in_http.rb +39 -10
- data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
- data/lib/fluent/plugin/in_sample.rb +1 -1
- data/lib/fluent/plugin/in_syslog.rb +13 -1
- data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
- data/lib/fluent/plugin/in_tail/position_file.rb +33 -33
- data/lib/fluent/plugin/in_tail.rb +216 -84
- data/lib/fluent/plugin/in_tcp.rb +47 -2
- data/lib/fluent/plugin/input.rb +39 -1
- data/lib/fluent/plugin/metrics.rb +119 -0
- data/lib/fluent/plugin/metrics_local.rb +96 -0
- data/lib/fluent/plugin/multi_output.rb +43 -6
- data/lib/fluent/plugin/out_copy.rb +1 -1
- data/lib/fluent/plugin/out_exec_filter.rb +2 -2
- data/lib/fluent/plugin/out_file.rb +20 -2
- data/lib/fluent/plugin/out_forward/ack_handler.rb +19 -4
- data/lib/fluent/plugin/out_forward/socket_cache.rb +2 -0
- data/lib/fluent/plugin/out_forward.rb +17 -9
- data/lib/fluent/plugin/out_secondary_file.rb +39 -22
- data/lib/fluent/plugin/output.rb +167 -78
- data/lib/fluent/plugin/parser.rb +3 -4
- data/lib/fluent/plugin/parser_apache2.rb +1 -1
- data/lib/fluent/plugin/parser_json.rb +1 -1
- data/lib/fluent/plugin/parser_syslog.rb +1 -1
- data/lib/fluent/plugin/storage_local.rb +3 -5
- data/lib/fluent/plugin.rb +10 -1
- data/lib/fluent/plugin_helper/child_process.rb +3 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +8 -1
- data/lib/fluent/plugin_helper/event_loop.rb +2 -2
- data/lib/fluent/plugin_helper/http_server/server.rb +2 -1
- data/lib/fluent/plugin_helper/metrics.rb +129 -0
- data/lib/fluent/plugin_helper/record_accessor.rb +1 -1
- data/lib/fluent/plugin_helper/retry_state.rb +14 -4
- data/lib/fluent/plugin_helper/server.rb +35 -6
- data/lib/fluent/plugin_helper/service_discovery.rb +2 -2
- data/lib/fluent/plugin_helper/socket.rb +13 -2
- data/lib/fluent/plugin_helper/thread.rb +3 -3
- data/lib/fluent/plugin_helper.rb +1 -0
- data/lib/fluent/plugin_id.rb +3 -2
- data/lib/fluent/registry.rb +2 -1
- data/lib/fluent/root_agent.rb +6 -0
- data/lib/fluent/rpc.rb +4 -3
- data/lib/fluent/supervisor.rb +283 -259
- data/lib/fluent/system_config.rb +13 -3
- data/lib/fluent/test/driver/base.rb +11 -5
- data/lib/fluent/test/driver/filter.rb +4 -0
- data/lib/fluent/test/startup_shutdown.rb +6 -8
- data/lib/fluent/time.rb +21 -20
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/win32api.rb +38 -0
- data/lib/fluent/winsvc.rb +5 -8
- data/templates/new_gem/test/helper.rb.erb +0 -1
- data/test/command/test_cat.rb +31 -2
- data/test/command/test_ctl.rb +1 -2
- data/test/command/test_fluentd.rb +209 -24
- data/test/command/test_plugin_config_formatter.rb +0 -1
- data/test/compat/test_parser.rb +6 -6
- data/test/config/test_system_config.rb +13 -11
- data/test/config/test_types.rb +1 -1
- data/test/log/test_console_adapter.rb +110 -0
- data/test/plugin/in_tail/test_io_handler.rb +26 -8
- data/test/plugin/in_tail/test_position_file.rb +48 -59
- data/test/plugin/out_forward/test_ack_handler.rb +39 -0
- data/test/plugin/out_forward/test_socket_cache.rb +26 -1
- data/test/plugin/test_bare_output.rb +14 -1
- data/test/plugin/test_base.rb +133 -1
- data/test/plugin/test_buf_file.rb +62 -23
- data/test/plugin/test_buf_file_single.rb +65 -0
- data/test/plugin/test_buffer.rb +267 -3
- data/test/plugin/test_buffer_chunk.rb +11 -0
- data/test/plugin/test_filter.rb +12 -1
- data/test/plugin/test_filter_parser.rb +1 -1
- data/test/plugin/test_filter_stdout.rb +2 -2
- data/test/plugin/test_in_forward.rb +9 -11
- data/test/plugin/test_in_http.rb +65 -3
- data/test/plugin/test_in_monitor_agent.rb +216 -11
- data/test/plugin/test_in_object_space.rb +9 -3
- data/test/plugin/test_in_syslog.rb +35 -0
- data/test/plugin/test_in_tail.rb +1393 -385
- data/test/plugin/test_in_tcp.rb +87 -2
- data/test/plugin/test_in_udp.rb +28 -0
- data/test/plugin/test_in_unix.rb +2 -2
- data/test/plugin/test_input.rb +12 -1
- data/test/plugin/test_metrics.rb +294 -0
- data/test/plugin/test_metrics_local.rb +96 -0
- data/test/plugin/test_multi_output.rb +25 -1
- data/test/plugin/test_out_exec.rb +6 -4
- data/test/plugin/test_out_exec_filter.rb +6 -2
- data/test/plugin/test_out_file.rb +34 -17
- data/test/plugin/test_out_forward.rb +78 -77
- data/test/plugin/test_out_http.rb +1 -0
- data/test/plugin/test_out_stdout.rb +2 -2
- data/test/plugin/test_output.rb +297 -12
- data/test/plugin/test_output_as_buffered.rb +44 -44
- data/test/plugin/test_output_as_buffered_compress.rb +32 -18
- data/test/plugin/test_output_as_buffered_retries.rb +54 -7
- data/test/plugin/test_output_as_buffered_secondary.rb +4 -4
- data/test/plugin/test_parser_regexp.rb +1 -6
- data/test/plugin/test_parser_syslog.rb +1 -1
- data/test/plugin_helper/test_cert_option.rb +1 -1
- data/test/plugin_helper/test_child_process.rb +38 -16
- data/test/plugin_helper/test_event_emitter.rb +29 -0
- data/test/plugin_helper/test_http_server_helper.rb +1 -1
- data/test/plugin_helper/test_metrics.rb +137 -0
- data/test/plugin_helper/test_retry_state.rb +602 -38
- data/test/plugin_helper/test_server.rb +78 -6
- data/test/plugin_helper/test_timer.rb +2 -2
- data/test/test_config.rb +191 -24
- data/test/test_event_router.rb +17 -0
- data/test/test_file_wrapper.rb +53 -0
- data/test/test_formatter.rb +24 -21
- data/test/test_log.rb +122 -40
- data/test/test_msgpack_factory.rb +32 -0
- data/test/test_plugin_classes.rb +102 -0
- data/test/test_root_agent.rb +30 -1
- data/test/test_supervisor.rb +477 -257
- data/test/test_time_parser.rb +22 -0
- metadata +55 -34
- data/.drone.yml +0 -35
- data/.github/workflows/issue-auto-closer.yml +0 -12
- data/.github/workflows/linux-test.yaml +0 -36
- data/.github/workflows/macos-test.yaml +0 -30
- data/.github/workflows/windows-test.yaml +0 -46
- data/.gitlab-ci.yml +0 -103
- data/lib/fluent/plugin/file_wrapper.rb +0 -187
- data/test/plugin/test_file_wrapper.rb +0 -126
- data/test/test_logger_initializer.rb +0 -46
data/test/plugin/test_in_tcp.rb
CHANGED
|
@@ -156,6 +156,19 @@ class TcpInputTest < Test::Unit::TestCase
|
|
|
156
156
|
assert_equal hostname, event[2]['host']
|
|
157
157
|
end
|
|
158
158
|
|
|
159
|
+
test "send_keepalive_packet_can_be_enabled" do
|
|
160
|
+
d = create_driver(base_config + %!
|
|
161
|
+
format none
|
|
162
|
+
send_keepalive_packet true
|
|
163
|
+
!)
|
|
164
|
+
assert_true d.instance.send_keepalive_packet
|
|
165
|
+
|
|
166
|
+
d = create_driver(base_config + %!
|
|
167
|
+
format none
|
|
168
|
+
!)
|
|
169
|
+
assert_false d.instance.send_keepalive_packet
|
|
170
|
+
end
|
|
171
|
+
|
|
159
172
|
test 'source_address_key' do
|
|
160
173
|
d = create_driver(base_config + %!
|
|
161
174
|
format none
|
|
@@ -205,13 +218,13 @@ class TcpInputTest < Test::Unit::TestCase
|
|
|
205
218
|
</client>
|
|
206
219
|
</security>
|
|
207
220
|
!)
|
|
208
|
-
d.run(
|
|
221
|
+
d.run(expect_records: 1, timeout: 2) do
|
|
209
222
|
create_tcp_socket('127.0.0.1', @port) do |sock|
|
|
210
223
|
sock.send("hello\n", 0)
|
|
211
224
|
end
|
|
212
225
|
end
|
|
213
226
|
|
|
214
|
-
assert_equal 1, d.
|
|
227
|
+
assert_equal 1, d.logs.count { |l| l =~ /anonymous client/ }
|
|
215
228
|
assert_equal 0, d.events.size
|
|
216
229
|
end
|
|
217
230
|
end
|
|
@@ -240,4 +253,76 @@ class TcpInputTest < Test::Unit::TestCase
|
|
|
240
253
|
assert_equal 'hello', event[2]['msg']
|
|
241
254
|
end
|
|
242
255
|
end
|
|
256
|
+
|
|
257
|
+
sub_test_case "message_length_limit" do
|
|
258
|
+
data("batch_emit", { extract: "" }, keep: true)
|
|
259
|
+
data("single_emit", { extract: "<extract>\ntag_key tag\n</extract>\n" }, keep: true)
|
|
260
|
+
test "drop records exceeding limit" do |data|
|
|
261
|
+
message_length_limit = 10
|
|
262
|
+
d = create_driver(base_config + %!
|
|
263
|
+
message_length_limit #{message_length_limit}
|
|
264
|
+
<parse>
|
|
265
|
+
@type none
|
|
266
|
+
</parse>
|
|
267
|
+
#{data[:extract]}
|
|
268
|
+
!)
|
|
269
|
+
d.run(expect_records: 2, timeout: 10) do
|
|
270
|
+
create_tcp_socket('127.0.0.1', @port) do |sock|
|
|
271
|
+
sock.send("a" * message_length_limit + "\n", 0)
|
|
272
|
+
sock.send("b" * (message_length_limit + 1) + "\n", 0)
|
|
273
|
+
sock.send("c" * (message_length_limit - 1) + "\n", 0)
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
expected_records = [
|
|
278
|
+
"a" * message_length_limit,
|
|
279
|
+
"c" * (message_length_limit - 1)
|
|
280
|
+
]
|
|
281
|
+
actual_records = d.events.collect do |event|
|
|
282
|
+
event[2]["message"]
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
assert_equal expected_records, actual_records
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
test "clear buffer and discard the subsequent data until the next delimiter" do |data|
|
|
289
|
+
message_length_limit = 12
|
|
290
|
+
d = create_driver(base_config + %!
|
|
291
|
+
message_length_limit #{message_length_limit}
|
|
292
|
+
delimiter ";"
|
|
293
|
+
<parse>
|
|
294
|
+
@type json
|
|
295
|
+
</parse>
|
|
296
|
+
#{data[:extract]}
|
|
297
|
+
!)
|
|
298
|
+
d.run(expect_records: 1, timeout: 10) do
|
|
299
|
+
create_tcp_socket('127.0.0.1', @port) do |sock|
|
|
300
|
+
sock.send('{"message":', 0)
|
|
301
|
+
sock.send('"hello', 0)
|
|
302
|
+
sleep 1 # To make the server read data and clear the buffer here.
|
|
303
|
+
sock.send('world!"};', 0) # This subsequent data must be discarded so that a parsing failure doesn't occur.
|
|
304
|
+
sock.send('{"k":"v"};', 0) # This will succeed to parse.
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
logs = d.logs.collect do |log|
|
|
309
|
+
log.gsub(/\A\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]\d{4} /, "")
|
|
310
|
+
end
|
|
311
|
+
actual_records = d.events.collect do |event|
|
|
312
|
+
event[2]
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
assert_equal(
|
|
316
|
+
{
|
|
317
|
+
# Asserting that '[warn]: pattern not matched message="world!\"}"' warning does not occur.
|
|
318
|
+
logs: ['[info]: The buffer size exceeds \'message_length_limit\', cleared: limit=12 size=17 head="{\"message\":\"hello"' + "\n"],
|
|
319
|
+
records: [{"k" => "v"}],
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
logs: logs[1..],
|
|
323
|
+
records: actual_records,
|
|
324
|
+
}
|
|
325
|
+
)
|
|
326
|
+
end
|
|
327
|
+
end
|
|
243
328
|
end
|
data/test/plugin/test_in_udp.rb
CHANGED
|
@@ -265,4 +265,32 @@ class UdpInputTest < Test::Unit::TestCase
|
|
|
265
265
|
end
|
|
266
266
|
end
|
|
267
267
|
end
|
|
268
|
+
|
|
269
|
+
test 'message_length_limit' do
|
|
270
|
+
message_length_limit = 32
|
|
271
|
+
d = create_driver(base_config + %!
|
|
272
|
+
format none
|
|
273
|
+
message_length_limit #{message_length_limit}
|
|
274
|
+
!)
|
|
275
|
+
d.run(expect_records: 3) do
|
|
276
|
+
create_udp_socket('127.0.0.1', @port) do |u|
|
|
277
|
+
3.times do |i|
|
|
278
|
+
u.send("#{i}" * 40 + "\n", 0)
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
if Fluent.windows?
|
|
284
|
+
expected_records = []
|
|
285
|
+
else
|
|
286
|
+
expected_records = 3.times.collect do |i|
|
|
287
|
+
"#{i}" * message_length_limit
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
actual_records = d.events.collect do |event|
|
|
291
|
+
event[2]["message"]
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
assert_equal expected_records, actual_records
|
|
295
|
+
end
|
|
268
296
|
end
|
data/test/plugin/test_in_unix.rb
CHANGED
|
@@ -174,8 +174,8 @@ class UnixInputTest < Test::Unit::TestCase
|
|
|
174
174
|
assert_equal 0, @d.events.size
|
|
175
175
|
|
|
176
176
|
logs = @d.instance.log.logs
|
|
177
|
-
assert_equal 1, logs.
|
|
177
|
+
assert_equal 1, logs.count { |line|
|
|
178
178
|
line =~ / \[warn\]: incoming data is broken: msg=#{data.inspect}/
|
|
179
|
-
}
|
|
179
|
+
}, "should not accept broken chunk"
|
|
180
180
|
end
|
|
181
181
|
end unless Fluent.windows?
|
data/test/plugin/test_input.rb
CHANGED
|
@@ -73,7 +73,7 @@ class InputTest < Test::Unit::TestCase
|
|
|
73
73
|
|
|
74
74
|
@p.configure(config_element('ROOT', '', {'@log_level' => 'debug'}))
|
|
75
75
|
|
|
76
|
-
assert
|
|
76
|
+
assert(@p.log.object_id != original_logger.object_id)
|
|
77
77
|
assert_equal Fluent::Log::LEVEL_DEBUG, @p.log.level
|
|
78
78
|
end
|
|
79
79
|
|
|
@@ -85,6 +85,17 @@ class InputTest < Test::Unit::TestCase
|
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
+
test 'can use metrics plugins and fallback methods' do
|
|
89
|
+
@p.configure(config_element('ROOT', '', {'@log_level' => 'debug'}))
|
|
90
|
+
|
|
91
|
+
%w[emit_size_metrics emit_records_metrics].each do |metric_name|
|
|
92
|
+
assert_true @p.instance_variable_get(:"@#{metric_name}").is_a?(Fluent::Plugin::Metrics)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
assert_equal 0, @p.emit_size
|
|
96
|
+
assert_equal 0, @p.emit_records
|
|
97
|
+
end
|
|
98
|
+
|
|
88
99
|
test 'are not available with multi workers configuration in default' do
|
|
89
100
|
assert_false @p.multi_workers_ready?
|
|
90
101
|
end
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
require_relative '../helper'
|
|
2
|
+
require 'fluent/plugin/metrics'
|
|
3
|
+
require 'fluent/plugin/base'
|
|
4
|
+
require 'fluent/system_config'
|
|
5
|
+
|
|
6
|
+
class BareMetrics < Fluent::Plugin::Metrics
|
|
7
|
+
Fluent::Plugin.register_metrics('bare', self)
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
# Just override for tests.
|
|
12
|
+
def has_methods_for_counter?
|
|
13
|
+
false
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class BasicCounterMetrics < Fluent::Plugin::Metrics
|
|
18
|
+
Fluent::Plugin.register_metrics('example', self)
|
|
19
|
+
|
|
20
|
+
attr_reader :data
|
|
21
|
+
|
|
22
|
+
def initialize
|
|
23
|
+
super
|
|
24
|
+
@data = 0
|
|
25
|
+
end
|
|
26
|
+
def get
|
|
27
|
+
@data
|
|
28
|
+
end
|
|
29
|
+
def inc
|
|
30
|
+
@data +=1
|
|
31
|
+
end
|
|
32
|
+
def add(value)
|
|
33
|
+
@data += value
|
|
34
|
+
end
|
|
35
|
+
def set(value)
|
|
36
|
+
@data = value
|
|
37
|
+
end
|
|
38
|
+
def close
|
|
39
|
+
@data = 0
|
|
40
|
+
super
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class AliasedCounterMetrics < Fluent::Plugin::Metrics
|
|
45
|
+
Fluent::Plugin.register_metrics('example', self)
|
|
46
|
+
|
|
47
|
+
attr_reader :data
|
|
48
|
+
|
|
49
|
+
def initialize
|
|
50
|
+
super
|
|
51
|
+
@data = 0
|
|
52
|
+
end
|
|
53
|
+
def configure(conf)
|
|
54
|
+
super
|
|
55
|
+
class << self
|
|
56
|
+
alias_method :set, :set_counter
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
def get
|
|
60
|
+
@data
|
|
61
|
+
end
|
|
62
|
+
def inc
|
|
63
|
+
@data +=1
|
|
64
|
+
end
|
|
65
|
+
def add(value)
|
|
66
|
+
@data += value
|
|
67
|
+
end
|
|
68
|
+
def set_counter(value)
|
|
69
|
+
@data = value
|
|
70
|
+
end
|
|
71
|
+
def close
|
|
72
|
+
@data = 0
|
|
73
|
+
super
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
class BasicGaugeMetrics < Fluent::Plugin::Metrics
|
|
78
|
+
Fluent::Plugin.register_metrics('example', self)
|
|
79
|
+
|
|
80
|
+
attr_reader :data
|
|
81
|
+
|
|
82
|
+
def initialize
|
|
83
|
+
super
|
|
84
|
+
@data = 0
|
|
85
|
+
end
|
|
86
|
+
def get
|
|
87
|
+
@data
|
|
88
|
+
end
|
|
89
|
+
def inc
|
|
90
|
+
@data +=1
|
|
91
|
+
end
|
|
92
|
+
def dec
|
|
93
|
+
@data -=1
|
|
94
|
+
end
|
|
95
|
+
def add(value)
|
|
96
|
+
@data += value
|
|
97
|
+
end
|
|
98
|
+
def sub(value)
|
|
99
|
+
@data -= value
|
|
100
|
+
end
|
|
101
|
+
def set(value)
|
|
102
|
+
@data = value
|
|
103
|
+
end
|
|
104
|
+
def close
|
|
105
|
+
@data = 0
|
|
106
|
+
super
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
class AliasedGaugeMetrics < Fluent::Plugin::Metrics
|
|
111
|
+
Fluent::Plugin.register_metrics('example', self)
|
|
112
|
+
|
|
113
|
+
attr_reader :data
|
|
114
|
+
|
|
115
|
+
def initialize
|
|
116
|
+
super
|
|
117
|
+
@data = 0
|
|
118
|
+
end
|
|
119
|
+
def configure(conf)
|
|
120
|
+
super
|
|
121
|
+
class << self
|
|
122
|
+
alias_method :dec, :dec_gauge
|
|
123
|
+
alias_method :set, :set_gauge
|
|
124
|
+
alias_method :sub, :sub_gauge
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
def get
|
|
128
|
+
@data
|
|
129
|
+
end
|
|
130
|
+
def inc
|
|
131
|
+
@data +=1
|
|
132
|
+
end
|
|
133
|
+
def dec_gauge
|
|
134
|
+
@data -=1
|
|
135
|
+
end
|
|
136
|
+
def add(value)
|
|
137
|
+
@data += value
|
|
138
|
+
end
|
|
139
|
+
def sub_gauge(value)
|
|
140
|
+
@data -= value
|
|
141
|
+
end
|
|
142
|
+
def set_gauge(value)
|
|
143
|
+
@data = value
|
|
144
|
+
end
|
|
145
|
+
def close
|
|
146
|
+
@data = 0
|
|
147
|
+
super
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
class StorageTest < Test::Unit::TestCase
|
|
152
|
+
sub_test_case 'BareMetrics' do
|
|
153
|
+
setup do
|
|
154
|
+
@m = BareMetrics.new
|
|
155
|
+
@m.configure(config_element())
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
test 'is configured with plugin information and system config' do
|
|
159
|
+
m = BareMetrics.new
|
|
160
|
+
m.configure(config_element('metrics', '', {}))
|
|
161
|
+
|
|
162
|
+
assert_false m.use_gauge_metric
|
|
163
|
+
assert_false m.has_methods_for_counter
|
|
164
|
+
assert_false m.has_methods_for_gauge
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
test 'all bare operations are not defined yet' do
|
|
168
|
+
assert_raise NotImplementedError do
|
|
169
|
+
@m.get
|
|
170
|
+
end
|
|
171
|
+
assert_raise NotImplementedError do
|
|
172
|
+
@m.inc
|
|
173
|
+
end
|
|
174
|
+
assert_raise NotImplementedError do
|
|
175
|
+
@m.dec
|
|
176
|
+
end
|
|
177
|
+
assert_raise NotImplementedError do
|
|
178
|
+
@m.add(10)
|
|
179
|
+
end
|
|
180
|
+
assert_raise NotImplementedError do
|
|
181
|
+
@m.sub(11)
|
|
182
|
+
end
|
|
183
|
+
assert_raise NotImplementedError do
|
|
184
|
+
@m.set(123)
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
sub_test_case 'BasicCounterMetric' do
|
|
190
|
+
setup do
|
|
191
|
+
@m = BasicCounterMetrics.new
|
|
192
|
+
@m.configure(config_element('metrics', '', {'@id' => '1'}))
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
test 'all basic counter operations work well' do
|
|
196
|
+
assert_true @m.has_methods_for_counter
|
|
197
|
+
assert_false @m.has_methods_for_gauge
|
|
198
|
+
|
|
199
|
+
assert_equal 0, @m.get
|
|
200
|
+
assert_equal 1, @m.inc
|
|
201
|
+
|
|
202
|
+
@m.add(20)
|
|
203
|
+
assert_equal 21, @m.get
|
|
204
|
+
assert_raise NotImplementedError do
|
|
205
|
+
@m.dec
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
@m.set(100)
|
|
209
|
+
assert_equal 100, @m.get
|
|
210
|
+
assert_raise NotImplementedError do
|
|
211
|
+
@m.sub(11)
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
sub_test_case 'AliasedCounterMetric' do
|
|
217
|
+
setup do
|
|
218
|
+
@m = AliasedCounterMetrics.new
|
|
219
|
+
@m.configure(config_element('metrics', '', {}))
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
test 'all aliased counter operations work well' do
|
|
223
|
+
assert_true @m.has_methods_for_counter
|
|
224
|
+
assert_false @m.has_methods_for_gauge
|
|
225
|
+
|
|
226
|
+
assert_equal 0, @m.get
|
|
227
|
+
assert_equal 1, @m.inc
|
|
228
|
+
|
|
229
|
+
@m.add(20)
|
|
230
|
+
assert_equal 21, @m.get
|
|
231
|
+
assert_raise NotImplementedError do
|
|
232
|
+
@m.dec
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
@m.set(100)
|
|
236
|
+
assert_equal 100, @m.get
|
|
237
|
+
assert_raise NotImplementedError do
|
|
238
|
+
@m.sub(11)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
sub_test_case 'BasicGaugeMetric' do
|
|
244
|
+
setup do
|
|
245
|
+
@m = BasicGaugeMetrics.new
|
|
246
|
+
@m.use_gauge_metric = true
|
|
247
|
+
@m.configure(config_element('metrics', '', {}))
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
test 'all basic gauge operations work well' do
|
|
251
|
+
assert_false @m.has_methods_for_counter
|
|
252
|
+
assert_true @m.has_methods_for_gauge
|
|
253
|
+
|
|
254
|
+
assert_equal 0, @m.get
|
|
255
|
+
assert_equal 1, @m.inc
|
|
256
|
+
|
|
257
|
+
@m.add(20)
|
|
258
|
+
assert_equal 21, @m.get
|
|
259
|
+
@m.dec
|
|
260
|
+
assert_equal 20, @m.get
|
|
261
|
+
|
|
262
|
+
@m.set(100)
|
|
263
|
+
assert_equal 100, @m.get
|
|
264
|
+
@m.sub(11)
|
|
265
|
+
assert_equal 89, @m.get
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
sub_test_case 'AliasedGaugeMetric' do
|
|
270
|
+
setup do
|
|
271
|
+
@m = AliasedGaugeMetrics.new
|
|
272
|
+
@m.use_gauge_metric = true
|
|
273
|
+
@m.configure(config_element('metrics', '', {}))
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
test 'all aliased gauge operations work well' do
|
|
277
|
+
assert_false @m.has_methods_for_counter
|
|
278
|
+
assert_true @m.has_methods_for_gauge
|
|
279
|
+
|
|
280
|
+
assert_equal 0, @m.get
|
|
281
|
+
assert_equal 1, @m.inc
|
|
282
|
+
|
|
283
|
+
@m.add(20)
|
|
284
|
+
assert_equal 21, @m.get
|
|
285
|
+
@m.dec
|
|
286
|
+
assert_equal 20, @m.get
|
|
287
|
+
|
|
288
|
+
@m.set(100)
|
|
289
|
+
assert_equal 100, @m.get
|
|
290
|
+
@m.sub(11)
|
|
291
|
+
assert_equal 89, @m.get
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require_relative '../helper'
|
|
2
|
+
require 'fluent/plugin/metrics_local'
|
|
3
|
+
require 'fluent/system_config'
|
|
4
|
+
|
|
5
|
+
class LocalMetricsTest < ::Test::Unit::TestCase
|
|
6
|
+
sub_test_case 'configure' do
|
|
7
|
+
test "configured for counter mode" do
|
|
8
|
+
m = Fluent::Plugin::LocalMetrics.new
|
|
9
|
+
m.configure(config_element('metrics', '', {"labels" => {test: "test-unit", language: "Ruby"}}))
|
|
10
|
+
|
|
11
|
+
assert_false m.use_gauge_metric
|
|
12
|
+
assert_equal({agent: "Fluentd", hostname: "#{Socket.gethostname}"}, m.default_labels)
|
|
13
|
+
assert_equal({test: "test-unit", language: "Ruby"}, m.labels)
|
|
14
|
+
assert_true m.has_methods_for_counter
|
|
15
|
+
assert_false m.has_methods_for_gauge
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test "configured for gauge mode" do
|
|
19
|
+
m = Fluent::Plugin::LocalMetrics.new
|
|
20
|
+
m.use_gauge_metric = true
|
|
21
|
+
m.configure(config_element('metrics', '', {"labels" => {test: "test-unit", language: "Ruby"}}))
|
|
22
|
+
|
|
23
|
+
assert_true m.use_gauge_metric
|
|
24
|
+
assert_equal({agent: "Fluentd", hostname: "#{Socket.gethostname}"}, m.default_labels)
|
|
25
|
+
assert_equal({test: "test-unit", language: "Ruby"}, m.labels)
|
|
26
|
+
assert_false m.has_methods_for_counter
|
|
27
|
+
assert_true m.has_methods_for_gauge
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
sub_test_case 'LocalMetric' do
|
|
32
|
+
sub_test_case "counter" do
|
|
33
|
+
setup do
|
|
34
|
+
@m = Fluent::Plugin::LocalMetrics.new
|
|
35
|
+
@m.configure(config_element('metrics', '', {}))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test '#configure' do
|
|
39
|
+
assert_true @m.has_methods_for_counter
|
|
40
|
+
assert_false @m.has_methods_for_gauge
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test 'all local counter operations work well' do
|
|
44
|
+
assert_equal 0, @m.get
|
|
45
|
+
assert_equal 1, @m.inc
|
|
46
|
+
|
|
47
|
+
@m.add(20)
|
|
48
|
+
assert_equal 21, @m.get
|
|
49
|
+
assert_raise NotImplementedError do
|
|
50
|
+
@m.dec
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
@m.set(100)
|
|
54
|
+
assert_equal 100, @m.get
|
|
55
|
+
|
|
56
|
+
@m.set(10)
|
|
57
|
+
assert_equal 100, @m.get # On counter, value should be overwritten bigger than stored one.
|
|
58
|
+
assert_raise NotImplementedError do
|
|
59
|
+
@m.sub(11)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
sub_test_case "gauge" do
|
|
65
|
+
setup do
|
|
66
|
+
@m = Fluent::Plugin::LocalMetrics.new
|
|
67
|
+
@m.use_gauge_metric = true
|
|
68
|
+
@m.configure(config_element('metrics', '', {}))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
test '#configure' do
|
|
72
|
+
assert_false @m.has_methods_for_counter
|
|
73
|
+
assert_true @m.has_methods_for_gauge
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
test 'all local gauge operations work well' do
|
|
77
|
+
assert_equal 0, @m.get
|
|
78
|
+
assert_equal 1, @m.inc
|
|
79
|
+
|
|
80
|
+
@m.add(20)
|
|
81
|
+
assert_equal 21, @m.get
|
|
82
|
+
@m.dec
|
|
83
|
+
assert_equal 20, @m.get
|
|
84
|
+
|
|
85
|
+
@m.set(100)
|
|
86
|
+
assert_equal 100, @m.get
|
|
87
|
+
|
|
88
|
+
@m.sub(11)
|
|
89
|
+
assert_equal 89, @m.get
|
|
90
|
+
|
|
91
|
+
@m.set(10)
|
|
92
|
+
assert_equal 10, @m.get # On gauge, value always should be overwritten.
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -146,8 +146,11 @@ class MultiOutputTest < Test::Unit::TestCase
|
|
|
146
146
|
@i.configure(conf)
|
|
147
147
|
assert_equal 4, @i.outputs.size
|
|
148
148
|
|
|
149
|
+
log_size_for_multi_output_itself = 4
|
|
150
|
+
log_size_for_metrics_plugin_helper = 4
|
|
151
|
+
expected_warn_log_size = log_size_for_multi_output_itself + log_size_for_metrics_plugin_helper
|
|
149
152
|
logs = @i.log.out.logs
|
|
150
|
-
assert{ logs.
|
|
153
|
+
assert{ logs.count{|log| log.include?('[warn]') && log.include?("'type' is deprecated parameter name. use '@type' instead.") } == expected_warn_log_size }
|
|
151
154
|
end
|
|
152
155
|
|
|
153
156
|
test '#emit_events calls #process always' do
|
|
@@ -176,5 +179,26 @@ class MultiOutputTest < Test::Unit::TestCase
|
|
|
176
179
|
|
|
177
180
|
assert_equal 2, @i.events.size
|
|
178
181
|
end
|
|
182
|
+
|
|
183
|
+
test 'can use metrics plugins and fallback methods' do
|
|
184
|
+
conf = config_element('ROOT', '', { '@type' => 'dummy_test_multi_output' },
|
|
185
|
+
[
|
|
186
|
+
config_element('store', '', { 'type' => 'dummy_test_multi_output_1' }),
|
|
187
|
+
config_element('store', '', { 'type' => 'dummy_test_multi_output_2' }),
|
|
188
|
+
config_element('store', '', { 'type' => 'dummy_test_multi_output_3' }),
|
|
189
|
+
config_element('store', '', { 'type' => 'dummy_test_multi_output_4' }),
|
|
190
|
+
]
|
|
191
|
+
)
|
|
192
|
+
@i.configure(conf)
|
|
193
|
+
|
|
194
|
+
%w[num_errors_metrics emit_count_metrics emit_size_metrics emit_records_metrics].each do |metric_name|
|
|
195
|
+
assert_true @i.instance_variable_get(:"@#{metric_name}").is_a?(Fluent::Plugin::Metrics)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
assert_equal 0, @i.num_errors
|
|
199
|
+
assert_equal 0, @i.emit_count
|
|
200
|
+
assert_equal 0, @i.emit_size
|
|
201
|
+
assert_equal 0, @i.emit_records
|
|
202
|
+
end
|
|
179
203
|
end
|
|
180
204
|
end
|
|
@@ -243,7 +243,7 @@ class ExecOutputTest < Test::Unit::TestCase
|
|
|
243
243
|
sub_test_case 'when executed process dies unexpectedly' do
|
|
244
244
|
setup do
|
|
245
245
|
@gen_config = ->(num){ <<EOC
|
|
246
|
-
command ruby -e "ARGV.first.to_i == 0 ? open(ARGV[1]){|f| STDOUT.write
|
|
246
|
+
command ruby -e "ARGV.first.to_i == 0 ? open(ARGV[1]){|f| STDOUT.write(f.read); STDOUT.flush} : (sleep 1 ; exit ARGV.first.to_i)" #{num} >#{TMP_DIR}/fail_out
|
|
247
247
|
<inject>
|
|
248
248
|
tag_key tag
|
|
249
249
|
time_key time
|
|
@@ -265,7 +265,7 @@ EOC
|
|
|
265
265
|
expect_path = "#{TMP_DIR}/fail_out"
|
|
266
266
|
|
|
267
267
|
d.end_if{ File.exist?(expect_path) }
|
|
268
|
-
d.run(default_tag: 'test', flush: true, wait_flush_completion:
|
|
268
|
+
d.run(default_tag: 'test', flush: true, wait_flush_completion: true, shutdown: false) do
|
|
269
269
|
d.feed(time, records[0])
|
|
270
270
|
d.feed(time, records[1])
|
|
271
271
|
end
|
|
@@ -281,7 +281,8 @@ EOC
|
|
|
281
281
|
assert{ d.instance.buffer.queue.empty? }
|
|
282
282
|
assert{ d.instance.dequeued_chunks.empty? }
|
|
283
283
|
|
|
284
|
-
|
|
284
|
+
ensure
|
|
285
|
+
d.instance_shutdown if d && d.instance
|
|
285
286
|
end
|
|
286
287
|
|
|
287
288
|
test 'flushed chunk will be taken back after child process unexpectedly exits' do
|
|
@@ -304,7 +305,8 @@ EOC
|
|
|
304
305
|
|
|
305
306
|
assert{ File.exist?(expect_path) && File.size(expect_path) == 0 }
|
|
306
307
|
|
|
307
|
-
|
|
308
|
+
ensure
|
|
309
|
+
d.instance_shutdown if d && d.instance
|
|
308
310
|
end
|
|
309
311
|
end
|
|
310
312
|
end
|
|
@@ -524,6 +524,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
524
524
|
assert_equal pid_list[1], events[1][2]['child_pid']
|
|
525
525
|
assert_equal pid_list[0], events[2][2]['child_pid']
|
|
526
526
|
assert_equal pid_list[1], events[3][2]['child_pid']
|
|
527
|
+
|
|
528
|
+
ensure
|
|
529
|
+
d.run(start: false, shutdown: true)
|
|
527
530
|
end
|
|
528
531
|
|
|
529
532
|
# child process exits per 3 lines
|
|
@@ -594,9 +597,10 @@ class ExecFilterOutputTest < Test::Unit::TestCase
|
|
|
594
597
|
# the number of pids should be same with number of child processes
|
|
595
598
|
assert_equal 2, pid_list.size
|
|
596
599
|
logs = d.instance.log.out.logs
|
|
597
|
-
assert_equal 2, logs.
|
|
598
|
-
assert_equal 2, logs.
|
|
600
|
+
assert_equal 2, logs.count { |l| l.include?('child process exits with error code') }
|
|
601
|
+
assert_equal 2, logs.count { |l| l.include?('respawning child process') }
|
|
599
602
|
|
|
603
|
+
ensure
|
|
600
604
|
d.run(start: false, shutdown: true)
|
|
601
605
|
end
|
|
602
606
|
end
|