diff --git a/lib/fluent/plugin/in_tail.rb b/lib/fluent/plugin/in_tail.rb index 6e59a2014f..0d9f78cac7 100644 --- a/lib/fluent/plugin/in_tail.rb +++ b/lib/fluent/plugin/in_tail.rb @@ -406,35 +406,28 @@ def setup_watcher(target_info, pe) def construct_watcher(target_info) path = target_info.path + + begin + ino = Fluent::FileWrapper.stat(path).ino + rescue Errno::ENOENT, Errno::EACCES + $log.warn "stat() for #{path} failed. Continuing without tailing it." + return + end + pe = nil if @pf pe = @pf[target_info] - if @read_from_head && pe.read_inode.zero? - begin - pe.update(Fluent::FileWrapper.stat(path).ino, 0) - rescue Errno::ENOENT, Errno::EACCES - $log.warn "stat() for #{path} failed. Continuing without tailing it." - end - end + pe.update(ino, 0) if @read_from_head && pe.read_inode.zero? end begin tw = setup_watcher(target_info, pe) + @tails[path] = tw + tw.on_notify rescue WatcherSetupError => e log.warn "Skip #{path} because unexpected setup error happens: #{e}" return end - - begin - target_info = TargetInfo.new(path, Fluent::FileWrapper.stat(path).ino) - @tails[path] = tw - tw.on_notify - rescue Errno::ENOENT, Errno::EACCES => e - $log.warn "stat() for #{path} failed with #{e.class.name}. Drop tail watcher for now." - # explicitly detach and unwatch watcher `tw`. - tw.unwatched = true - detach_watcher(tw, target_info.ino, false) - end end def start_watchers(targets_info) diff --git a/test/plugin/test_in_tail.rb b/test/plugin/test_in_tail.rb index 695bfe67e9..6cdb16c113 100644 --- a/test/plugin/test_in_tail.rb +++ b/test/plugin/test_in_tail.rb @@ -2171,14 +2171,15 @@ def test_ENOENT_error_after_setup_watcher 'format' => 'none', }) d = create_driver(config) - mock.proxy(d.instance).setup_watcher(anything, anything) do |tw| + mock.proxy(d.instance).existence_path do |hash| cleanup_file(path) - tw - end + hash + end.at_least(1) assert_nothing_raised do d.run(shutdown: false) {} end - assert($log.out.logs.any?{|log| log.include?("stat() for #{path} failed with Errno::ENOENT. Drop tail watcher for now.\n") }) + assert($log.out.logs.any?{|log| log.include?("stat() for #{path} failed. Continuing without tailing it.\n") }, + $log.out.logs.join("\n")) ensure d.instance_shutdown if d && d.instance end @@ -2196,14 +2197,15 @@ def test_EACCES_error_after_setup_watcher 'format' => 'none', }) d = create_driver(config, false) - mock.proxy(d.instance).setup_watcher(anything, anything) do |tw| + mock.proxy(d.instance).existence_path do |hash| FileUtils.chmod(0000, "#{TMP_DIR}/noaccess") - tw - end + hash + end.at_least(1) assert_nothing_raised do d.run(shutdown: false) {} end - assert($log.out.logs.any?{|log| log.include?("stat() for #{path} failed with Errno::EACCES. Drop tail watcher for now.\n") }) + assert($log.out.logs.any?{|log| log.include?("stat() for #{path} failed. Continuing without tailing it.\n") }, + $log.out.logs.join("\n")) end ensure d.instance_shutdown if d && d.instance