10000 how to get field value · Issue #3215 · tokio-rs/tracing · GitHub
[go: up one dir, main page]

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

how to get field value #3215

Open
kongbai1996 opened this issue Feb 10, 2025 · 3 comments
Open

how to get field value #3215

kongbai1996 opened this issue Feb 10, 2025 · 3 comments

Comments

@kongbai1996
Copy link

I can get the field name by Field: 8000 :name method, but how to get field value?

@tglane
Copy link
tglane commented Feb 10, 2025

I had the same issue today and found a workaround by using a custom visitor that implements tracing::field::Visit and passed that to tracing::Event::record(&self, visitor: &mut dyn Visit). Maybe that's useful for you too.

But I wonder if there is a good reason why there is no function like Field::value? If this would be something desirable I could take a look at this issue?

@kongbai1996
Copy link
Author

I had the same issue today and found a workaround by using a custom visitor that implements tracing::field::Visit and passed that to tracing::Event::record(&self, visitor: &mut dyn Visit). Maybe that's useful for you too.

How to use it?

@tglane
Copy link
tglane commented Feb 11, 2025

Suppose you want to read the field value from an tracing::Event as an example. Then you could do the following to read the field value from a field with name EXAMPLE into a string:

#[derive(Default)]
struct ExampleVisitor(pub Option<String>);

impl tracing::field::Visit for ExampleVisitor {
    fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) {
        // Mandatory to implement
    }
    
    fn record_str(&mut self, field: &tracing::field::Field, value: &str) {
        if field.name() == "EXAMPLE" {
            // Extract the field value if the name matches our searched field name
            self.0 = Some(value.to_string());
        }
    }
}

struct MyLoggingLayer;

impl<S: tracing::Subscriber> tracing_subscriber::layer::Layer<S> for MyLoggingLayer {
    fn on_event(&self, event: &tracing_core::event::Event<'_>, _ctx: tracing_subscriber::layer::Context<'_, S>) {
        // Listen for logging events in this logging layer
        // Visit the records/fields of the event with out custom visitor
        let my_visitor = ExampleVisitor::default();
        event.record(&mut my_visitor);
        
        if let Some(field_val) = my_visitor.0 {
            println!("Found {} at the field value EXAMPLE", field_val);
        }
    }
}

The idea here is that the event allows you to pass a custom struct that implements tracing::field::Visit to all the internal fields. Here you can use the record_<type you are interested in> function of the trait to visit the types you are interested in and do what ever you want with it after visiting them within Event::record. The same procedure can be applied in the other event handler function provided by tracing_subscriber::layer::Layer. I have to admit that is feels a bit clumsy but it works for me and is the best I could come up with.

I hope this helps 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

2 participants
0