tracing_subscriber::fmt

Trait FormatEvent

Source
pub trait FormatEvent<S, N>
where S: Subscriber + for<'a> LookupSpan<'a>, N: for<'a> FormatFields<'a> + 'static,
{ // Required method fn format_event( &self, ctx: &FmtContext<'_, S, N>, writer: Writer<'_>, event: &Event<'_>, ) -> Result; }
Available on crate features fmt and std only.
Expand description

A type that can format a tracing Event to a Writer.

FormatEvent is primarily used in the context of fmt::Subscriber or fmt::Layer. Each time an event is dispatched to fmt::Subscriber or fmt::Layer, the subscriber or layer forwards it to its associated FormatEvent to emit a log message.

This trait is already implemented for function pointers with the same signature as format_event.

§Arguments

The following arguments are passed to FormatEvent::format_event:

  • A FmtContext. This is an extension of the layer::Context type, which can be used for accessing stored information such as the current span context an event occurred in.

    In addition, FmtContext exposes access to the FormatFields implementation that the subscriber was configured to use via the FmtContext::field_format method. This can be used when the FormatEvent implementation needs to format the event’s fields.

    For convenience, FmtContext also implements FormatFields, forwarding to the configured FormatFields type.

  • A Writer to which the formatted representation of the event is written. This type implements the std::fmt::Write trait, and therefore can be used with the std::write! and std::writeln! macros, as well as calling std::fmt::Write methods directly.

    The Writer type also implements additional methods that provide information about how the event should be formatted. The Writer::has_ansi_escapes method indicates whether ANSI terminal escape codes are supported by the underlying I/O writer that the event will be written to. If this returns true, the formatter is permitted to use ANSI escape codes to add colors and other text formatting to its output. If it returns false, the event will be written to an output that does not support ANSI escape codes (such as a log file), and they should not be emitted.

    Crates like nu_ansi_term and owo-colors can be used to add ANSI escape codes to formatted output.

  • The actual Event to be formatted.

§Examples

This example re-implements a simiplified version of this crate’s default formatter:

use std::fmt;
use tracing_core::{Subscriber, Event};
use tracing_subscriber::fmt::{
    format::{self, FormatEvent, FormatFields},
    FmtContext,
    FormattedFields,
};
use tracing_subscriber::registry::LookupSpan;

struct MyFormatter;

impl<S, N> FormatEvent<S, N> for MyFormatter
where
    S: Subscriber + for<'a> LookupSpan<'a>,
    N: for<'a> FormatFields<'a> + 'static,
{
    fn format_event(
        &self,
        ctx: &FmtContext<'_, S, N>,
        mut writer: format::Writer<'_>,
        event: &Event<'_>,
    ) -> fmt::Result {
        // Format values from the event's's metadata:
        let metadata = event.metadata();
        write!(&mut writer, "{} {}: ", metadata.level(), metadata.target())?;

        // Format all the spans in the event's span context.
        if let Some(scope) = ctx.event_scope() {
            for span in scope.from_root() {
                write!(writer, "{}", span.name())?;

                // `FormattedFields` is a formatted representation of the span's
                // fields, which is stored in its extensions by the `fmt` layer's
                // `new_span` method. The fields will have been formatted
                // by the same field formatter that's provided to the event
                // formatter in the `FmtContext`.
                let ext = span.extensions();
                let fields = &ext
                    .get::<FormattedFields<N>>()
                    .expect("will never be `None`");

                // Skip formatting the fields if the span had no fields.
                if !fields.is_empty() {
                    write!(writer, "{{{}}}", fields)?;
                }
                write!(writer, ": ")?;
            }
        }

        // Write fields on the event
        ctx.field_format().format_fields(writer.by_ref(), event)?;

        writeln!(writer)
    }
}

let _subscriber = tracing_subscriber::fmt()
    .event_format(MyFormatter)
    .init();

let _span = tracing::info_span!("my_span", answer = 42).entered();
tracing::info!(question = "life, the universe, and everything", "hello world");

This formatter will print events like this:

DEBUG yak_shaving::shaver: some-span{field-on-span=foo}: started shaving yak

Required Methods§

Source

fn format_event( &self, ctx: &FmtContext<'_, S, N>, writer: Writer<'_>, event: &Event<'_>, ) -> Result

Write a log message for Event in Context to the given Writer.

Implementations on Foreign Types§

Source§

impl<S, N> FormatEvent<S, N> for fn(ctx: &FmtContext<'_, S, N>, _: Writer<'_>, _: &Event<'_>) -> Result
where S: Subscriber + for<'a> LookupSpan<'a>, N: for<'a> FormatFields<'a> + 'static,

Source§

fn format_event( &self, ctx: &FmtContext<'_, S, N>, writer: Writer<'_>, event: &Event<'_>, ) -> Result

Implementors§

Source§

impl<C, N, T> FormatEvent<C, N> for Format<Pretty, T>
where C: Subscriber + for<'a> LookupSpan<'a>, N: for<'a> FormatFields<'a> + 'static, T: FormatTime,

Source§

impl<S, N, T> FormatEvent<S, N> for Format<Compact, T>
where S: Subscriber + for<'a> LookupSpan<'a>, N: for<'a> FormatFields<'a> + 'static, T: FormatTime,

Source§

impl<S, N, T> FormatEvent<S, N> for Format<Full, T>
where S: Subscriber + for<'a> LookupSpan<'a>, N: for<'a> FormatFields<'a> + 'static, T: FormatTime,

Source§

impl<S, N, T> FormatEvent<S, N> for Format<Json, T>
where S: Subscriber + for<'lookup> LookupSpan<'lookup>, N: for<'writer> FormatFields<'writer> + 'static, T: FormatTime,