Repository navigation
in_tail: register the replacement of a rotated file from the watcher #12784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2536,6 +2536,7 @@ int flb_tail_file_rotated(struct flb_tail_file *file) | |
| flb_tail_scan(ctx->path_list, ctx); | ||
| } | ||
| else { | ||
| file->rotate_replaced = FLB_TRUE; | ||
| tail_signal_manager(file->config); | ||
| } | ||
| } | ||
|
|
@@ -2547,6 +2548,60 @@ int flb_tail_file_rotated(struct flb_tail_file *file) | |
| return 0; | ||
| } | ||
|
|
||
| /* | ||
| * Register the files that replaced rotated files but did not exist yet when | ||
| * the rotation was handled. | ||
| * | ||
| * flb_tail_file_rotated() looks for the replacement right after the rename | ||
| * is detected. A container runtime creates the new file only after the | ||
| * rename (kubelet renames the log, then asks the runtime to reopen it), so | ||
| * that lookup can come too early. The new file is then found by the next | ||
| * path scan, which runs every 'refresh_interval' (60 seconds by default), | ||
| * and if it is rotated again before that scan it is never read at all. | ||
| * | ||
| * A rotated file is checked until its replacement is registered, either here | ||
| * or by flb_tail_file_rotated(), and skipped afterwards. | ||
| * | ||
| * Returns the number of files registered. | ||
| */ | ||
| int flb_tail_file_discover_rotated_replacements(struct flb_tail_config *ctx) | ||
| { | ||
| int ret; | ||
| int count = 0; | ||
| struct stat st; | ||
| struct mk_list *head; | ||
| struct flb_tail_file *file; | ||
|
|
||
| mk_list_foreach(head, &ctx->files_rotated) { | ||
| file = mk_list_entry(head, struct flb_tail_file, _rotate_head); | ||
| if (file->rotate_replaced == FLB_TRUE) { | ||
| continue; | ||
| } | ||
|
|
||
| /* Check if a new file has been created with the original name */ | ||
| ret = tail_file_stat(ctx, file->orig_name, &st); | ||
| if (ret == 0 && st.st_ino != file->inode) { | ||
| if (flb_tail_file_exists(&st, ctx) == FLB_FALSE) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apply If a delayed replacement has an mtime older than
|
||
| flb_plg_debug(ctx->ins, "inode=%"PRIu64" replaced rotated " | ||
| "inode=%"PRIu64" as %s", (uint64_t) st.st_ino, | ||
| file->inode, file->orig_name); | ||
| ret = flb_tail_file_append(file->orig_name, &st, | ||
| FLB_TAIL_STATIC, -1, ctx); | ||
|
Comment on lines
+2588
to
+2589
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a delayed replacement is installed with an old mtime (for example via Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preserve the saved offset for an ignored replacement. Without a database, let a refresh scan exclude an old replacement and save its size, N. If the writer then appends a fresh line before the watcher runs, this call passes
|
||
| if (ret == 0) { | ||
| file->rotate_replaced = FLB_TRUE; | ||
| count++; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (count > 0) { | ||
| tail_signal_manager(ctx); | ||
| } | ||
|
|
||
| return count; | ||
| } | ||
|
|
||
| static int check_purge_deleted_file(struct flb_tail_config *ctx, | ||
| struct flb_tail_file *file, time_t ts) | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With a large supported
rotate_waitand frequent rotations, every old entry remains infiles_rotated, and this loop stats itsorig_nameon everywatcher_intervaltick even after a replacement has already been registered. Multiple retained rotations of one active path therefore produce duplicate filesystem calls, making the callback O(retained rotations) every two seconds and potentially causing substantial CPU/I/O load for high-volume deployments; track unresolved original paths (or otherwise de-duplicate them) rather than polling every historical entry.Useful? React with 👍 / 👎.