pub trait MakeWriterExt<'a>: MakeWriter<'a> {
    // Provided methods
    fn with_max_level(self, level: Level) -> WithMaxLevel<Self>
       where Self: Sized { ... }
    fn with_min_level(self, level: Level) -> WithMinLevel<Self>
       where Self: Sized { ... }
    fn with_filter<F>(self, filter: F) -> WithFilter<Self, F>
       where Self: Sized,
             F: Fn(&Metadata<'_>) -> bool { ... }
    fn and<B>(self, other: B) -> Tee<Self, B> 
       where Self: Sized,
             B: MakeWriter<'a> + Sized { ... }
    fn or_else<W, B>(self, other: B) -> OrElse<Self, B>
       where Self: MakeWriter<'a, Writer = OptionalWriter<W>> + Sized,
             B: MakeWriter<'a> + Sized,
             W: Write { ... }
}
Available on crate features fmt and std only.
Expand description

Extension trait adding combinators for working with types implementing MakeWriter.

This is not intended to be implemented directly for user-defined MakeWriters; instead, it should be imported when the desired methods are used.

Provided Methods§

source

fn with_max_level(self, level: Level) -> WithMaxLevel<Self>
where Self: Sized,

Wraps self and returns a MakeWriter that will only write output for events at or below the provided verbosity Level. For instance, Level::TRACE is considered to be _more verbosethanLevel::INFO`.

Events whose level is more verbose than level will be ignored, and no output will be written.

Examples
use tracing::Level;
use tracing_subscriber::fmt::writer::MakeWriterExt;

// Construct a writer that outputs events to `stderr` only if the span or
// event's level is >= WARN (WARN and ERROR).
let mk_writer = std::io::stderr.with_max_level(Level::WARN);

tracing_subscriber::fmt().with_writer(mk_writer).init();

Writing the ERROR and WARN levels to stderr, and everything else to stdout:


let mk_writer = std::io::stderr
    .with_max_level(Level::WARN)
    .or_else(std::io::stdout);

tracing_subscriber::fmt().with_writer(mk_writer).init();

Writing the ERROR level to stderr, the INFO and WARN levels to stdout, and the INFO and DEBUG` levels to a file:

use std::{sync::Arc, fs::File};
let debug_log = Arc::new(File::create("debug.log")?);

let mk_writer = std::io::stderr
    .with_max_level(Level::ERROR)
    .or_else(std::io::stdout
        .with_max_level(Level::INFO)
        .and(debug_log.with_max_level(Level::DEBUG))
    );

tracing_subscriber::fmt().with_writer(mk_writer).init();
source

fn with_min_level(self, level: Level) -> WithMinLevel<Self>
where Self: Sized,

Wraps self and returns a MakeWriter that will only write output for events at or above the provided verbosity Level.

Events whose level is less verbose than level will be ignored, and no output will be written.

Examples
use tracing::Level;
use tracing_subscriber::fmt::writer::MakeWriterExt;

// Construct a writer that outputs events to `stdout` only if the span or
// event's level is <= DEBUG (DEBUG and TRACE).
let mk_writer = std::io::stdout.with_min_level(Level::DEBUG);

tracing_subscriber::fmt().with_writer(mk_writer).init();

This can be combined with MakeWriterExt::with_max_level to write only within a range of levels:

// Only write the `DEBUG` and `INFO` levels to stdout.
let mk_writer = std::io::stdout
    .with_max_level(Level::DEBUG)
    .with_min_level(Level::INFO)
    // Write the `WARN` and `ERROR` levels to stderr.
    .and(std::io::stderr.with_min_level(Level::WARN));

tracing_subscriber::fmt().with_writer(mk_writer).init();
source

fn with_filter<F>(self, filter: F) -> WithFilter<Self, F>
where Self: Sized, F: Fn(&Metadata<'_>) -> bool,

Wraps self with a predicate that takes a span or event’s Metadata and returns a bool. The returned MakeWriter’s MakeWriter::make_writer_for method will check the predicate to determine if a writer should be produced for a given span or event.

If the predicate returns false, the wrapped MakeWriter’s make_writer_for will return OptionalWriter::none. Otherwise, it calls the wrapped MakeWriter’s make_writer_for method, and returns the produced writer.

This can be used to filter an output based on arbitrary Metadata parameters.

Examples

Writing events with a specific target to an HTTP access log, and other events to stdout:

use tracing_subscriber::fmt::writer::MakeWriterExt;
use std::{sync::Arc, fs::File};
let access_log = Arc::new(File::create("access.log")?);

let mk_writer = access_log
    // Only write events with the target "http::access_log" to the
    // access log file.
    .with_filter(|meta| meta.target() == "http::access_log")
    // Write events with all other targets to stdout.
    .or_else(std::io::stdout);

tracing_subscriber::fmt().with_writer(mk_writer).init();

Conditionally enabling or disabling a log file:

use tracing_subscriber::fmt::writer::MakeWriterExt;
use std::{
    sync::{Arc, atomic::{AtomicBool, Ordering}},
    fs::File,
};

static DEBUG_LOG_ENABLED: AtomicBool = AtomicBool::new(false);

// Create the debug log file
let debug_file = Arc::new(File::create("debug.log")?)
    // Enable the debug log only if the flag is enabled.
    .with_filter(|_| DEBUG_LOG_ENABLED.load(Ordering::Acquire));

// Always write to stdout
let mk_writer = std::io::stdout
    // Write to the debug file if it's enabled
    .and(debug_file);

tracing_subscriber::fmt().with_writer(mk_writer).init();

// ...

// Later, we can toggle on or off the debug log file.
DEBUG_LOG_ENABLED.store(true, Ordering::Release);
source

fn and<B>(self, other: B) -> Tee<Self, B>
where Self: Sized, B: MakeWriter<'a> + Sized,

Combines self with another type implementing MakeWriter, returning a new MakeWriter that produces writers that write to both outputs.

If writing to either writer returns an error, the returned writer will return that error. However, both writers will still be written to before the error is returned, so it is possible for one writer to fail while the other is written to successfully.

Examples
use tracing_subscriber::fmt::writer::MakeWriterExt;

// Construct a writer that outputs events to `stdout` *and* `stderr`.
let mk_writer = std::io::stdout.and(std::io::stderr);

tracing_subscriber::fmt().with_writer(mk_writer).init();

and can be used in conjunction with filtering combinators. For example, if we want to write to a number of outputs depending on the level of an event, we could write:

use tracing::Level;
use std::{sync::Arc, fs::File};
let debug_log = Arc::new(File::create("debug.log")?);

// Write everything to the debug log.
let mk_writer = debug_log
    // Write the `ERROR` and `WARN` levels to stderr.
    .and(std::io::stderr.with_max_level(Level::WARN))
    // Write `INFO` to `stdout`.
    .and(std::io::stdout
        .with_max_level(Level::INFO)
        .with_min_level(Level::INFO)
    );

tracing_subscriber::fmt().with_writer(mk_writer).init();
source

fn or_else<W, B>(self, other: B) -> OrElse<Self, B>
where Self: MakeWriter<'a, Writer = OptionalWriter<W>> + Sized, B: MakeWriter<'a> + Sized, W: Write,

Combines self with another type implementing MakeWriter, returning a new MakeWriter that calls other’s make_writer if self’s make_writer returns OptionalWriter::none.

Examples
use tracing::Level;
use tracing_subscriber::fmt::writer::MakeWriterExt;

// Produces a writer that writes to `stderr` if the level is >= WARN,
// or returns `OptionalWriter::none()` otherwise.
let stderr = std::io::stderr.with_max_level(Level::WARN);

// If the `stderr` `MakeWriter` is disabled by the max level filter,
// write to stdout instead:
let mk_writer = stderr.or_else(std::io::stdout);

tracing_subscriber::fmt().with_writer(mk_writer).init();

Implementors§

source§

impl<'a, M> MakeWriterExt<'a> for M
where M: MakeWriter<'a>,