diff --git a/lib/fluent/plugin/in_exec.rb b/lib/fluent/plugin/in_exec.rb index 7f932ee1f2..de4aa4647c 100644 --- a/lib/fluent/plugin/in_exec.rb +++ b/lib/fluent/plugin/in_exec.rb @@ -43,6 +43,8 @@ class ExecInput < Fluent::Plugin::Input config_param :tag, :string, default: nil desc 'The interval time between periodic program runs.' config_param :run_interval, :time, default: nil + desc 'Command (program) execution timeout.' + config_param :command_timeout, :time, default: nil desc 'The default block size to read if parser requires partial read.' config_param :read_block_size, :size, default: 10240 # 10k desc 'The encoding to receive the result of the command, especially for non-ascii characters.' @@ -86,9 +88,9 @@ def start options[:external_encoding] = @encoding if @encoding if @run_interval - child_process_execute(:exec_input, @command, interval: @run_interval, **options, &method(:run)) + child_process_execute(:exec_input, @command, interval: @run_interval, wait_timeout: @command_timeout, **options, &method(:run)) else - child_process_execute(:exec_input, @command, immediate: true, **options, &method(:run)) + child_process_execute(:exec_input, @command, immediate: true, wait_timeout: @command_timeout, **options, &method(:run)) end end diff --git a/test/plugin/test_in_exec.rb b/test/plugin/test_in_exec.rb index f7c9f6d705..59b5461741 100644 --- a/test/plugin/test_in_exec.rb +++ b/test/plugin/test_in_exec.rb @@ -295,4 +295,48 @@ def create_driver(conf) assert_match(/LoadError/, event[2]['message']) end end + sub_test_case 'command_timeout' do + test 'configure command_timeout' do + d = create_driver %[ + command ruby -e "sleep 10" + tag test + run_interval 1s + command_timeout 1s + + @type none + + ] + assert_equal 1.0, d.instance.command_timeout + end + + test 'command_timeout kills long-running child process' do + d = create_driver %[ + command ruby -e "sleep 10" + tag test + run_interval 5s + command_timeout 1s + + @type none + + ] + start_time = Time.now + d.run(timeout: 5) do + sleep 1 # avoid to return test immediately + end + elapsed = Time.now - start_time + assert (elapsed >= 1.0 and elapsed < 5), "command should have been killed by command_timeout" + end + + test 'command_timeout defaults to nil' do + d = create_driver %[ + command ruby -e "puts 'hello'" + tag test + run_interval 1s + + @type none + + ] + assert_nil d.instance.command_timeout + end + end end