Trait Drain

Source
pub trait Drain {
    type Ok;
    type Err;

Show 15 methods // Required method fn log( &self, record: &Record<'_>, values: &OwnedKVList, ) -> Result<Self::Ok, Self::Err>; // Provided methods fn flush(&self) -> Result<(), FlushError> { ... } fn is_enabled(&self, level: Level) -> bool { ... } fn is_critical_enabled(&self) -> bool { ... } fn is_error_enabled(&self) -> bool { ... } fn is_warning_enabled(&self) -> bool { ... } fn is_info_enabled(&self) -> bool { ... } fn is_debug_enabled(&self) -> bool { ... } fn is_trace_enabled(&self) -> bool { ... } fn map<F, R>(self, f: F) -> R where Self: Sized, F: FnOnce(Self) -> R { ... } fn filter<F>(self, f: F) -> Filter<Self, F> where Self: Sized, F: FilterFn { ... } fn filter_level(self, level: Level) -> LevelFilter<Self> where Self: Sized { ... } fn map_err<F, E>(self, f: F) -> MapError<Self, E> where Self: Sized, F: MapErrFn<Self::Err, E> { ... } fn ignore_res(self) -> IgnoreResult<Self> where Self: Sized { ... } fn fuse(self) -> Fuse<Self> where Self::Err: Debug, Self: Sized { ... }
}
Expand description

Logging drain

Drains typically mean destination for logs, but slog generalizes the term.

Drains are responsible for handling logging statements (Records) from Loggers associated with them: filtering, modifying, formatting and writing the log records into given destination(s).

It’s a typical pattern to parametrize Drains over Drain traits to allow composing Drains.

Implementing this trait allows writing custom Drains. Slog users should not be afraid of implementing their own Drains. Any custom log handling logic should be implemented as a Drain.

Required Associated Types§

Source

type Ok

Type returned by this drain

It can be useful in some circumstances, but rarely. It will probably default to () once https://github.com/rust-lang/rust/issues/29661 is stable.

Source

type Err

Type of potential errors that can be returned by this Drain

Required Methods§

Source

