Skip to content
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

[Tracing][Subscriber] Extend root fields with (static) custom fields #2887

Open
gheorghitamutu opened this issue Feb 20, 2024 · 0 comments
Open

Comments

@gheorghitamutu
Copy link

Feature Request

Crates

tracing-subscriber

Motivation

Custom root fields for a log entry (in formatter).

Proposal

At the moment we can customize only fields that are in a span (not the static metadata structure). I'd like to globally set several fields at layer/subscriber initialization and they would be used through the entire logging process for that application.

I know that we can use an option called flatten_event and set it to true to move all the fields for an event at the root level but this requires that every event (along with info!, error!, etc macros) to contain said fields which I don't find it as a reasonable approach (a lot of code repetition and the fields can be easily forgotten to be added in each macro).

I found out that several options were requsted/described in these issues:
#1531
#2670

I'd like to add this feature in a Subscriber because, for my case it was JSON, the formatter is initialized as it follows:

In https://github.com/tokio-rs/tracing/blob/master/tracing-subscriber/src/fmt/fmt_subscriber.rs#L581

    pub fn json(self) -> Subscriber<C, format::JsonFields, format::Format<format::Json, T>, W> {
        Subscriber {
            fmt_event: self.fmt_event.json(),
            fmt_fields: format::JsonFields::new(),
            fmt_span: self.fmt_span,
            make_writer: self.make_writer,
            // always disable ANSI escapes in JSON mode!
            is_ansi: false,
            log_internal_errors: self.log_internal_errors,
            _inner: self._inner,
        }
    }

With self.fmt_event.json() implemented in https://github.com/tokio-rs/tracing/blob/master/tracing-subscriber/src/fmt/format/mod.rs#L685 as:

    pub fn json(self) -> Format<Json, T> {
        Format {
            format: Json::default(),
            timer: self.timer,
            ansi: self.ansi,
            display_target: self.display_target,
            display_timestamp: self.display_timestamp,
            display_level: self.display_level,
            display_thread_id: self.display_thread_id,
            display_thread_name: self.display_thread_name,
            display_filename: self.display_filename,
            display_line_number: self.display_line_number,
        }
    }

What I'm thinking of is that we can add a function to json (or format at general) that can say:

     let file = File::create("myapp.log")?;
     let subscriber = tracing_subscriber::fmt::subscriber()
         .with_thread_names(true)
         .with_target(true)
         .with_root_fields(vec![("a", "value1"), ("b", "value2")])
         .json()
         .with_writer(file)

Or any type of structure passed to function with_root_fields and each custom formatter (json, pretty, compact) can treat them as it does with filename, target, etc:

            if self.display_filename {
                if let Some(filename) = meta.file() {
                    serializer.serialize_entry("filename", filename)?;
                }
            }
.................
            // pseudocode
            if self.custom_root_fields_container_option { // optional, you can just not have elements in container
                for (k,v) in meta.custom_root_fields_container() {
                    serializer.serialize_entry(k, v)?;
                }
            }

If you think this works as a rough proposal I can try and code this and make a PR for a review (also including the tests required).

I could also try coding other alternatives that you might propose to this issue.

Please let me know what you think. Thank you!

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

No branches or pull requests

1 participant