Skip to content

feat(logging): add a setting to panic when add_fields! overwrites a key - #286

Open
LubabaKhalid wants to merge 1 commit into
cloudflare:mainfrom
LubabaKhalid:feat/log-panic-on-overwritten-field
Open

LubabaKhalid wants to merge 1 commit into
cloudflare:mainfrom
LubabaKhalid:feat/log-panic-on-overwritten-field

Conversation

@LubabaKhalid

Copy link
Copy Markdown

Calling add_fields! in a loop without forking the logger adds one level to the logger chain on every call, and a long enough chain overflows the stack when it is dropped. The nesting limit and logger freezing already catch some of these cases, but often the cause is the same key being set over and over.

This adds LoggingSettings::panic_on_field_overwrite (off by default). When it is enabled, add_fields! panics if it sets a key that the current logger already has, including keys inherited from a parent logger. The panic message names the key. Intentional overwrites can opt out per call:

log::add_fields!(allow_overwrite; "request_id" => new_id);

The flag is stored on the logger next to the frozen state, so forked loggers inherit it and test contexts can turn it on with set_logging_settings. The check walks the keys of the logger's existing fields on each add_fields! call, so it is meant as a debugging aid rather than something to leave on in hot paths.

The internal add_log_fields function used by the macro takes an extra allow_overwrite argument. It lives in the #[doc(hidden)] internal module, so this does not change the public API.

Testing

  • New tests for a panic on an overwritten key (including a key inherited by a forked logger) and for allow_overwrite letting the overwrite through.
  • cargo test -p foundations --test logging and the add_fields! doctest.
  • The rest of the foundations tests pass. The panic hook and telemetry init tests rely on process-global state, so I ran those one per process, the way nextest runs them in CI.
  • cargo clippy -p foundations --all-targets with the CI lint flags, cargo check with logging, logging,settings and telemetry alone, and rustfmt --check --edition 2024.

Closes #243

Adding the same key with `add_fields!` again and again without forking
the logger builds a long logger chain, which can overflow the stack when
it is dropped.

Add `LoggingSettings::panic_on_field_overwrite`. When enabled,
`add_fields!` panics if it sets a key that the current logger already
has, including keys inherited from a parent logger. Intentional
overwrites opt out with `add_fields!(allow_overwrite; ...)`.

The flag is stored on the logger, like the frozen state, so forked
loggers inherit it and test contexts can enable it through
`set_logging_settings`.
@LubabaKhalid

Copy link
Copy Markdown
Author

@TheJokr this adds the setting to panic when a log field is overwritten, with an allow_overwrite escape hatch in add_fields!. Could you take a look when you have a moment? Thanks!

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.

Add log setting to panic when field is overwritten

1 participant