Filtering events

emit supports client-side filtering using a Filter.

Setup

Filters are configured through the setup function at the start of your application by calling emit_when:

extern crate emit;
extern crate emit_term;
fn main() {
    let rt = emit::setup()
        // This filter accepts any event with a level over warn
        .emit_when(emit::level::min_filter(emit::Level::Warn))
        .emit_to(emit_term::stdout())
        .init();

    // Your app code goes here

    rt.blocking_flush(std::time::Duration::from_secs(5));
}

Filters can be combined with and_when and or_when:

extern crate emit;
use emit::Filter;

extern crate emit_term;
fn main() {
    let rt = emit::setup()
        // This filter accepts any event with a level over warn or where the module path is `my_module`
        .emit_when(emit::level::min_filter(emit::Level::Warn)
            .or_when(emit::filter::from_fn(|evt| evt.mdl() == "my_module"))
        )
        .emit_to(emit_term::stdout())
        .init();

    // Your app code goes here

    rt.blocking_flush(std::time::Duration::from_secs(5));
}

Wrapping emitters in filters

You can also wrap an emitter in emit_to in a filter:

extern crate emit;
extern crate emit_term;
use emit::Emitter;

fn main() {
    let rt = emit::setup()
        // Wrap the emitter in a filter instead of setting it independently
        .emit_to(emit_term::stdout()
            .wrap_emitter(emit::emitter::wrapping::from_filter(
                emit::level::min_filter(emit::Level::Warn))
            )
        )
        .init();

    // Your app code goes here

    rt.blocking_flush(std::time::Duration::from_secs(5));
}

Wrapping an emitter in a filter is not the same as providing an emitter and filter independently.

When you use emit_when, the filter may be by-passed using the when control parameter on the emit! or #[span] macros to emit an event even if the filter wouldn't match it. However, the filter specified by emit_when doesn't allow you to filter differently if you specify multiple emitters.

When you wrap an emitter in a filter, the filter cannot by by-passed, but each emitter can use its own filter.

Also see Wrapping emitters for more details on wrappings.

Filtering by level

You can use the level::min_filter function to create a filter that matches events based on their level:

extern crate emit;
extern crate emit_term;
fn main() {
    let rt = emit::setup()
        // This filter accepts any event with a level over warn
        .emit_when(emit::level::min_filter(emit::Level::Warn))
        .emit_to(emit_term::stdout())
        .init();

    // Your app code goes here

    rt.blocking_flush(std::time::Duration::from_secs(5));
}

See the crate docs for more details.

Filtering by module

You can use the level::min_by_path_filter function to create a filter that matches events based on their module path and level:

extern crate emit;
extern crate emit_term;
fn main() {
    let rt = emit::setup()
        // This filter accepts any event with a level over warn
        .emit_when(emit::level::min_by_path_filter([
            (emit::path!("noisy_module"), emit::Level::Warn),
            (emit::path!("noisy_module::important_sub_module"), emit::Level::Info),
            (emit::path!("important_module"), emit::Level::Debug),
        ]))
        .emit_to(emit_term::stdout())
        .init();

    // Your app code goes here

    rt.blocking_flush(std::time::Duration::from_secs(5));
}

See the crate docs for more details.

Filtering spans

When you use the #[span] macro, emit will apply the filter to determine whether the span should be created. If the span doesn't match the filter then no trace context will be generated for it. This isn't the same as trace sampling. emit doesn't have the concept of a trace that is not recorded. See Sampling and filtering traces for more details.