Skip to content

Add log rotation functionality as alternative to log truncation#596

Merged
jnovy merged 1 commit intocontainers:mainfrom
jnovy:211
Sep 22, 2025
Merged

Add log rotation functionality as alternative to log truncation#596
jnovy merged 1 commit intocontainers:mainfrom
jnovy:211

Conversation

@jnovy
Copy link
Collaborator

@jnovy jnovy commented Sep 11, 2025

This commit implements comprehensive log rotation functionality for conmon:

  • Add --log-rotate and --log-max-files CLI options
  • Implement rotate_k8s_file() and shift_backup_files() functions
  • Add comprehensive BATS test suite covering rotation and truncation scenarios
  • Maintain backward compatibility with existing truncation behavior
  • Update existing tests to work with new functionality

The log rotation creates backup files (.1, .2, etc.) instead of truncating when --log-rotate is enabled, providing better log preservation.

Fixes: #211

@packit-as-a-service
Copy link

Ephemeral COPR build failed. @containers/packit-build please check.

@jankaluza
Copy link
Member

I'll review that one tomorrow morning, FYI.

Copy link
Member

@jankaluza jankaluza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will give it one more go later, but so far I've finished.

src/cli.c Outdated
{"log-rotate", 0, 0, G_OPTION_ARG_NONE, &opt_log_rotate, "Enable log rotation instead of truncation when log-size-max is reached",
NULL},
{"log-max-files", 0, 0, G_OPTION_ARG_INT, &opt_log_max_files, "Number of backup log files to keep (default: 1)", NULL},
{"log-allowlist-dirs", 0, 0, G_OPTION_ARG_STRING, &opt_log_allowlist_dirs, "Colon-separated list of allowed log directories", NULL},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one needs a documentation in conmon.8.md.

src/cli.c Outdated
fprintf(stderr, "conmon: log-max-files must be non-negative, got %d\n", opt_log_max_files);
exit(EXIT_FAILURE);
}
if (opt_log_max_files > 1000) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking, the limit here is INT_MAX. I understand that 1000 should be enough for everyone, but personally I do not like the artificial limits like that. If someone wants to have 10000 files, why not?

This is definitely not a blocker and my subjective opinion. Just something to consider.

src/cli.c Outdated
{"log-rotate", 0, 0, G_OPTION_ARG_NONE, &opt_log_rotate, "Enable log rotation instead of truncation when log-size-max is reached",
NULL},
{"log-max-files", 0, 0, G_OPTION_ARG_INT, &opt_log_max_files, "Number of backup log files to keep (default: 1)", NULL},
{"log-allowlist-dirs", 0, 0, G_OPTION_ARG_STRING, &opt_log_allowlist_dirs, "Colon-separated list of allowed log directories", NULL},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also thinking if we should use G_OPTION_ARG_STRING_ARRAY here to stay consistent with the rest of the options. The log-allowlist-dirs is the first option where we use colon-separated values while other options allowing multiple values use G_OPTION_ARG_STRING_ARRAY. What do you think?

return -1;

/* Check for embedded null bytes */
if (memchr(path, '\0', strlen(path)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is redundant. The strlen(path) returns length up to first 0, so memchr will never find anything.

}

/* Validate canonical path doesn't escape filesystem boundaries */
if (strstr(canonical_path, "/../") || g_str_has_suffix(canonical_path, "/..") || strcmp(canonical_path, "..") == 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the extra caution here, but after the realpath, the canonical_path will not have any directory traversals. That should be the point of that function. I'm not against keeping it here, but it does not give you any extra safety I think.

gboolean had_errors = FALSE;

/* Enhanced bounds checking to prevent integer overflow and underflow */
if (opt_log_max_files <= 0 || opt_log_max_files > 1000) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the INT_MAX here as well or replace 1000 with definition so it can be later changed in single place if needed.

@jnovy
Copy link
Collaborator Author

jnovy commented Sep 15, 2025

Updated, PTAL @jankaluza


run_conmon --cid "$CTR_ID" --cuuid "$CTR_ID" --runtime "$VALID_PATH" \
--log-path "k8s-file:$allowed_log" \
--log-allowlist-dirs "$allowed_dir" \
Copy link
Member

@jankaluza jankaluza Sep 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also test second --log-allowlist-dirs?

--log-allowlist-dirs "$allowed_dir" \
--log-allowlist-dirs /foo

So we know that multiple options are enabled and /foo does not override the first one.

src/cli.c Outdated
{"log-rotate", 0, 0, G_OPTION_ARG_NONE, &opt_log_rotate, "Enable log rotation instead of truncation when log-size-max is reached",
NULL},
{"log-max-files", 0, 0, G_OPTION_ARG_INT, &opt_log_max_files, "Number of backup log files to keep (default: 1)", NULL},
{"log-allowlist-dirs", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_log_allowlist_dirs, "Allowed log directories", NULL},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading it now, maybe make it singular to be consistent with other options?

log-allowlist-dir

Enable log rotation instead of log truncation. When enabled, log files are rotated
with numbered suffixes (.1, .2, etc.) instead of being truncated when they reach
the maximum size.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the log-allowlist-dir should still be documented here.

This commit implements comprehensive log rotation functionality for conmon:

- Add --log-rotate option to enable rotation instead of truncation
- Add --log-max-files option to specify number of backup files (default: 1)
- Add --log-allowlist-dir option to specify allowed log directories
- Implement rotate_k8s_file() and shift_backup_files() functions
- Add comprehensive BATS test suite covering rotation and truncation scenarios
- Maintain backward compatibility with existing truncation behavior
- Update existing tests to work with new functionality

The log rotation creates backup files (.1, .2, etc.) instead of truncating
when --log-rotate is enabled, providing better log preservation.

Fixes: containers#211

Signed-off-by: Jindrich Novy <jnovy@redhat.com>
@jnovy
Copy link
Collaborator Author

jnovy commented Sep 18, 2025

Updated the option name, commit description and man page, @jankaluza PTAL

@jankaluza
Copy link
Member

LGTM.

I think this is OK from the code point of view and the test coverage is also solid.

@jnovy jnovy merged commit d3d5d68 into containers:main Sep 22, 2025
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve --log-size-max handling

2 participants