tracing icon indicating copy to clipboard operation
tracing copied to clipboard

Filter `field=value` doesn't work.

Open wllenyj opened this issue 4 years ago • 12 comments

Bug Report

Version

master branch cargo build --exmaples

$ cargo --version cargo 1.47.0 (f3c7e066a 2020-08-28)

Platform

Linux 4.9

Crates

Description

When I run the subscriber-filter example like this, it doesn't work like I thought it would.

RUST_LOG=[shave{yak=2}] ../target/debug/examples/subscriber-filter 

Output nothing.

Run like this, it work:

$ RUST_LOG=[shave{yak}] ../target/debug/examples/subscriber-filter 
Jan 10 23:28:31.626 TRACE shave{yak=1}: subscriber_filter::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
Jan 10 23:28:31.626 TRACE shave{yak=1}: subscriber_filter::yak_shave: yak shaved successfully
Jan 10 23:28:31.626 TRACE shave{yak=2}: subscriber_filter::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
Jan 10 23:28:31.626 TRACE shave{yak=2}: subscriber_filter::yak_shave: yak shaved successfully
Jan 10 23:28:31.626 TRACE shave{yak=3}: subscriber_filter::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
Jan 10 23:28:31.627  WARN shave{yak=3}: subscriber_filter::yak_shave: could not locate yak

I tried :

RUST_LOG=[shave{yak=\"2\"}] 
RUST_LOG=[shave{yak='2'}]
RUST_LOG="[shave{yak=\"2\"}]"

none of them worked.

Thanks all.

wllenyj avatar Jan 10 '21 15:01 wllenyj

Ah, I see the issue --- this is an interaction between how the filter is interpreted and the span generated by the #[instrument] macro. #[instrument] records all fields as fmt::Debug, but [shave{yak=2}] creates a filter that expects the numeric value 2, not a value whose fmt::Debug implementation produces the string 2. On the other hand, the filters with quotes expect a string value, not a fmt::Debug value.

To demonstrate the issue, you can try changing the shave function from

#[tracing::instrument]
pub fn shave(yak: usize) -> Result<(), Box<dyn Error + 'static>> {
   // ...
}

to

pub fn shave(yak: usize) -> Result<(), Box<dyn Error + 'static>> {
    let span = tracing::trace_span!("shave", yak);
    let _e = span.enter();
    // ...
}

With the manually created span, yak is recorded as a number. Then, the filter behaves as expected:

$ RUST_LOG="[shave{yak=2}]" cargo run --example subscriber-filter 
    Finished dev [unoptimized + debuginfo] target(s) in 0.10s
     Running `target/debug/examples/subscriber-filter`
Jan 10 10:44:28.502 TRACE shave{yak=2}: subscriber_filter::yak_shave: hello! I'm gonna shave a yak excitement="yay!"
Jan 10 10:44:28.502 TRACE shave{yak=2}: subscriber_filter::yak_shave: yak shaved successfully

We should improve how EnvFilter handles cases like this. It would probably be good to always try matching fmt::Debug output when a Debug value is recorded, even when a primitive type is expected.

hawkw avatar Jan 10 '21 18:01 hawkw

Additional faulty case:

    tracing_subscriber::fmt()
        .with_env_filter(tracing_subscriber::EnvFilter::new("[{x}]=debug"))
        .init();
    tracing::debug!(x="a", "test");

shows the DEBUG log line, but the following doesn't print anything:

    tracing_subscriber::fmt()
        .with_env_filter(tracing_subscriber::EnvFilter::new("[{x=a}]=debug"))
        .init();
    tracing::debug!(x="a", "test");

I tried using x="a", same result.

Yamakaky avatar Feb 16 '21 16:02 Yamakaky

I am seeing the same effect, but looks like the root cause might be different. Seems filters with value somehow don't enable spans?

Ie, if I have a single filter, it doesnit work. If, however, I add a dummy fiter which matches noting, I get output:

image

image

EDIT: this might be just wrong? seems like {nope} just enables all infos

matklad avatar Mar 05 '21 15:03 matklad

I think I'm seeing the same issue as in the original report, where the value recorded for a field comes from a type alias for u64, and I can't seem to filter on that field value with any syntax I've tried.

Has there been any progress on this issue? I see that there's a note about matching on Debug representations vs. literal values in the EnvFilter documentation, but I'm not sure if that's been around since before this issue was filed.

maddiemort avatar Jul 18 '22 12:07 maddiemort

I haven't been able to dig into this properly—and Eliza would probably be able to correct me on this—but most of the progress has gone to https://github.com/CAD97/tracing-filter/, which will be the successor to EnvFilter. I would try and see if you still have this issue with tracing-filter.

davidbarsky avatar Jul 19 '22 15:07 davidbarsky

I've had the same issue as the original issue, but my recorded field is actually the debug representation -- not anything special with numbers or bools. No regex I can use matches the value, and even disabling regex (using EnvFilter::builder) and matching with the exact value fails.

You can see I also tried this with the tracing-filter crate, and I am seeing the same issue there

msdrigg avatar Nov 10 '22 22:11 msdrigg

I would try and see if you still have this issue with tracing-filter.

Unfortunately it looks like tracing-filter only has two filtering implementations at the moment: simple filters, which are too simple to be able to do the kind of filtering that triggers the bug for me; and legacy filters, which are described as "100% bug-for-bug compatible" with the original, and in my testing that held true (this bug appeared there too). So that's not a solution for me, for the time being.

maddiemort avatar Jan 09 '23 11:01 maddiemort

Here's a minimal reproducible example of the filtering issue:

https://github.com/juancampa/tracing-field-filtering-repro

juancampa avatar Jun 10 '23 20:06 juancampa

Has anyone found a good solution to this? My workaround is this:

  1. use a span! macro manually
  2. event!(parent: &span, ...)
  3. let env_filter =
        EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("warn"));
    let log_file = File::create(concat!(env!("CARGO_MANIFEST_DIR"), "/log.txt")).unwrap();
    let fmt_layer = fmt::layer()
        .with_span_events(tracing_subscriber::fmt::format::FmtSpan::NONE) // this is the default
        .with_writer(log_file);
    

Filtering on field values only works for spans, not events, but not the enter & exit events of each span. So the only solution I could find is to output events after nesting them in a span which has the fields I want to filter on.

farnoy avatar Dec 16 '23 14:12 farnoy

I encountered this issue and this syntax worked for me

RUST_LOG="module[span{field=value}]" ./binary

Basically, don't quote the value

seunlanlege avatar Feb 18 '24 15:02 seunlanlege