fluentd 1.14.6 → 1.15.0
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/.github/workflows/linux-test.yaml +1 -1
- data/.github/workflows/windows-test.yaml +4 -1
- data/CHANGELOG.md +53 -1
- data/fluentd.gemspec +2 -1
- data/lib/fluent/command/ctl.rb +4 -1
- data/lib/fluent/command/fluentd.rb +10 -0
- data/lib/fluent/config/literal_parser.rb +2 -2
- data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
- data/lib/fluent/config/yaml_parser/loader.rb +91 -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/plugin/file_wrapper.rb +52 -107
- data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
- data/lib/fluent/plugin/in_tail/position_file.rb +1 -15
- data/lib/fluent/plugin/in_tail.rb +66 -47
- data/lib/fluent/plugin/out_forward/socket_cache.rb +2 -0
- data/lib/fluent/plugin/output.rb +2 -1
- data/lib/fluent/plugin/parser_syslog.rb +1 -1
- data/lib/fluent/plugin_helper/server.rb +3 -1
- data/lib/fluent/plugin_helper/service_discovery.rb +2 -2
- data/lib/fluent/supervisor.rb +109 -25
- data/lib/fluent/system_config.rb +2 -1
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +2 -0
- data/test/command/test_ctl.rb +0 -1
- data/test/command/test_fluentd.rb +33 -0
- data/test/config/test_system_config.rb +3 -1
- data/test/config/test_types.rb +1 -1
- data/test/plugin/in_tail/test_io_handler.rb +14 -4
- data/test/plugin/in_tail/test_position_file.rb +0 -63
- data/test/plugin/out_forward/test_socket_cache.rb +26 -1
- data/test/plugin/test_file_wrapper.rb +0 -68
- data/test/plugin/test_in_object_space.rb +9 -3
- data/test/plugin/test_in_syslog.rb +1 -1
- data/test/plugin/test_in_tail.rb +629 -353
- data/test/plugin/test_out_forward.rb +30 -20
- 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 +16 -4
- data/test/test_config.rb +135 -4
- data/test/test_supervisor.rb +155 -0
- metadata +11 -5
data/lib/fluent/plugin/output.rb
CHANGED
@@ -235,6 +235,7 @@ module Fluent
|
|
235
235
|
@dequeued_chunks_mutex = nil
|
236
236
|
@output_enqueue_thread = nil
|
237
237
|
@output_flush_threads = nil
|
238
|
+
@output_flush_thread_current_position = 0
|
238
239
|
|
239
240
|
@simple_chunking = nil
|
240
241
|
@chunk_keys = @chunk_key_accessors = @chunk_key_time = @chunk_key_tag = nil
|
@@ -492,6 +493,7 @@ module Fluent
|
|
492
493
|
@dequeued_chunks = []
|
493
494
|
@dequeued_chunks_mutex = Mutex.new
|
494
495
|
|
496
|
+
@output_flush_thread_current_position = 0
|
495
497
|
@buffer_config.flush_thread_count.times do |i|
|
496
498
|
thread_title = "flush_thread_#{i}".to_sym
|
497
499
|
thread_state = FlushThreadState.new(nil, nil, Mutex.new, ConditionVariable.new)
|
@@ -503,7 +505,6 @@ module Fluent
|
|
503
505
|
@output_flush_threads << thread_state
|
504
506
|
end
|
505
507
|
end
|
506
|
-
@output_flush_thread_current_position = 0
|
507
508
|
|
508
509
|
if !@under_plugin_development && (@flush_mode == :interval || @chunk_key_time)
|
509
510
|
@output_enqueue_thread = thread_create(:enqueue_thread, &method(:enqueue_thread_run))
|
@@ -484,7 +484,7 @@ module Fluent
|
|
484
484
|
|
485
485
|
time = begin
|
486
486
|
@time_parser_rfc5424.parse(time_str)
|
487
|
-
rescue Fluent::TimeParser::TimeParseError
|
487
|
+
rescue Fluent::TimeParser::TimeParseError
|
488
488
|
@time_parser_rfc5424_without_subseconds.parse(time_str)
|
489
489
|
end
|
490
490
|
record['time'] = time_str if @keep_time_key
|
@@ -267,7 +267,9 @@ module Fluent
|
|
267
267
|
### Socket Params ###
|
268
268
|
|
269
269
|
# SO_LINGER 0 to send RST rather than FIN to avoid lots of connections sitting in TIME_WAIT at src.
|
270
|
-
# Set positive value if needing to send FIN on closing.
|
270
|
+
# Set positive value if needing to send FIN on closing on non-Windows.
|
271
|
+
# (On Windows, Fluentd can send FIN with zero `linger_timeout` since Fluentd doesn't set 0 to SO_LINGER on Windows.
|
272
|
+
# See `socket_option.rb`.)
|
271
273
|
# NOTE:
|
272
274
|
# Socket-options can be specified from each plugin as needed, so most of them is not defined here for now.
|
273
275
|
# This is because there is no positive reason to do so.
|
@@ -44,7 +44,7 @@ module Fluent
|
|
44
44
|
|
45
45
|
@discovery_manager.start
|
46
46
|
unless @discovery_manager.static_config?
|
47
|
-
timer_execute(@_plugin_helper_service_discovery_title, @
|
47
|
+
timer_execute(@_plugin_helper_service_discovery_title, @_plugin_helper_service_discovery_interval) do
|
48
48
|
@discovery_manager.run_once
|
49
49
|
end
|
50
50
|
end
|
@@ -96,7 +96,7 @@ module Fluent
|
|
96
96
|
# @param custom_build_method [Proc]
|
97
97
|
def service_discovery_create_manager(title, configurations:, load_balancer: nil, custom_build_method: nil, interval: 3)
|
98
98
|
@_plugin_helper_service_discovery_title = title
|
99
|
-
@
|
99
|
+
@_plugin_helper_service_discovery_interval = interval
|
100
100
|
|
101
101
|
@discovery_manager = Fluent::PluginHelper::ServiceDiscovery::Manager.new(
|
102
102
|
log: log,
|
data/lib/fluent/supervisor.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
require 'fileutils'
|
18
18
|
require 'open3'
|
19
|
+
require 'pathname'
|
19
20
|
|
20
21
|
require 'fluent/config'
|
21
22
|
require 'fluent/counter'
|
@@ -215,44 +216,50 @@ module Fluent
|
|
215
216
|
Thread.new do
|
216
217
|
ipc = Win32::Ipc.new(nil)
|
217
218
|
events = [
|
218
|
-
Win32::Event.new("#{@pid_signame}_STOP_EVENT_THREAD"),
|
219
|
-
Win32::Event.new("#{@pid_signame}"),
|
220
|
-
Win32::Event.new("#{@pid_signame}_HUP"),
|
221
|
-
Win32::Event.new("#{@pid_signame}_USR1"),
|
222
|
-
Win32::Event.new("#{@pid_signame}_USR2"),
|
219
|
+
{win32_event: Win32::Event.new("#{@pid_signame}_STOP_EVENT_THREAD"), action: :stop_event_thread},
|
220
|
+
{win32_event: Win32::Event.new("#{@pid_signame}"), action: :stop},
|
221
|
+
{win32_event: Win32::Event.new("#{@pid_signame}_HUP"), action: :hup},
|
222
|
+
{win32_event: Win32::Event.new("#{@pid_signame}_USR1"), action: :usr1},
|
223
|
+
{win32_event: Win32::Event.new("#{@pid_signame}_USR2"), action: :usr2},
|
224
|
+
{win32_event: Win32::Event.new("#{@pid_signame}_CONT"), action: :cont},
|
223
225
|
]
|
224
226
|
if @signame
|
225
227
|
signame_events = [
|
226
|
-
Win32::Event.new("#{@signame}"),
|
227
|
-
Win32::Event.new("#{@signame}_HUP"),
|
228
|
-
Win32::Event.new("#{@signame}_USR1"),
|
229
|
-
Win32::Event.new("#{@signame}_USR2"),
|
228
|
+
{win32_event: Win32::Event.new("#{@signame}"), action: :stop},
|
229
|
+
{win32_event: Win32::Event.new("#{@signame}_HUP"), action: :hup},
|
230
|
+
{win32_event: Win32::Event.new("#{@signame}_USR1"), action: :usr1},
|
231
|
+
{win32_event: Win32::Event.new("#{@signame}_USR2"), action: :usr2},
|
232
|
+
{win32_event: Win32::Event.new("#{@signame}_CONT"), action: :cont},
|
230
233
|
]
|
231
234
|
events.concat(signame_events)
|
232
235
|
end
|
233
236
|
begin
|
234
237
|
loop do
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
+
ipc_idx = ipc.wait_any(events.map {|e| e[:win32_event]}, Windows::Synchronize::INFINITE)
|
239
|
+
event_idx = ipc_idx - 1
|
240
|
+
|
241
|
+
if event_idx >= 0 && event_idx < events.length
|
242
|
+
$log.debug("Got Win32 event \"#{events[event_idx][:win32_event].name}\"")
|
238
243
|
else
|
239
|
-
$log.warn("Unexpected
|
244
|
+
$log.warn("Unexpected return value of Win32::Ipc#wait_any: #{ipc_idx}")
|
240
245
|
end
|
241
|
-
case
|
242
|
-
when
|
246
|
+
case events[event_idx][:action]
|
247
|
+
when :stop
|
243
248
|
stop(true)
|
244
|
-
when
|
249
|
+
when :hup
|
245
250
|
supervisor_sighup_handler
|
246
|
-
when
|
251
|
+
when :usr1
|
247
252
|
supervisor_sigusr1_handler
|
248
|
-
when
|
253
|
+
when :usr2
|
249
254
|
supervisor_sigusr2_handler
|
250
|
-
when
|
255
|
+
when :cont
|
256
|
+
supervisor_dump_handler_for_windows
|
257
|
+
when :stop_event_thread
|
251
258
|
break
|
252
259
|
end
|
253
260
|
end
|
254
261
|
ensure
|
255
|
-
events.each { |event| event.close }
|
262
|
+
events.each { |event| event[:win32_event].close }
|
256
263
|
end
|
257
264
|
end
|
258
265
|
end
|
@@ -302,6 +309,26 @@ module Fluent
|
|
302
309
|
$log.error "Failed to reload config file: #{e}"
|
303
310
|
end
|
304
311
|
|
312
|
+
def supervisor_dump_handler_for_windows
|
313
|
+
# As for UNIX-like, SIGCONT signal to each process makes the process output its dump-file,
|
314
|
+
# and it is implemented before the implementation of the function for Windows.
|
315
|
+
# It is possible to trap SIGCONT and handle it here also on UNIX-like,
|
316
|
+
# but for backward compatibility, this handler is currently for a Windows-only.
|
317
|
+
raise "[BUG] This function is for Windows ONLY." unless Fluent.windows?
|
318
|
+
|
319
|
+
Thread.new do
|
320
|
+
begin
|
321
|
+
FluentSigdump.dump_windows
|
322
|
+
rescue => e
|
323
|
+
$log.error "failed to dump: #{e}"
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
send_signal_to_workers(:CONT)
|
328
|
+
rescue => e
|
329
|
+
$log.error "failed to dump: #{e}"
|
330
|
+
end
|
331
|
+
|
305
332
|
def kill_worker
|
306
333
|
if config[:worker_pid]
|
307
334
|
pids = config[:worker_pid].clone
|
@@ -358,6 +385,14 @@ module Fluent
|
|
358
385
|
restart(true)
|
359
386
|
when :USR2
|
360
387
|
reload
|
388
|
+
when :CONT
|
389
|
+
dump_all_windows_workers
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
def dump_all_windows_workers
|
394
|
+
@monitors.each do |m|
|
395
|
+
m.send_command("DUMP\n")
|
361
396
|
end
|
362
397
|
end
|
363
398
|
end
|
@@ -458,7 +493,8 @@ module Fluent
|
|
458
493
|
config_path: path,
|
459
494
|
main_cmd: params['main_cmd'],
|
460
495
|
signame: params['signame'],
|
461
|
-
disable_shared_socket: params['disable_shared_socket']
|
496
|
+
disable_shared_socket: params['disable_shared_socket'],
|
497
|
+
restart_worker_interval: params['restart_worker_interval'],
|
462
498
|
}
|
463
499
|
if daemonize
|
464
500
|
se_config[:pid_path] = pid_path
|
@@ -580,7 +616,8 @@ module Fluent
|
|
580
616
|
standalone_worker: false,
|
581
617
|
signame: nil,
|
582
618
|
conf_encoding: 'utf-8',
|
583
|
-
disable_shared_socket: nil
|
619
|
+
disable_shared_socket: nil,
|
620
|
+
config_file_type: :guess,
|
584
621
|
}
|
585
622
|
end
|
586
623
|
|
@@ -593,6 +630,7 @@ module Fluent
|
|
593
630
|
end
|
594
631
|
|
595
632
|
def initialize(opt)
|
633
|
+
@config_file_type = opt[:config_file_type]
|
596
634
|
@daemonize = opt[:daemonize]
|
597
635
|
@standalone_worker= opt[:standalone_worker]
|
598
636
|
@config_path = opt[:config_path]
|
@@ -618,7 +656,9 @@ module Fluent
|
|
618
656
|
@conf = Fluent::Config.build(config_path: @config_path,
|
619
657
|
encoding: @conf_encoding ? @conf_encoding : 'utf-8',
|
620
658
|
additional_config: @inline_config ? @inline_config : nil,
|
621
|
-
use_v1_config: !!@use_v1_config
|
659
|
+
use_v1_config: !!@use_v1_config,
|
660
|
+
type: @config_file_type,
|
661
|
+
)
|
622
662
|
@system_config = build_system_config(@conf)
|
623
663
|
if @system_config.log
|
624
664
|
@log_rotate_age ||= @system_config.log.rotate_age
|
@@ -744,7 +784,13 @@ module Fluent
|
|
744
784
|
$log.warn('the value "-" for `inline_config` is deprecated. See https://github.com/fluent/fluentd/issues/2711')
|
745
785
|
@inline_config = STDIN.read
|
746
786
|
end
|
747
|
-
@conf = Fluent::Config.build(
|
787
|
+
@conf = Fluent::Config.build(
|
788
|
+
config_path: @config_path,
|
789
|
+
encoding: @conf_encoding,
|
790
|
+
additional_config: @inline_config,
|
791
|
+
use_v1_config: @use_v1_config,
|
792
|
+
type: @config_file_type,
|
793
|
+
)
|
748
794
|
@system_config = build_system_config(@conf)
|
749
795
|
|
750
796
|
@log.level = @system_config.log_level
|
@@ -822,7 +868,8 @@ module Fluent
|
|
822
868
|
'counter_server' => @system_config.counter_server,
|
823
869
|
'log_format' => @system_config.log.format,
|
824
870
|
'log_time_format' => @system_config.log.time_format,
|
825
|
-
'disable_shared_socket' => @system_config.disable_shared_socket
|
871
|
+
'disable_shared_socket' => @system_config.disable_shared_socket,
|
872
|
+
'restart_worker_interval' => @system_config.restart_worker_interval,
|
826
873
|
}
|
827
874
|
|
828
875
|
se = ServerEngine.create(ServerModule, WorkerModule){
|
@@ -896,6 +943,9 @@ module Fluent
|
|
896
943
|
when "RELOAD"
|
897
944
|
$log.debug "fluentd main process get #{cmd} command"
|
898
945
|
reload_config
|
946
|
+
when "DUMP"
|
947
|
+
$log.debug "fluentd main process get #{cmd} command"
|
948
|
+
dump
|
899
949
|
else
|
900
950
|
$log.warn "fluentd main process get unknown command [#{cmd}]"
|
901
951
|
end
|
@@ -929,6 +979,7 @@ module Fluent
|
|
929
979
|
encoding: @conf_encoding,
|
930
980
|
additional_config: @inline_config,
|
931
981
|
use_v1_config: @use_v1_config,
|
982
|
+
type: @config_file_type,
|
932
983
|
)
|
933
984
|
|
934
985
|
Fluent::VariableStore.try_to_reset do
|
@@ -945,6 +996,16 @@ module Fluent
|
|
945
996
|
end
|
946
997
|
end
|
947
998
|
|
999
|
+
def dump
|
1000
|
+
Thread.new do
|
1001
|
+
begin
|
1002
|
+
FluentSigdump.dump_windows
|
1003
|
+
rescue => e
|
1004
|
+
$log.error("failed to dump: #{e}")
|
1005
|
+
end
|
1006
|
+
end
|
1007
|
+
end
|
1008
|
+
|
948
1009
|
def logging_with_console_output
|
949
1010
|
yield $log
|
950
1011
|
unless @log.stdout?
|
@@ -1054,4 +1115,27 @@ module Fluent
|
|
1054
1115
|
fluentd_spawn_cmd
|
1055
1116
|
end
|
1056
1117
|
end
|
1118
|
+
|
1119
|
+
module FluentSigdump
|
1120
|
+
def self.dump_windows
|
1121
|
+
raise "[BUG] WindowsSigdump::dump is for Windows ONLY." unless Fluent.windows?
|
1122
|
+
|
1123
|
+
# Sigdump outputs under `/tmp` dir without `SIGDUMP_PATH` specified,
|
1124
|
+
# but `/tmp` dir may not exist on Windows by default.
|
1125
|
+
# So use the systemroot-temp-dir instead.
|
1126
|
+
dump_filepath = ENV['SIGDUMP_PATH'].nil? || ENV['SIGDUMP_PATH'].empty? \
|
1127
|
+
? "#{ENV['windir']}/Temp/fluentd-sigdump-#{Process.pid}.log"
|
1128
|
+
: get_path_with_pid(ENV['SIGDUMP_PATH'])
|
1129
|
+
|
1130
|
+
require 'sigdump'
|
1131
|
+
Sigdump.dump(dump_filepath)
|
1132
|
+
|
1133
|
+
$log.info "dump to #{dump_filepath}."
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
def self.get_path_with_pid(raw_path)
|
1137
|
+
path = Pathname.new(raw_path)
|
1138
|
+
path.sub_ext("-#{Process.pid}#{path.extname}").to_s
|
1139
|
+
end
|
1140
|
+
end
|
1057
1141
|
end
|
data/lib/fluent/system_config.rb
CHANGED
@@ -22,7 +22,7 @@ module Fluent
|
|
22
22
|
include Configurable
|
23
23
|
|
24
24
|
SYSTEM_CONFIG_PARAMETERS = [
|
25
|
-
:workers, :root_dir, :log_level,
|
25
|
+
:workers, :restart_worker_interval, :root_dir, :log_level,
|
26
26
|
:suppress_repeated_stacktrace, :emit_error_log_interval, :suppress_config_dump,
|
27
27
|
:log_event_verbose, :ignore_repeated_log_interval, :ignore_same_log_interval,
|
28
28
|
:without_source, :rpc_endpoint, :enable_get_dump, :process_name,
|
@@ -32,6 +32,7 @@ module Fluent
|
|
32
32
|
]
|
33
33
|
|
34
34
|
config_param :workers, :integer, default: 1
|
35
|
+
config_param :restart_worker_interval, :time, default: 0
|
35
36
|
config_param :root_dir, :string, default: nil
|
36
37
|
config_param :log_level, :enum, list: [:trace, :debug, :info, :warn, :error, :fatal], default: 'info'
|
37
38
|
config_param :suppress_repeated_stacktrace, :bool, default: nil
|
data/lib/fluent/version.rb
CHANGED
data/lib/fluent/winsvc.rb
CHANGED
data/test/command/test_ctl.rb
CHANGED
@@ -7,7 +7,6 @@ require 'fluent/command/ctl'
|
|
7
7
|
|
8
8
|
class TestFluentdCtl < ::Test::Unit::TestCase
|
9
9
|
def assert_win32_event(event_name, command, pid_or_svcname)
|
10
|
-
command, event_suffix = data
|
11
10
|
event = Win32::Event.new(event_name)
|
12
11
|
ipc = Win32::Ipc.new(event.handle)
|
13
12
|
ret = Win32::Ipc::TIMEOUT
|
@@ -589,6 +589,39 @@ CONF
|
|
589
589
|
)
|
590
590
|
end
|
591
591
|
|
592
|
+
sub_test_case "YAML config format" do
|
593
|
+
test 'success to start the number of workers specified in configuration' do
|
594
|
+
conf = <<'CONF'
|
595
|
+
system:
|
596
|
+
workers: 2
|
597
|
+
root_dir: "#{@root_path}"
|
598
|
+
config:
|
599
|
+
- source:
|
600
|
+
$type: dummy
|
601
|
+
$id: !fluent/s "dummy.#{worker_id}" # check worker_id works or not with actual command
|
602
|
+
$label: '@dummydata'
|
603
|
+
tag: dummy
|
604
|
+
dummy: !fluent/json {"message": !fluent/s "yay from #{hostname}!"}
|
605
|
+
|
606
|
+
- label:
|
607
|
+
$name: '@dummydata'
|
608
|
+
config:
|
609
|
+
- match:
|
610
|
+
$tag: dummy
|
611
|
+
$type: "null"
|
612
|
+
$id: blackhole
|
613
|
+
CONF
|
614
|
+
conf_path = create_conf_file('workers1.yaml', conf)
|
615
|
+
assert Dir.exist?(@root_path)
|
616
|
+
|
617
|
+
assert_log_matches(
|
618
|
+
create_cmdline(conf_path),
|
619
|
+
"#0 fluentd worker is now running worker=0",
|
620
|
+
"#1 fluentd worker is now running worker=1"
|
621
|
+
)
|
622
|
+
end
|
623
|
+
end
|
624
|
+
|
592
625
|
test 'success to start the number of workers specified by command line option' do
|
593
626
|
conf = <<CONF
|
594
627
|
<system>
|
@@ -19,6 +19,7 @@ module Fluent::Config
|
|
19
19
|
@system_config = nil
|
20
20
|
@cl_opt = {
|
21
21
|
wokers: nil,
|
22
|
+
restart_worker_interval: nil,
|
22
23
|
root_dir: nil,
|
23
24
|
log: FakeLoggerInitializer.new,
|
24
25
|
log_level: Fluent::Log::LEVEL_INFO,
|
@@ -72,6 +73,7 @@ module Fluent::Config
|
|
72
73
|
sc = Fluent::SystemConfig.new(conf)
|
73
74
|
sc.overwrite_variables(**s.for_system_config)
|
74
75
|
assert_equal(1, sc.workers)
|
76
|
+
assert_equal(0, sc.restart_worker_interval)
|
75
77
|
assert_nil(sc.root_dir)
|
76
78
|
assert_equal(Fluent::Log::LEVEL_INFO, sc.log_level)
|
77
79
|
assert_nil(sc.suppress_repeated_stacktrace)
|
@@ -88,6 +90,7 @@ module Fluent::Config
|
|
88
90
|
|
89
91
|
data(
|
90
92
|
'workers' => ['workers', 3],
|
93
|
+
'restart_worker_interval' => ['restart_worker_interval', 60],
|
91
94
|
'root_dir' => ['root_dir', File.join(TMP_DIR, 'root')],
|
92
95
|
'log_level' => ['log_level', 'error'],
|
93
96
|
'suppress_repeated_stacktrace' => ['suppress_repeated_stacktrace', true],
|
@@ -174,7 +177,6 @@ module Fluent::Config
|
|
174
177
|
</log>
|
175
178
|
</system>
|
176
179
|
EOS
|
177
|
-
s = FakeSupervisor.new
|
178
180
|
sc = Fluent::SystemConfig.new(conf)
|
179
181
|
assert_equal(3, sc.log.rotate_age)
|
180
182
|
end
|
data/test/config/test_types.rb
CHANGED
@@ -190,7 +190,7 @@ class TestConfigTypes < ::Test::Unit::TestCase
|
|
190
190
|
data("val" => [:val, 'val'],
|
191
191
|
"v" => [:v, 'v'],
|
192
192
|
"value" => [:value, 'value'])
|
193
|
-
test 'enum' do |(expected, val
|
193
|
+
test 'enum' do |(expected, val)|
|
194
194
|
assert_equal expected, Config::ENUM_TYPE.call(val, {list: [:val, :value, :v]})
|
195
195
|
end
|
196
196
|
|
@@ -21,12 +21,20 @@ class IntailIOHandlerTest < Test::Unit::TestCase
|
|
21
21
|
@file.unlink rescue nil
|
22
22
|
end
|
23
23
|
|
24
|
+
def create_target_info
|
25
|
+
Fluent::Plugin::TailInput::TargetInfo.new(@file.path, Fluent::FileWrapper.stat(@file.path).ino)
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_watcher
|
29
|
+
Fluent::Plugin::TailInput::TailWatcher.new(create_target_info, nil, nil, nil, nil, nil, nil, nil, nil)
|
30
|
+
end
|
31
|
+
|
24
32
|
test '#on_notify load file content and passed it to receive_lines method' do
|
25
33
|
text = "this line is test\ntest line is test\n"
|
26
34
|
@file.write(text)
|
27
35
|
@file.close
|
28
36
|
|
29
|
-
watcher =
|
37
|
+
watcher = create_watcher
|
30
38
|
|
31
39
|
update_pos = 0
|
32
40
|
|
@@ -61,7 +69,7 @@ class IntailIOHandlerTest < Test::Unit::TestCase
|
|
61
69
|
|
62
70
|
update_pos = 0
|
63
71
|
|
64
|
-
watcher =
|
72
|
+
watcher = create_watcher
|
65
73
|
stub(watcher).pe do
|
66
74
|
pe = 'position_file'
|
67
75
|
stub(pe).read_pos { 0 }
|
@@ -92,7 +100,7 @@ class IntailIOHandlerTest < Test::Unit::TestCase
|
|
92
100
|
|
93
101
|
update_pos = 0
|
94
102
|
|
95
|
-
watcher =
|
103
|
+
watcher = create_watcher
|
96
104
|
stub(watcher).pe do
|
97
105
|
pe = 'position_file'
|
98
106
|
stub(pe).read_pos { 0 }
|
@@ -107,6 +115,7 @@ class IntailIOHandlerTest < Test::Unit::TestCase
|
|
107
115
|
end
|
108
116
|
|
109
117
|
r.on_notify
|
118
|
+
assert_equal text.bytesize, update_pos
|
110
119
|
assert_equal 8, returned_lines[0].size
|
111
120
|
end
|
112
121
|
|
@@ -118,7 +127,7 @@ class IntailIOHandlerTest < Test::Unit::TestCase
|
|
118
127
|
|
119
128
|
update_pos = 0
|
120
129
|
|
121
|
-
watcher =
|
130
|
+
watcher = create_watcher
|
122
131
|
stub(watcher).pe do
|
123
132
|
pe = 'position_file'
|
124
133
|
stub(pe).read_pos { 0 }
|
@@ -133,6 +142,7 @@ class IntailIOHandlerTest < Test::Unit::TestCase
|
|
133
142
|
end
|
134
143
|
|
135
144
|
r.on_notify
|
145
|
+
assert_equal text.bytesize, update_pos
|
136
146
|
assert_equal 5, returned_lines[0].size
|
137
147
|
assert_equal 3, returned_lines[1].size
|
138
148
|
end
|
@@ -40,10 +40,6 @@ class IntailPositionFileTest < Test::Unit::TestCase
|
|
40
40
|
|
41
41
|
test '.load' do
|
42
42
|
write_data(@file, TEST_CONTENT)
|
43
|
-
paths = {
|
44
|
-
"valid_path" => Fluent::Plugin::TailInput::TargetInfo.new("valid_path", 1),
|
45
|
-
"inode23bit" => Fluent::Plugin::TailInput::TargetInfo.new("inode23bit", 2),
|
46
|
-
}
|
47
43
|
Fluent::Plugin::TailInput::PositionFile.load(@file, false, TEST_CONTENT_PATHS, **{logger: $log})
|
48
44
|
|
49
45
|
@file.seek(0)
|
@@ -146,11 +142,6 @@ class IntailPositionFileTest < Test::Unit::TestCase
|
|
146
142
|
sub_test_case '#load' do
|
147
143
|
test 'compact invalid and convert 32 bit inode value' do
|
148
144
|
write_data(@file, TEST_CONTENT)
|
149
|
-
invalid_path = "invalidpath100000000000000000000000000000000"
|
150
|
-
paths = TEST_CONTENT_PATHS.merge({
|
151
|
-
invalid_path => Fluent::Plugin::TailInput::TargetInfo.new(invalid_path, 0),
|
152
|
-
"unwatched" => Fluent::Plugin::TailInput::TargetInfo.new("unwatched", 0),
|
153
|
-
})
|
154
145
|
Fluent::Plugin::TailInput::PositionFile.load(@file, false, TEST_CONTENT_PATHS, **{logger: $log})
|
155
146
|
|
156
147
|
@file.seek(0)
|
@@ -322,58 +313,4 @@ class IntailPositionFileTest < Test::Unit::TestCase
|
|
322
313
|
assert_equal 2, f.read_inode
|
323
314
|
end
|
324
315
|
end
|
325
|
-
|
326
|
-
sub_test_case "TargetInfo equality rules" do
|
327
|
-
sub_test_case "== operator" do
|
328
|
-
def test_equal
|
329
|
-
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
330
|
-
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1235)
|
331
|
-
|
332
|
-
assert_equal t1, t2
|
333
|
-
end
|
334
|
-
|
335
|
-
def test_not_equal
|
336
|
-
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
337
|
-
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test2", 1234)
|
338
|
-
|
339
|
-
assert_not_equal t1, t2
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
sub_test_case "eql? method" do
|
344
|
-
def test_eql?
|
345
|
-
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
346
|
-
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test", 5321)
|
347
|
-
|
348
|
-
assert do
|
349
|
-
t1.eql? t2
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
def test_not_eql?
|
354
|
-
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test2", 1234)
|
355
|
-
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test3", 1234)
|
356
|
-
|
357
|
-
assert do
|
358
|
-
!t1.eql? t2
|
359
|
-
end
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
sub_test_case "hash" do
|
364
|
-
def test_equal
|
365
|
-
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
366
|
-
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test", 7321)
|
367
|
-
|
368
|
-
assert_equal t1.hash, t2.hash
|
369
|
-
end
|
370
|
-
|
371
|
-
def test_not_equal
|
372
|
-
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
373
|
-
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test2", 1234)
|
374
|
-
|
375
|
-
assert_not_equal t1.hash, t2.hash
|
376
|
-
end
|
377
|
-
end
|
378
|
-
end
|
379
316
|
end
|
@@ -110,6 +110,10 @@ class SocketCacheTest < Test::Unit::TestCase
|
|
110
110
|
end
|
111
111
|
|
112
112
|
sub_test_case 'purge_obsolete_socks' do
|
113
|
+
def teardown
|
114
|
+
Timecop.return
|
115
|
+
end
|
116
|
+
|
113
117
|
test 'delete key in inactive_socks' do
|
114
118
|
c = Fluent::Plugin::ForwardOutput::SocketCache.new(10, $log)
|
115
119
|
sock = mock!.close { 'closed' }.subject
|
@@ -134,7 +138,7 @@ class SocketCacheTest < Test::Unit::TestCase
|
|
134
138
|
c.checkin(sock)
|
135
139
|
|
136
140
|
# wait timeout
|
137
|
-
Timecop.freeze(Time.parse('2016-04-13 14:
|
141
|
+
Timecop.freeze(Time.parse('2016-04-13 14:00:11 +0900'))
|
138
142
|
c.checkout_or('key') { sock2 }
|
139
143
|
|
140
144
|
assert_equal(1, c.instance_variable_get(:@inflight_sockets).size)
|
@@ -145,5 +149,26 @@ class SocketCacheTest < Test::Unit::TestCase
|
|
145
149
|
assert_equal(1, c.instance_variable_get(:@inflight_sockets).size)
|
146
150
|
assert_equal(sock2, c.instance_variable_get(:@inflight_sockets).values.first.sock)
|
147
151
|
end
|
152
|
+
|
153
|
+
test 'should not purge just after checkin and purge after timeout' do
|
154
|
+
Timecop.freeze(Time.parse('2016-04-13 14:00:00 +0900'))
|
155
|
+
|
156
|
+
c = Fluent::Plugin::ForwardOutput::SocketCache.new(10, $log)
|
157
|
+
sock = dont_allow(mock!).close
|
158
|
+
stub(sock).inspect
|
159
|
+
c.checkout_or('key') { sock }
|
160
|
+
|
161
|
+
Timecop.freeze(Time.parse('2016-04-13 14:00:11 +0900'))
|
162
|
+
c.checkin(sock)
|
163
|
+
|
164
|
+
assert_equal(1, c.instance_variable_get(:@available_sockets).size)
|
165
|
+
c.purge_obsolete_socks
|
166
|
+
assert_equal(1, c.instance_variable_get(:@available_sockets).size)
|
167
|
+
|
168
|
+
Timecop.freeze(Time.parse('2016-04-13 14:00:22 +0900'))
|
169
|
+
assert_equal(1, c.instance_variable_get(:@available_sockets).size)
|
170
|
+
c.purge_obsolete_socks
|
171
|
+
assert_equal(0, c.instance_variable_get(:@available_sockets).size)
|
172
|
+
end
|
148
173
|
end
|
149
174
|
end
|