Skip to content

Commit

Permalink
in_tail: Fix for unexpected file close after logs rotate in update_wa…
Browse files Browse the repository at this point in the history
…tcher and stop_watcher

Some 'watcher' method is using 'path' as the key in fluentd v1.16.1.
It is strange to manage with path in follow_inode true case.
This patch changed update_watcher and stop_wathcer to use inode as the "key".

Partially fixes #3614 (follow_inode true case)

Signed-off-by: Katuya Kawakami <[email protected]>
Signed-off-by: Masaki Hatada <[email protected]>
  • Loading branch information
kattz-kawa committed Jun 1, 2023
1 parent dc7e4b2 commit 84b1b49
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
30 changes: 23 additions & 7 deletions lib/fluent/plugin/in_tail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,12 @@ def construct_watcher(target_info)
return
end

@tails[path] = tw
if @follow_inodes
@tails[target_info.ino] = tw
else
@tails[path] = tw
end

tw.on_notify
end

Expand All @@ -459,9 +464,17 @@ def stop_watchers(targets_info, immediate: false, unwatched: false, remove_watch
remove_path_from_group_watcher(target_info.path)

if remove_watcher
tw = @tails.delete(target_info.path)
if @follow_inodes
tw = @tails.delete(target_info.ino)
else
tw = @tails.delete(target_info.path)
end
else
tw = @tails[target_info.path]
if @follow_inodes
tw = @tails[target_info.ino]
else
tw = @tails[target_info.path]
end
end
if tw
tw.unwatched = unwatched
Expand Down Expand Up @@ -499,19 +512,22 @@ def update_watcher(target_info, pe)
end
end

rotated_tw = @tails[path]

if @follow_inodes
new_ino = target_info.ino
rotated_target_info = TargetInfo.new(path, pe.read_inode)
rotated_tw = @tails[rotated_target_info.ino]
new_position_entry = @pf[target_info]

if new_position_entry.read_inode == 0
# When follow_inodes is true, it's not cleaned up by refresh_watcher.
# So it should be unwatched here explicitly.
rotated_tw.unwatched = true if rotated_tw
@tails[path] = setup_watcher(target_info, new_position_entry)
@tails[path].on_notify
@tails.delete(rotated_target_info.ino)
@tails[new_ino] = setup_watcher(target_info, new_position_entry)
@tails[new_ino].on_notify
end
else
rotated_tw = @tails[path]
@tails[path] = setup_watcher(target_info, pe)
@tails[path].on_notify
end
Expand Down
6 changes: 3 additions & 3 deletions test/plugin/test_in_tail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2156,13 +2156,13 @@ def test_should_close_watcher_after_rotate_wait
target_info = create_target_info("#{@tmp_dir}/tail.txt")
mock.proxy(Fluent::Plugin::TailInput::TailWatcher).new(target_info, anything, anything, true, true, anything, nil, anything, anything).once
d.run(shutdown: false)
assert d.instance.instance_variable_get(:@tails)[target_info.path]
assert d.instance.instance_variable_get(:@tails)[target_info.ino]

Timecop.travel(now + 10) do
d.instance.instance_eval do
sleep 0.1 until @tails[target_info.path] == nil
sleep 0.1 until @tails[target_info.ino] == nil
end
assert_nil d.instance.instance_variable_get(:@tails)[target_info.path]
assert_nil d.instance.instance_variable_get(:@tails)[target_info.ino]
end
d.instance_shutdown
end
Expand Down

0 comments on commit 84b1b49

Please sign in to comment.