From 1c1ef8ecf3cba3fa7d5da6b901ba3baff2f439ef Mon Sep 17 00:00:00 2001 From: Takuro Ashie Date: Tue, 13 Apr 2021 10:14:30 +0900 Subject: [PATCH] in_tail: Fix an incorrect error handling This commit fixes the following error reported at #3327, it will occur when a file is removed after calling setup_watcher and before registering the created watcher. 2021-04-12 16:00:21 -0700 [warn]: stat() for /var/log/containers/obfuscated_container_xxx_1.log failed with ENOENT. Drop tail watcher for now. 2021-04-12 16:00:21 -0700 [error]: unexpected error error_class=NoMethodError error="undefined method `each_value' for #\nDid you mean? each_slice" 2021-04-12 16:00:21 -0700 [error]: /usr/local/lib/ruby/gems/2.7.0/gems/fluentd-1.12.2/lib/fluent/plugin/in_tail.rb:428:in `stop_watchers' 2021-04-12 16:00:21 -0700 [error]: /usr/local/lib/ruby/gems/2.7.0/gems/fluentd-1.12.2/lib/fluent/plugin/in_tail.rb:422:in `rescue in block in start_watchers' 2021-04-12 16:00:21 -0700 [error]: /usr/local/lib/ruby/gems/2.7.0/gems/fluentd-1.12.2/lib/fluent/plugin/in_tail.rb:416:in `block in start_watchers' 2021-04-12 16:00:21 -0700 [error]: /usr/local/lib/ruby/gems/2.7.0/gems/fluentd-1.12.2/lib/fluent/plugin/in_tail.rb:396:in `each_value' 2021-04-12 16:00:21 -0700 [error]: /usr/local/lib/ruby/gems/2.7.0/gems/fluentd-1.12.2/lib/fluent/plugin/in_tail.rb:396:in `start_watchers' Signed-off-by: Takuro Ashie --- lib/fluent/plugin/in_tail.rb | 3 ++- test/plugin/test_in_tail.rb | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/fluent/plugin/in_tail.rb b/lib/fluent/plugin/in_tail.rb index f397e765ca..5fa73b6eb7 100644 --- a/lib/fluent/plugin/in_tail.rb +++ b/lib/fluent/plugin/in_tail.rb @@ -419,7 +419,8 @@ def start_watchers(targets_info) rescue Errno::ENOENT $log.warn "stat() for #{target_info.path} failed with ENOENT. Drop tail watcher for now." # explicitly detach and unwatch watcher `tw`. - stop_watchers(target_info, immediate: true, unwatched: true) + tw.unwatched = true + detach_watcher(tw, target_info.ino, false) end } end diff --git a/test/plugin/test_in_tail.rb b/test/plugin/test_in_tail.rb index 94bead49e0..faf737b0bf 100644 --- a/test/plugin/test_in_tail.rb +++ b/test/plugin/test_in_tail.rb @@ -1919,4 +1919,22 @@ def test_skip_refresh_on_startup waiting(5) { sleep 0.1 until d.instance.instance_variable_get(:@tails).keys.size == 1 } d.instance_shutdown end + + def test_ENOENT_error_after_setup_watcher + path = "#{TMP_DIR}/tail.txt" + FileUtils.touch(path) + config = config_element('', '', { + 'format' => 'none', + }) + d = create_driver(config) + mock.proxy(d.instance).setup_watcher(anything, anything) do |tw| + cleanup_file(path) + tw + end + assert_nothing_raised do + d.run(shutdown: false) {} + end + d.instance_shutdown + assert($log.out.logs.any?{|log| log.include?("stat() for #{path} failed with ENOENT. Drop tail watcher for now.\n") }) + end end