tracing_configuration/
format.rs

1use tracing_core::{Event, Subscriber};
2use tracing_subscriber::{
3    fmt::{
4        format::{
5            Compact, DefaultFields, Format, Full, Json, JsonFields, Pretty, PrettyFields, Writer,
6        },
7        FmtContext,
8    },
9    registry::LookupSpan,
10};
11
12use crate::time::FormatTime;
13
14/// Implementor of [`tracing_subscriber::fmt::FormatEvent`], constructed [`From`] [`Format`](crate::Format).
15pub struct FormatEvent(FormatEventInner);
16
17impl From<crate::Format> for FormatEvent {
18    fn from(value: crate::Format) -> Self {
19        Self(value.into())
20    }
21}
22
23impl<S, N> tracing_subscriber::fmt::FormatEvent<S, N> for FormatEvent
24where
25    S: Subscriber + for<'a> LookupSpan<'a>,
26    N: for<'a> tracing_subscriber::fmt::FormatFields<'a> + 'static,
27{
28    fn format_event(
29        &self,
30        ctx: &FmtContext<'_, S, N>,
31        writer: Writer<'_>,
32        event: &Event<'_>,
33    ) -> std::fmt::Result {
34        self.0.format_event(ctx, writer, event)
35    }
36}
37
38/// Implementor of [`tracing_subscriber::fmt::FormatFields`], constructed [`From`] [`Formatter`](crate::Formatter).
39pub struct FormatFields(FormatFieldsInner);
40
41impl From<crate::Formatter> for FormatFields {
42    fn from(value: crate::Formatter) -> Self {
43        Self(value.into())
44    }
45}
46
47impl<'writer> tracing_subscriber::fmt::FormatFields<'writer> for FormatFields {
48    fn format_fields<R: tracing_subscriber::field::RecordFields>(
49        &self,
50        writer: Writer<'writer>,
51        fields: R,
52    ) -> std::fmt::Result {
53        self.0.format_fields(writer, fields)
54    }
55}
56
57enum FormatEventInner {
58    Full(Format<Full, FormatTime>),
59    Compact(Format<Compact, FormatTime>),
60    Pretty(Format<Pretty, FormatTime>),
61    Json(Format<Json, FormatTime>),
62}
63
64impl From<crate::Format> for FormatEventInner {
65    fn from(value: crate::Format) -> Self {
66        let crate::Format {
67            ansi,
68            target,
69            level,
70            thread_ids,
71            thread_names,
72            file,
73            line_number,
74            formatter,
75            timer,
76            span_events: _, // handled out-of-band
77        } = value;
78
79        let orig = Format::default().with_timer(FormatTime::from(timer.unwrap_or_default()));
80        let mut this = match formatter.unwrap_or_default() {
81            crate::Formatter::Full => Self::Full(orig),
82            crate::Formatter::Compact => Self::Compact(orig.compact()),
83            crate::Formatter::Pretty => Self::Pretty(orig.pretty()),
84            crate::Formatter::Json(it) => Self::Json({
85                let crate::Json {
86                    flatten_event,
87                    current_span,
88                    span_list,
89                } = it.unwrap_or_default();
90                let mut this = orig.json();
91                if let Some(it) = flatten_event {
92                    this = this.flatten_event(it)
93                }
94                if let Some(it) = current_span {
95                    this = this.with_current_span(it)
96                }
97                if let Some(it) = span_list {
98                    this = this.with_span_list(it)
99                }
100                this
101            }),
102        };
103
104        macro_rules! apply {
105            ($receiver:ident.$method:ident($arg:expr)) => {
106                if let Some(arg) = $arg {
107                    $receiver = match $receiver {
108                        Self::Full(it) => Self::Full(it.$method(arg)),
109                        Self::Compact(it) => Self::Compact(it.$method(arg)),
110                        Self::Pretty(it) => Self::Pretty(it.$method(arg)),
111                        Self::Json(it) => Self::Json(it.$method(arg)),
112                    };
113                }
114            };
115        }
116
117        apply!(this.with_ansi(ansi));
118        apply!(this.with_target(target));
119        apply!(this.with_level(level));
120        apply!(this.with_thread_ids(thread_ids));
121        apply!(this.with_thread_names(thread_names));
122        apply!(this.with_file(file));
123        apply!(this.with_line_number(line_number));
124
125        this
126    }
127}
128
129impl<S, N> tracing_subscriber::fmt::FormatEvent<S, N> for FormatEventInner
130where
131    S: Subscriber + for<'a> LookupSpan<'a>,
132    N: for<'a> tracing_subscriber::fmt::format::FormatFields<'a> + 'static,
133{
134    fn format_event(
135        &self,
136        ctx: &FmtContext<'_, S, N>,
137        writer: Writer<'_>,
138        event: &Event<'_>,
139    ) -> std::fmt::Result {
140        match self {
141            FormatEventInner::Full(it) => it.format_event(ctx, writer, event),
142            FormatEventInner::Compact(it) => it.format_event(ctx, writer, event),
143            FormatEventInner::Pretty(it) => it.format_event(ctx, writer, event),
144            FormatEventInner::Json(it) => it.format_event(ctx, writer, event),
145        }
146    }
147}
148
149enum FormatFieldsInner {
150    Default(DefaultFields),
151    Json(JsonFields),
152    Pretty(PrettyFields),
153}
154
155impl From<crate::Formatter> for FormatFieldsInner {
156    fn from(value: crate::Formatter) -> Self {
157        match value {
158            crate::Formatter::Full => Self::Default(DefaultFields::new()),
159            crate::Formatter::Compact => Self::Default(DefaultFields::new()),
160            crate::Formatter::Pretty => Self::Pretty(PrettyFields::new()),
161            crate::Formatter::Json { .. } => Self::Json(JsonFields::new()),
162        }
163    }
164}
165
166impl<'writer> tracing_subscriber::fmt::FormatFields<'writer> for FormatFieldsInner {
167    fn format_fields<R: tracing_subscriber::field::RecordFields>(
168        &self,
169        writer: Writer<'writer>,
170        fields: R,
171    ) -> std::fmt::Result {
172        match self {
173            FormatFieldsInner::Default(it) => it.format_fields(writer, fields),
174            FormatFieldsInner::Json(it) => it.format_fields(writer, fields),
175            FormatFieldsInner::Pretty(it) => it.format_fields(writer, fields),
176        }
177    }
178}