LoggerConfig

Trait LoggerConfig 

Source
pub trait LoggerConfig: Parser {
    // Provided methods
    fn bypass_log_init(&self) -> bool { ... }
    fn default_log_level(&self) -> LevelFilter { ... }
    fn default_log_format<S, N>(
        &self,
    ) -> impl FormatEvent<S, N> + Send + Sync + 'static
       where S: Subscriber + for<'a> LookupSpan<'a>,
             N: for<'writer> FormatFields<'writer> + 'static { ... }
    fn default_log_writer(
        &self,
    ) -> impl for<'writer> MakeWriter<'writer> + Send + Sync + 'static { ... }
    fn default_log_layer(
        &self,
    ) -> Box<dyn Layer<Registry> + Send + Sync + 'static> { ... }
}
Expand description

automatic tracing & tracing_subscriber configuration

Available configuration for the Logger trait.

Default implementations are what you’d expect. Use this derive macro for typical use cases.

§Examples

#[derive(LoggerDefault)]
#[log_format(full)]
#[log_level(entrypoint::LevelFilter::DEBUG)]
#[log_writer(std::io::stdout)]
struct Args {}

#[entrypoint::entrypoint]
fn main(args: Args) -> anyhow::Result<()> {
    // logs are ready to use
    info!("hello!");
}

For advanced customization requirements, refer to LoggerConfig::bypass_log_init.

Provided Methods§

Source

fn bypass_log_init(&self) -> bool

hook to disable/enable automatic initialization

This disrupts automatic initialization so that completely custom Layers can be provided to Logger::log_init. This is intended only for advanced use cases, such as:

  1. multiple Layers are required
  2. a reload handle needs to be kept accessible

Default behvaior (false) is to call Logger::log_init on startup and register the default layer provided by LoggerConfig::default_log_layer.

Overriding this to true will not automatically call Logger::log_init on startup. All other defaults provided by the LoggerConfig trait methods are ignored. The application is then required to directly call Logger::log_init with explicitly provided layer(s).

§Examples
struct Args {}

impl entrypoint::LoggerConfig for Args {
    fn bypass_log_init(&self) -> bool { true }
}

#[entrypoint::entrypoint]
fn main(args: Args) -> anyhow::Result<()> {
    // logging hasn't been configured yet
    assert!(!enabled!(entrypoint::Level::ERROR));

    // must manually config/init logging
    let (layer, reload_handle) = reload::Layer::new(
        tracing_subscriber::fmt::Layer::default()
            .event_format(args.default_log_format())
            .with_writer(args.default_log_writer())
            .with_filter(args.default_log_level()),
    );
    let args = args.log_init(Some(vec![layer.boxed()]))?;

    // OK... now logging should work
    assert!( enabled!(entrypoint::Level::ERROR));
    assert!(!enabled!(entrypoint::Level::TRACE));

    // we've maintained direct access to the layer and reload handle
    let _ = reload_handle.modify(|layer| *layer.filter_mut() = entrypoint::LevelFilter::TRACE);
    assert!( enabled!(entrypoint::Level::TRACE));
}
Source

fn default_log_level(&self) -> LevelFilter

define the default tracing_subscriber LevelFilter

Defaults to DEFAULT_MAX_LEVEL.

This can be easily set with convenience macros.

§Examples
struct Args {
    /// allow user to pass in debug level
    #[arg(long)]
    default_log_level: LevelFilter,
}

impl entrypoint::LoggerConfig for Args {
    fn default_log_level(&self) -> LevelFilter {
        self.default_log_level.clone()
    }
}
Source

fn default_log_format<S, N>( &self, ) -> impl FormatEvent<S, N> + Send + Sync + 'static
where S: Subscriber + for<'a> LookupSpan<'a>, N: for<'writer> FormatFields<'writer> + 'static,

define the default tracing_subscriber Format

Defaults to Format::default.

This can be easily set with convenience macros.

§Examples
impl entrypoint::LoggerConfig for Args {
    fn default_log_format<S,N>(&self) -> impl FormatEvent<S,N> + Send + Sync + 'static
    where
        S: Subscriber + for<'a> LookupSpan<'a>,
        N: for<'writer> FormatFields<'writer> + 'static,
    {
        Format::default().pretty()
    }
}
Source

fn default_log_writer( &self, ) -> impl for<'writer> MakeWriter<'writer> + Send + Sync + 'static

define the default tracing_subscriber MakeWriter

Defaults to std::io::stdout.

This can be easily set with convenience macros.

§Examples
impl entrypoint::LoggerConfig for Args {
    fn default_log_writer(&self) -> impl for<'writer> MakeWriter<'writer> + Send + Sync + 'static {
        std::io::stderr
    }
}
Source

fn default_log_layer(&self) -> Box<dyn Layer<Registry> + Send + Sync + 'static>

define the default tracing_subscriber Layer to register

This method uses the defaults defined by LoggerConfig methods and composes a default Layer to register.

You probably don’t want to override this default implementation.

  1. For standard customization, override these other trait methods:
  2. Minor/static customization(s) can be achieved by overriding this method… though this might warrant moving to the ‘advanced requirements’ option below.
  3. Otherwise, for advanced requirements, refer to LoggerConfig::bypass_log_init.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§