fn log( &self, record: &Record<'_>, values: &OwnedKVList, ) -> Result<Self::Ok, Self::Err>

Handle one logging statement (Record)

Every logging Record built from a logging statement (eg. info!(...)), and key-value lists of a Logger it was executed on will be passed to the root drain registered during Logger::root.

Typically Drains:

  • pass this information (or not) to the sub-logger(s) (filters)
  • format and write the information to a destination (writers)
  • deal with the errors returned from the sub-logger(s)

Provided Methods§

Source

fn flush(&self) -> Result<(), FlushError>

Flush all pending log records, blocking until completion.

This method is logically idempotent. In theory, two successive flush calls are the same as one: They will both flush all message up to the point of the final. In practice, this is not actually the case as IO is complicated and flush calls can return errors.

Should call std::io::Write::flush if applicable. If this drain wraps another drain, it should delegate to the flush call of the wrapped drain.

An implementation of flush should try to avoid blocking log operations while the flush is in progress. Unfortunately, there are some cases like impl Drain for Mutex where this is not possible.

A flush call is only required to flush records that are queued before the start of the call. In particular, consider the following interleaving of events

thread1 drain.log(record1)
thread1: drain.flush() begin
thread2: drain.log(record2)
thread2: drain.flush() finish

In this case, the drain is only required to flush record1. It may or may not flush record2. This is mainly relevant for the implementation of slog_async::Async, as we have no control over the implementation of std::io::Write::flush. This behavior is chosen to prevent a flush call from blocking indefinitely in the case of concurrent logging by other threads.

Returns FlushError::NotSupported if the drain has not implemented this method.

Source

fn is_enabled(&self, level: Level) -> bool

Avoid: Check if messages at the specified log level are maybe enabled for this logger.

The purpose of it so to allow imprecise detection if a given logging level has any chance of actually being logged. This might be used to explicitly skip needless computation.

It is best effort, can return false positives, but not false negatives.

The logger is still free to ignore records even if the level is enabled, so an enabled level doesn’t necessarily guarantee that the record will actually be logged.

This function is somewhat needless, and is better expressed by using lazy values (see FnValue). A FnValue is more precise and does not require additional (potentially recursive) calls to do something that log will already do anyways (making decision if something should be logged or not).

let logger = Logger::root(Discard, o!());
if logger.is_enabled(Level::Debug) {
    let num = 5.0f64;
    let sqrt = num.sqrt();
    debug!(logger, "Sqrt"; "num" => num, "sqrt" => sqrt);
}
Source

fn is_critical_enabled(&self) -> bool

Avoid: See is_enabled

Source

fn is_error_enabled(&self) -> bool

Avoid: See is_enabled

Source

fn is_warning_enabled(&self) -> bool

Avoid: See is_enabled

Source

fn is_info_enabled(&self) -> bool

Avoid: See is_enabled

Source

fn is_debug_enabled(&self) -> bool

Avoid: See is_enabled

Source

fn is_trace_enabled(&self) -> bool

Avoid: See is_enabled

Source

fn map<F, R>(self, f: F) -> R
where Self: Sized, F: FnOnce(Self) -> R,

Pass Drain through a closure, eg. to wrap into another Drain.

use slog::{Discard, Fuse, Drain, o};
let _drain = Discard.map(Fuse);
Source

fn filter<F>(self, f: F) -> Filter<Self, F>
where Self: Sized, F: FilterFn,

Filter logging records passed to Drain

Wrap Self in Filter

This will convert self to a Drain that ignores Records for which f returns false.

Source

fn filter_level(self, level: Level) -> LevelFilter<Self>
where Self: Sized,

Filter logging records passed to Drain (by level)

Wrap Self in LevelFilter

This will convert self to a Drain that ignores Records of logging lever smaller than level.

Source

fn map_err<F, E>(self, f: F) -> MapError<Self, E>
where Self: Sized, F: MapErrFn<Self::Err, E>,

Map logging errors returned by this drain

f is a closure that takes Drain::Err returned by a given drain, and returns new error of potentially different type

Source

fn ignore_res(self) -> IgnoreResult<Self>
where Self: Sized,

Ignore results returned by this drain

Wrap Self in IgnoreResult

Source

fn fuse(self) -> Fuse<Self>
where Self::Err: Debug, Self: Sized,

Make Self panic when returning any errors

Wrap Self in Map

Implementations on Foreign Types§

Source§

impl<'a, D: Drain + 'a> Drain for &'a D

Source§

type Ok = <D as Drain>::Ok

Source§

type Err = <D as Drain>::Err

Source§

fn log( &self, record: &Record<'_>, values: &OwnedKVList, ) -> Result<Self::Ok, Self::Err>

Source§

fn is_enabled(&self, level: Level) -> bool

Source§

fn flush(&self) -> Result<(), FlushError>

Source§

impl<'a, D: Drain + 'a> Drain for &'a mut D

Source§

type Ok = <D as Drain>::Ok

Source§

type Err = <D as Drain>::Err

Source§

fn log( &self, record: &Record<'_>, values: &OwnedKVList, ) -> Result<Self::Ok, Self::Err>

Source§

fn is_enabled(&self, level: Level) -> bool

Source§

fn flush(&self) -> Result<(), FlushError>

Source§

impl<D: Drain + ?Sized> Drain for Box<D>

Source§

type Ok = <D as Drain>::Ok

Source§

type Err = <D as Drain>::Err

Source§

fn log(&self, record: &Record<'_>, o: &OwnedKVList) -> Result<Self::Ok, D::Err>

Source§

fn is_enabled(&self, level: Level) -> bool

Source§

fn flush(&self) -> Result<(), FlushError>

Source§

impl<D: Drain + ?Sized> Drain for Arc<D>

Source§

type Ok = <D as Drain>::Ok

Source§

type Err = <D as Drain>::Err

Source§

fn log(&self, record: &Record<'_>, o: &OwnedKVList) -> Result<Self::Ok, D::Err>

Source§

fn is_enabled(&self, level: Level) -> bool

Source§

fn flush(&self) -> Result<(), FlushError>

Source§

impl<D: Drain> Drain for Mutex<D>

Source§

type Ok = <D as Drain>::Ok

Source§

type Err = MutexDrainError<D>

Source§

fn log( &self, record: &Record<'_>, logger_values: &OwnedKVList, ) -> Result<Self::Ok, Self::Err>

Source§

fn is_enabled(&self, level: Level) -> bool

Source§

fn flush(&self) -> Result<(), FlushError>

Implementors§

Source§

impl Drain for Discard

Source§

impl<D1: Drain, D2: Drain> Drain for Duplicate<D1, D2>

Source§

type Ok = (<D1 as Drain>::Ok, <D2 as Drain>::Ok)

Source§

type Err = (Result<<D1 as Drain>::Ok, <D1 as Drain>::Err>, Result<<D2 as Drain>::Ok, <D2 as Drain>::Err>)

Source§

impl<D> Drain for Logger<D>
where D: SendSyncUnwindSafeDrain<Ok = (), Err = Never>,

Source§

impl<D: Drain> Drain for Fuse<D>
where D::Err: Debug,

Source§

impl<D: Drain> Drain for IgnoreResult<D>

Source§

impl<D: Drain> Drain for LevelFilter<D>

Source§

type Ok = Option<<D as Drain>::Ok>

Source§

type Err = <D as Drain>::Err

Source§

impl<D: Drain, E> Drain for MapError<D, E>

Source§

type Ok = <D as Drain>::Ok

Source§

type Err = E

Source§

impl<D: Drain, F> Drain for Filter<D, F>
where F: FilterFn,

Source§

type Ok = Option<<D as Drain>::Ok>

Source§

type Err = <D as Drain>::Err