fluentd 1.11.3-x86-mingw32 → 1.12.2-x86-mingw32
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.
- checksums.yaml +4 -4
- data/.deepsource.toml +13 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- data/.github/ISSUE_TEMPLATE/config.yml +5 -0
- data/.github/workflows/linux-test.yaml +36 -0
- data/.github/workflows/macos-test.yaml +30 -0
- data/.github/workflows/stale-actions.yml +22 -0
- data/.github/workflows/windows-test.yaml +30 -0
- data/CHANGELOG.md +138 -0
- data/MAINTAINERS.md +5 -2
- data/README.md +2 -2
- data/bin/fluent-cap-ctl +7 -0
- data/bin/fluent-ctl +7 -0
- data/fluentd.gemspec +4 -3
- data/lib/fluent/capability.rb +87 -0
- data/lib/fluent/command/bundler_injection.rb +1 -1
- data/lib/fluent/command/ca_generate.rb +6 -3
- data/lib/fluent/command/cap_ctl.rb +174 -0
- data/lib/fluent/command/cat.rb +0 -1
- data/lib/fluent/command/ctl.rb +177 -0
- data/lib/fluent/command/fluentd.rb +4 -0
- data/lib/fluent/command/plugin_config_formatter.rb +18 -2
- data/lib/fluent/compat/parser.rb +2 -2
- data/lib/fluent/config/section.rb +2 -2
- data/lib/fluent/config/types.rb +2 -2
- data/lib/fluent/env.rb +4 -0
- data/lib/fluent/event.rb +3 -13
- data/lib/fluent/load.rb +0 -1
- data/lib/fluent/plugin.rb +5 -0
- data/lib/fluent/plugin/buffer.rb +2 -21
- data/lib/fluent/plugin/formatter.rb +24 -0
- data/lib/fluent/plugin/formatter_csv.rb +1 -1
- data/lib/fluent/plugin/formatter_hash.rb +3 -1
- data/lib/fluent/plugin/formatter_json.rb +3 -1
- data/lib/fluent/plugin/formatter_ltsv.rb +7 -5
- data/lib/fluent/plugin/formatter_out_file.rb +6 -4
- data/lib/fluent/plugin/formatter_single_value.rb +4 -2
- data/lib/fluent/plugin/formatter_tsv.rb +4 -2
- data/lib/fluent/plugin/in_http.rb +24 -3
- data/lib/fluent/plugin/in_monitor_agent.rb +1 -1
- data/lib/fluent/plugin/in_tail.rb +128 -41
- data/lib/fluent/plugin/in_tail/position_file.rb +39 -14
- data/lib/fluent/plugin/in_tcp.rb +1 -0
- data/lib/fluent/plugin/out_copy.rb +18 -5
- data/lib/fluent/plugin/out_exec_filter.rb +3 -3
- data/lib/fluent/plugin/out_forward.rb +61 -28
- data/lib/fluent/plugin/out_http.rb +29 -4
- data/lib/fluent/plugin/output.rb +14 -6
- data/lib/fluent/plugin/storage_local.rb +3 -3
- data/lib/fluent/plugin_helper/http_server/compat/server.rb +1 -1
- data/lib/fluent/plugin_helper/inject.rb +4 -1
- data/lib/fluent/plugin_helper/retry_state.rb +4 -0
- data/lib/fluent/supervisor.rb +153 -48
- data/lib/fluent/system_config.rb +2 -1
- data/lib/fluent/time.rb +58 -1
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +22 -4
- data/templates/plugin_config_formatter/param.md-table.erb +10 -0
- data/test/command/test_binlog_reader.rb +22 -6
- data/test/command/test_cap_ctl.rb +100 -0
- data/test/command/test_ctl.rb +57 -0
- data/test/command/test_fluentd.rb +38 -0
- data/test/command/test_plugin_config_formatter.rb +124 -2
- data/test/config/test_configurable.rb +1 -1
- data/test/plugin/in_tail/test_position_file.rb +46 -26
- data/test/plugin/out_forward/test_connection_manager.rb +6 -0
- data/test/plugin/test_filter_stdout.rb +6 -1
- data/test/plugin/test_formatter_hash.rb +6 -3
- data/test/plugin/test_formatter_json.rb +14 -4
- data/test/plugin/test_formatter_ltsv.rb +13 -5
- data/test/plugin/test_formatter_out_file.rb +35 -14
- data/test/plugin/test_formatter_single_value.rb +12 -6
- data/test/plugin/test_formatter_tsv.rb +12 -4
- data/test/plugin/test_in_exec.rb +1 -1
- data/test/plugin/test_in_http.rb +25 -0
- data/test/plugin/test_in_tail.rb +470 -32
- data/test/plugin/test_out_copy.rb +87 -0
- data/test/plugin/test_out_file.rb +23 -18
- data/test/plugin/test_out_forward.rb +74 -0
- data/test/plugin/test_out_http.rb +20 -1
- data/test/plugin/test_output.rb +12 -0
- data/test/plugin/test_parser_syslog.rb +2 -2
- data/test/plugin/test_sd_file.rb +1 -1
- data/test/plugin_helper/test_child_process.rb +5 -2
- data/test/plugin_helper/test_compat_parameters.rb +7 -2
- data/test/plugin_helper/test_http_server_helper.rb +3 -1
- data/test/plugin_helper/test_inject.rb +42 -0
- data/test/plugin_helper/test_server.rb +18 -5
- data/test/test_capability.rb +74 -0
- data/test/test_event.rb +16 -0
- data/test/test_formatter.rb +64 -10
- data/test/test_output.rb +6 -1
- data/test/test_supervisor.rb +150 -1
- data/test/test_time_parser.rb +109 -0
- metadata +61 -29
- data/.travis.yml +0 -57
- data/appveyor.yml +0 -28
@@ -22,34 +22,40 @@ module Fluent::Plugin
|
|
22
22
|
UNWATCHED_POSITION = 0xffffffffffffffff
|
23
23
|
POSITION_FILE_ENTRY_REGEX = /^([^\t]+)\t([0-9a-fA-F]+)\t([0-9a-fA-F]+)/.freeze
|
24
24
|
|
25
|
-
def self.load(file, logger:)
|
26
|
-
pf = new(file, logger: logger)
|
25
|
+
def self.load(file, follow_inodes, existing_paths, logger:)
|
26
|
+
pf = new(file, follow_inodes, existing_paths, logger: logger)
|
27
27
|
pf.load
|
28
28
|
pf
|
29
29
|
end
|
30
30
|
|
31
|
-
def initialize(file, logger: nil)
|
31
|
+
def initialize(file, follow_inodes, existing_paths, logger: nil)
|
32
32
|
@file = file
|
33
33
|
@logger = logger
|
34
34
|
@file_mutex = Mutex.new
|
35
35
|
@map = {}
|
36
|
+
@follow_inodes = follow_inodes
|
37
|
+
@existing_paths = existing_paths
|
36
38
|
end
|
37
39
|
|
38
|
-
def [](
|
39
|
-
if m = @map[path]
|
40
|
+
def [](target_info)
|
41
|
+
if m = @map[@follow_inodes ? target_info.ino : target_info.path]
|
40
42
|
return m
|
41
43
|
end
|
42
44
|
|
43
45
|
@file_mutex.synchronize {
|
44
46
|
@file.seek(0, IO::SEEK_END)
|
45
|
-
seek = @file.pos + path.bytesize + 1
|
46
|
-
@file.write "#{path}\t0000000000000000\t0000000000000000\n"
|
47
|
-
|
47
|
+
seek = @file.pos + target_info.path.bytesize + 1
|
48
|
+
@file.write "#{target_info.path}\t0000000000000000\t0000000000000000\n"
|
49
|
+
if @follow_inodes
|
50
|
+
@map[target_info.ino] = FilePositionEntry.new(@file, @file_mutex, seek, 0, 0)
|
51
|
+
else
|
52
|
+
@map[target_info.path] = FilePositionEntry.new(@file, @file_mutex, seek, 0, 0)
|
53
|
+
end
|
48
54
|
}
|
49
55
|
end
|
50
56
|
|
51
|
-
def unwatch(
|
52
|
-
if (entry = @map.delete(path))
|
57
|
+
def unwatch(target_info)
|
58
|
+
if (entry = @map.delete(@follow_inodes ? target_info.ino : target_info.path))
|
53
59
|
entry.update_pos(UNWATCHED_POSITION)
|
54
60
|
end
|
55
61
|
end
|
@@ -69,7 +75,11 @@ module Fluent::Plugin
|
|
69
75
|
pos = m[2].to_i(16)
|
70
76
|
ino = m[3].to_i(16)
|
71
77
|
seek = @file.pos - line.bytesize + path.bytesize + 1
|
72
|
-
|
78
|
+
if @follow_inodes
|
79
|
+
map[ino] = FilePositionEntry.new(@file, @file_mutex, seek, pos, ino)
|
80
|
+
else
|
81
|
+
map[path] = FilePositionEntry.new(@file, @file_mutex, seek, pos, ino)
|
82
|
+
end
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
@@ -94,8 +104,9 @@ module Fluent::Plugin
|
|
94
104
|
@file.truncate(0)
|
95
105
|
@file.write(entries.values.map(&:to_entry_fmt).join)
|
96
106
|
|
97
|
-
|
98
|
-
|
107
|
+
# entry contains path/ino key and value.
|
108
|
+
entries.each do |key, val|
|
109
|
+
if (m = @map[key])
|
99
110
|
m.seek = val.seek
|
100
111
|
end
|
101
112
|
end
|
@@ -139,13 +150,25 @@ module Fluent::Plugin
|
|
139
150
|
@logger.warn("#{path} already exists. use latest one: deleted #{entries[path]}") if @logger
|
140
151
|
end
|
141
152
|
|
142
|
-
|
153
|
+
if @follow_inodes
|
154
|
+
entries[ino] = Entry.new(path, pos, ino, file_pos + path.size + 1)
|
155
|
+
else
|
156
|
+
entries[path] = Entry.new(path, pos, ino, file_pos + path.size + 1)
|
157
|
+
end
|
143
158
|
file_pos += line.size
|
144
159
|
end
|
145
160
|
end
|
146
161
|
|
162
|
+
entries = remove_deleted_files_entries(entries, @existing_paths) if @follow_inodes
|
147
163
|
entries
|
148
164
|
end
|
165
|
+
|
166
|
+
def remove_deleted_files_entries(existent_entries, existing_paths)
|
167
|
+
filtered_entries = existent_entries.select {|file_entry|
|
168
|
+
existing_paths.key?(file_entry)
|
169
|
+
}
|
170
|
+
filtered_entries
|
171
|
+
end
|
149
172
|
end
|
150
173
|
|
151
174
|
Entry = Struct.new(:path, :pos, :ino, :seek) do
|
@@ -224,5 +247,7 @@ module Fluent::Plugin
|
|
224
247
|
@inode
|
225
248
|
end
|
226
249
|
end
|
250
|
+
|
251
|
+
TargetInfo = Struct.new(:path, :ino)
|
227
252
|
end
|
228
253
|
end
|
data/lib/fluent/plugin/in_tcp.rb
CHANGED
@@ -98,6 +98,7 @@ module Fluent::Plugin
|
|
98
98
|
def start
|
99
99
|
super
|
100
100
|
|
101
|
+
log.info "listening tcp socket", bind: @bind, port: @port
|
101
102
|
del_size = @delimiter.length
|
102
103
|
if @_extract_enabled && @_extract_tag_key
|
103
104
|
server_create(:in_tcp_server_single_emit, @port, bind: @bind, resolve_name: !!@source_hostname_key) do |data, conn|
|
@@ -27,20 +27,28 @@ module Fluent::Plugin
|
|
27
27
|
desc 'Pass different record to each `store` plugin by specified method'
|
28
28
|
config_param :copy_mode, :enum, list: [:no_copy, :shallow, :deep, :marshal], default: :no_copy
|
29
29
|
|
30
|
-
attr_reader :ignore_errors
|
30
|
+
attr_reader :ignore_errors, :ignore_if_prev_successes
|
31
31
|
|
32
32
|
def initialize
|
33
33
|
super
|
34
34
|
@ignore_errors = []
|
35
|
+
@ignore_if_prev_successes = []
|
35
36
|
end
|
36
37
|
|
37
38
|
def configure(conf)
|
38
39
|
super
|
39
40
|
|
40
41
|
@copy_proc = gen_copy_proc
|
41
|
-
@stores.
|
42
|
-
|
42
|
+
@stores.each_with_index { |store, i|
|
43
|
+
if i == 0 && store.arg.include?('ignore_if_prev_success')
|
44
|
+
raise Fluent::ConfigError, "ignore_if_prev_success must specify 2nd or later <store> directives"
|
45
|
+
end
|
46
|
+
@ignore_errors << (store.arg.include?('ignore_error'))
|
47
|
+
@ignore_if_prev_successes << (store.arg.include?('ignore_if_prev_success'))
|
43
48
|
}
|
49
|
+
if @ignore_errors.uniq.size == 1 && @ignore_errors.include?(true) && @ignore_if_prev_successes.include?(false)
|
50
|
+
log.warn "ignore_errors are specified in all <store>, but ignore_if_prev_success is not specified. Is this intended?"
|
51
|
+
end
|
44
52
|
end
|
45
53
|
|
46
54
|
def multi_workers_ready?
|
@@ -55,10 +63,15 @@ module Fluent::Plugin
|
|
55
63
|
}
|
56
64
|
es = m
|
57
65
|
end
|
58
|
-
|
66
|
+
success = Array.new(outputs.size)
|
59
67
|
outputs.each_with_index do |output, i|
|
60
68
|
begin
|
61
|
-
|
69
|
+
if i > 0 && success[i - 1] && @ignore_if_prev_successes[i]
|
70
|
+
log.debug "ignore copy because prev_success in #{output.plugin_id}", index: i
|
71
|
+
else
|
72
|
+
output.emit_events(tag, @copy_proc ? @copy_proc.call(es) : es)
|
73
|
+
success[i] = true
|
74
|
+
end
|
62
75
|
rescue => e
|
63
76
|
if @ignore_errors[i]
|
64
77
|
log.error "ignore emit error in #{output.plugin_id}", error: e
|
@@ -159,9 +159,9 @@ module Fluent::Plugin
|
|
159
159
|
@added_prefix_string = @add_prefix + '.'
|
160
160
|
end
|
161
161
|
|
162
|
-
@respawns = if @child_respawn.nil?
|
162
|
+
@respawns = if @child_respawn.nil? || (@child_respawn == 'none') || (@child_respawn == '0')
|
163
163
|
0
|
164
|
-
elsif @child_respawn == 'inf'
|
164
|
+
elsif (@child_respawn == 'inf') || (@child_respawn == '-1')
|
165
165
|
-1
|
166
166
|
elsif @child_respawn =~ /^\d+$/
|
167
167
|
@child_respawn.to_i
|
@@ -251,7 +251,7 @@ module Fluent::Plugin
|
|
251
251
|
|
252
252
|
def tag_remove_prefix(tag)
|
253
253
|
if @remove_prefix
|
254
|
-
if (tag[0, @removed_length] == @removed_prefix_string
|
254
|
+
if ((tag[0, @removed_length] == @removed_prefix_string) && (tag.length > @removed_length)) || (tag == @removed_prefix_string)
|
255
255
|
tag = tag[@removed_length..-1] || ''
|
256
256
|
end
|
257
257
|
end
|
@@ -166,6 +166,7 @@ module Fluent::Plugin
|
|
166
166
|
|
167
167
|
@usock = nil
|
168
168
|
@keep_alive_watcher_interval = 5 # TODO
|
169
|
+
@suspend_flush = false
|
169
170
|
end
|
170
171
|
|
171
172
|
def configure(conf)
|
@@ -291,6 +292,15 @@ module Fluent::Plugin
|
|
291
292
|
@require_ack_response
|
292
293
|
end
|
293
294
|
|
295
|
+
def overwrite_delayed_commit_timeout
|
296
|
+
# Output#start sets @delayed_commit_timeout by @buffer_config.delayed_commit_timeout
|
297
|
+
# But it should be overwritten by ack_response_timeout to rollback chunks after timeout
|
298
|
+
if @delayed_commit_timeout != @ack_response_timeout
|
299
|
+
log.info "delayed_commit_timeout is overwritten by ack_response_timeout"
|
300
|
+
@delayed_commit_timeout = @ack_response_timeout + 2 # minimum ack_reader IO.select interval is 1s
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
294
304
|
def start
|
295
305
|
super
|
296
306
|
|
@@ -303,13 +313,7 @@ module Fluent::Plugin
|
|
303
313
|
end
|
304
314
|
|
305
315
|
if @require_ack_response
|
306
|
-
|
307
|
-
# But it should be overwritten by ack_response_timeout to rollback chunks after timeout
|
308
|
-
if @delayed_commit_timeout != @ack_response_timeout
|
309
|
-
log.info "delayed_commit_timeout is overwritten by ack_response_timeout"
|
310
|
-
@delayed_commit_timeout = @ack_response_timeout + 2 # minimum ack_reader IO.select interval is 1s
|
311
|
-
end
|
312
|
-
|
316
|
+
overwrite_delayed_commit_timeout
|
313
317
|
thread_create(:out_forward_receiving_ack, &method(:ack_reader))
|
314
318
|
end
|
315
319
|
|
@@ -346,6 +350,26 @@ module Fluent::Plugin
|
|
346
350
|
end
|
347
351
|
end
|
348
352
|
|
353
|
+
def before_shutdown
|
354
|
+
super
|
355
|
+
@suspend_flush = true
|
356
|
+
end
|
357
|
+
|
358
|
+
def after_shutdown
|
359
|
+
last_ack if @require_ack_response
|
360
|
+
super
|
361
|
+
end
|
362
|
+
|
363
|
+
def try_flush
|
364
|
+
return if @require_ack_response && @suspend_flush
|
365
|
+
super
|
366
|
+
end
|
367
|
+
|
368
|
+
def last_ack
|
369
|
+
overwrite_delayed_commit_timeout
|
370
|
+
ack_check(ack_select_interval)
|
371
|
+
end
|
372
|
+
|
349
373
|
def write(chunk)
|
350
374
|
return if chunk.empty?
|
351
375
|
tag = chunk.metadata.tag
|
@@ -361,6 +385,7 @@ module Fluent::Plugin
|
|
361
385
|
end
|
362
386
|
tag = chunk.metadata.tag
|
363
387
|
discovery_manager.select_service { |node| node.send_data(tag, chunk) }
|
388
|
+
last_ack if @require_ack_response && @suspend_flush
|
364
389
|
end
|
365
390
|
|
366
391
|
def create_transfer_socket(host, port, hostname, &block)
|
@@ -481,31 +506,39 @@ module Fluent::Plugin
|
|
481
506
|
@connection_manager.purge_obsolete_socks
|
482
507
|
end
|
483
508
|
|
509
|
+
def ack_select_interval
|
510
|
+
if @delayed_commit_timeout > 3
|
511
|
+
1
|
512
|
+
else
|
513
|
+
@delayed_commit_timeout / 3.0
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
484
517
|
def ack_reader
|
485
|
-
select_interval =
|
486
|
-
1
|
487
|
-
else
|
488
|
-
@delayed_commit_timeout / 3.0
|
489
|
-
end
|
518
|
+
select_interval = ack_select_interval
|
490
519
|
|
491
520
|
while thread_current_running?
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
case result
|
496
|
-
when AckHandler::Result::SUCCESS
|
497
|
-
commit_write(chunk_id)
|
498
|
-
when AckHandler::Result::FAILED
|
499
|
-
node.disable!
|
500
|
-
rollback_write(chunk_id, update_retry: false)
|
501
|
-
when AckHandler::Result::CHUNKID_UNMATCHED
|
502
|
-
rollback_write(chunk_id, update_retry: false)
|
503
|
-
else
|
504
|
-
log.warn("BUG: invalid status #{result} #{chunk_id}")
|
521
|
+
ack_check(select_interval)
|
522
|
+
end
|
523
|
+
end
|
505
524
|
|
506
|
-
|
507
|
-
|
508
|
-
|
525
|
+
def ack_check(select_interval)
|
526
|
+
@ack_handler.collect_response(select_interval) do |chunk_id, node, sock, result|
|
527
|
+
@connection_manager.close(sock)
|
528
|
+
|
529
|
+
case result
|
530
|
+
when AckHandler::Result::SUCCESS
|
531
|
+
commit_write(chunk_id)
|
532
|
+
when AckHandler::Result::FAILED
|
533
|
+
node.disable!
|
534
|
+
rollback_write(chunk_id, update_retry: false)
|
535
|
+
when AckHandler::Result::CHUNKID_UNMATCHED
|
536
|
+
rollback_write(chunk_id, update_retry: false)
|
537
|
+
else
|
538
|
+
log.warn("BUG: invalid status #{result} #{chunk_id}")
|
539
|
+
|
540
|
+
if chunk_id
|
541
|
+
rollback_write(chunk_id, update_retry: false)
|
509
542
|
end
|
510
543
|
end
|
511
544
|
end
|
@@ -21,6 +21,16 @@ require 'fluent/tls'
|
|
21
21
|
require 'fluent/plugin/output'
|
22
22
|
require 'fluent/plugin_helper/socket'
|
23
23
|
|
24
|
+
# patch Net::HTTP to support extra_chain_cert which was added in Ruby feature #9758.
|
25
|
+
# see: https://github.com/ruby/ruby/commit/31af0dafba6d3769d2a39617c0dddedb97883712
|
26
|
+
unless Net::HTTP::SSL_IVNAMES.include?(:@extra_chain_cert)
|
27
|
+
class Net::HTTP
|
28
|
+
SSL_IVNAMES << :@extra_chain_cert
|
29
|
+
SSL_ATTRIBUTES << :extra_chain_cert
|
30
|
+
attr_accessor :extra_chain_cert
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
24
34
|
module Fluent::Plugin
|
25
35
|
class HTTPOutput < Output
|
26
36
|
Fluent::Plugin.register_output('http', self)
|
@@ -41,6 +51,8 @@ module Fluent::Plugin
|
|
41
51
|
config_param :json_array, :bool, default: false
|
42
52
|
desc 'Additional headers for HTTP request'
|
43
53
|
config_param :headers, :hash, default: nil
|
54
|
+
desc 'Additional placeholder based headers for HTTP request'
|
55
|
+
config_param :headers_from_placeholders, :hash, default: nil
|
44
56
|
|
45
57
|
desc 'The connection open timeout in seconds'
|
46
58
|
config_param :open_timeout, :integer, default: nil
|
@@ -171,7 +183,15 @@ module Fluent::Plugin
|
|
171
183
|
end
|
172
184
|
if @tls_client_cert_path
|
173
185
|
raise Fluent::ConfigError, "tls_client_cert_path is wrong: #{@tls_client_cert_path}" unless File.file?(@tls_client_cert_path)
|
174
|
-
|
186
|
+
|
187
|
+
bundle = File.read(@tls_client_cert_path)
|
188
|
+
bundle_certs = bundle.scan(/-----BEGIN CERTIFICATE-----(?:.|\n)+?-----END CERTIFICATE-----/)
|
189
|
+
opt[:cert] = OpenSSL::X509::Certificate.new(bundle_certs[0])
|
190
|
+
|
191
|
+
intermediate_certs = bundle_certs[1..-1]
|
192
|
+
if intermediate_certs
|
193
|
+
opt[:extra_chain_cert] = intermediate_certs.map { |cert| OpenSSL::X509::Certificate.new(cert) }
|
194
|
+
end
|
175
195
|
end
|
176
196
|
if @tls_private_key_path
|
177
197
|
raise Fluent::ConfigError, "tls_private_key_path is wrong: #{@tls_private_key_path}" unless File.file?(@tls_private_key_path)
|
@@ -195,12 +215,17 @@ module Fluent::Plugin
|
|
195
215
|
URI.parse(endpoint)
|
196
216
|
end
|
197
217
|
|
198
|
-
def set_headers(req)
|
218
|
+
def set_headers(req, chunk)
|
199
219
|
if @headers
|
200
220
|
@headers.each do |k, v|
|
201
221
|
req[k] = v
|
202
222
|
end
|
203
223
|
end
|
224
|
+
if @headers_from_placeholders
|
225
|
+
@headers_from_placeholders.each do |k, v|
|
226
|
+
req[k] = extract_placeholders(v, chunk)
|
227
|
+
end
|
228
|
+
end
|
204
229
|
req['Content-Type'] = @content_type
|
205
230
|
end
|
206
231
|
|
@@ -214,8 +239,8 @@ module Fluent::Plugin
|
|
214
239
|
if @auth
|
215
240
|
req.basic_auth(@auth.username, @auth.password)
|
216
241
|
end
|
217
|
-
set_headers(req)
|
218
|
-
req.body = @json_array ? "[#{chunk.read.chop
|
242
|
+
set_headers(req, chunk)
|
243
|
+
req.body = @json_array ? "[#{chunk.read.chop}]" : chunk.read
|
219
244
|
req
|
220
245
|
end
|
221
246
|
|
data/lib/fluent/plugin/output.rb
CHANGED
@@ -769,17 +769,19 @@ module Fluent
|
|
769
769
|
end
|
770
770
|
end
|
771
771
|
|
772
|
-
|
773
|
-
log.warn "chunk key placeholder '#{$1}' not replaced. template:#{str}"
|
774
|
-
end
|
775
|
-
|
776
|
-
rvalue.sub(CHUNK_ID_PLACEHOLDER_PATTERN) {
|
772
|
+
rvalue = rvalue.sub(CHUNK_ID_PLACEHOLDER_PATTERN) {
|
777
773
|
if chunk_passed
|
778
774
|
dump_unique_id_hex(chunk.unique_id)
|
779
775
|
else
|
780
776
|
log.warn "${chunk_id} is not allowed in this plugin. Pass Chunk instead of metadata in extract_placeholders's 2nd argument"
|
781
777
|
end
|
782
778
|
}
|
779
|
+
|
780
|
+
if rvalue =~ CHUNK_KEY_PLACEHOLDER_PATTERN
|
781
|
+
log.warn "chunk key placeholder '#{$1}' not replaced. template:#{str}"
|
782
|
+
end
|
783
|
+
|
784
|
+
rvalue
|
783
785
|
end
|
784
786
|
end
|
785
787
|
|
@@ -1250,7 +1252,13 @@ module Fluent
|
|
1250
1252
|
log.debug "buffer queue cleared"
|
1251
1253
|
@retry = nil
|
1252
1254
|
else
|
1253
|
-
@retry.
|
1255
|
+
# Ensure that the current time is greater than or equal to @retry.next_time to avoid the situation when
|
1256
|
+
# @retry.step is called almost as many times as the number of flush threads in a short time.
|
1257
|
+
if Time.now >= @retry.next_time
|
1258
|
+
@retry.step
|
1259
|
+
else
|
1260
|
+
@retry.recalc_next_time # to prevent all flush threads from retrying at the same time
|
1261
|
+
end
|
1254
1262
|
if error
|
1255
1263
|
if using_secondary
|
1256
1264
|
msg = "failed to flush the buffer with secondary output."
|
@@ -87,7 +87,7 @@ module Fluent
|
|
87
87
|
if File.exist?(@path)
|
88
88
|
raise Fluent::ConfigError, "Plugin storage path '#{@path}' is not readable/writable" unless File.readable?(@path) && File.writable?(@path)
|
89
89
|
begin
|
90
|
-
data = open(@path, 'r:utf-8') { |io| io.read }
|
90
|
+
data = File.open(@path, 'r:utf-8') { |io| io.read }
|
91
91
|
if data.empty?
|
92
92
|
log.warn "detect empty plugin storage file during startup. Ignored: #{@path}"
|
93
93
|
return
|
@@ -115,7 +115,7 @@ module Fluent
|
|
115
115
|
return if @on_memory
|
116
116
|
return unless File.exist?(@path)
|
117
117
|
begin
|
118
|
-
json_string = open(@path, 'r:utf-8'){ |io| io.read }
|
118
|
+
json_string = File.open(@path, 'r:utf-8'){ |io| io.read }
|
119
119
|
json = Yajl::Parser.parse(json_string)
|
120
120
|
unless json.is_a?(Hash)
|
121
121
|
log.error "broken content for plugin storage (Hash required: ignored)", type: json.class
|
@@ -133,7 +133,7 @@ module Fluent
|
|
133
133
|
tmp_path = @path + '.tmp'
|
134
134
|
begin
|
135
135
|
json_string = Yajl::Encoder.encode(@store, pretty: @pretty_print)
|
136
|
-
open(tmp_path, 'w:utf-8', @mode) { |io| io.write json_string; io.fsync }
|
136
|
+
File.open(tmp_path, 'w:utf-8', @mode) { |io| io.write json_string; io.fsync }
|
137
137
|
File.rename(tmp_path, @path)
|
138
138
|
rescue => e
|
139
139
|
log.error "failed to save data for plugin storage to file", path: @path, tmp: tmp_path, error: e
|