Expand description

Convenience trait and functions to ease tracing-subscriber initialization.

Program configuration can come from multiple sources. This crate supplies the TracingConfig trait to allow the grouping of tracing-subscriber initialization related items.

For example, I often have some configuration from the command line (quiet and verbose flags), some configuration from a configuration file, and some configuration (secrets) loaded from external sources. I implement this trait on a struct to collect the tracing-subscriber related configuration, then use functions such as full_filtered to configure layers as appropriate.

There are also convenience functions such as set_default that will setup a Registry, add the given vector of Layer, and initialize per the upstream functions of the same name.

Example

#[derive(Clone, Debug, Default)]
struct TomlConfig {
    // ...other configuration
    tracing: Tracing,
    tracing_file: TracingFile,
    // ...other configuration
}

#[derive(Clone, Debug, Default)]
struct Tracing {
    target: bool,
    thread_ids: bool,
    thread_names: bool,
    line_numbers: bool,
}

impl TracingConfig for Tracing {
    // Normally pulled from command line arguments, i.e. prog -qq
    fn quiet(&self) -> u8 {
        0
    }

    // Normally pulled from command line arguments, i.e. prog -vv
    fn verbose(&self) -> u8 {
        2
    }

    fn with_line_number(&self) -> bool {
        self.line_numbers
    }

    fn with_target(&self) -> bool {
        self.target
    }

    fn with_thread_ids(&self) -> bool {
        self.thread_ids
    }

    fn with_thread_names(&self) -> bool {
        self.thread_names
    }
}

#[derive(Clone, Debug, Default)]
struct TracingFile;

impl TracingConfig for TracingFile {
    fn quiet(&self) -> u8 {
        0
    }

    fn verbose(&self) -> u8 {
        3
    }

    fn with_ansi(&self) -> bool {
        false
    }
}

// Load configuration and pull out the tracing specific.
let toml_config = TomlConfig::default();
let tracing_config = toml_config.tracing;
let tracing_file_config = toml_config.tracing_file;

// Setup a full format, filtered layer.  The filtering is set based on the quiet
// and verbose values from the configuration
let layer = full_filtered(&tracing_config);

// Setup a second full format layer to write to a file.  Use the non-filtered
// version when you wish to modify items such as the writer, or the time format.
// You can also chose to ignore the generated level filter and apply your own.
let file = File::create("trace.log")?;
let (file_layer, level_filter) = full(&tracing_file_config);
let file_layer = file_layer.with_writer(file).with_filter(level_filter);

// Create a Registry, add the layers, and set this subscriber as the default
// for this scope
let _unused = set_default(vec![layer.boxed(), file_layer.boxed()]);

// Create a new span and enter it.
let span = span!(Level::INFO, "a new span");
let _enter = span.enter();

// Trace away...
info!("info level");

Re-exports

  • pub use time::format_description::well_known::Iso8601;
  • pub use time::format_description::well_known::Rfc2822;
  • pub use time::format_description::well_known::Rfc3339;
  • pub use tracing_subscriber::fmt::time::OffsetTime;
  • pub use tracing_subscriber::fmt::time::SystemTime;
  • pub use tracing_subscriber::fmt::time::Uptime;
  • pub use tracing_subscriber::fmt::time::UtcTime;
  • pub use tracing_subscriber::Layer;

Traits

Functions