1use tracing::Subscriber;
3use tracing_subscriber::fmt::{FormatEvent, FormatFields, FormattedFields};
4use tracing_subscriber::registry::LookupSpan;
5
6#[expect(
7 missing_docs,
8 reason = "This is internal code. This struct needs to be pub for some reason for the Formatter impl to work in staged code?"
9)]
10pub struct Formatter;
11
12impl<S, N> FormatEvent<S, N> for Formatter
13where
14 S: Subscriber + for<'a> LookupSpan<'a>,
15 N: for<'a> FormatFields<'a> + 'static,
16{
17 fn format_event(
18 &self,
19 ctx: &tracing_subscriber::fmt::FmtContext<'_, S, N>,
20 mut writer: tracing_subscriber::fmt::format::Writer<'_>,
21 event: &tracing::Event<'_>,
22 ) -> std::fmt::Result {
23 use colored::Colorize;
24
25 let metadata = event.metadata();
26
27 write!(
28 &mut writer,
29 "{} {} {}{} {} {}:{}: ",
30 chrono::Utc::now()
31 .format("%Y-%m-%dT%H:%M:%S%.f%:z")
32 .to_string()
33 .magenta()
34 .underline()
35 .on_white(),
36 metadata.level().as_str().red(),
37 std::thread::current()
38 .name()
39 .unwrap_or("unnamed-thread")
40 .blue(),
41 format!("({:?})", std::thread::current().id()).blue(),
42 metadata.target().green(),
44 metadata.file().unwrap_or("unknown-file").red(),
45 format!("{}", metadata.line().unwrap_or(0)).red(),
46 )?;
47
48 if let Some(scope) = ctx.event_scope() {
49 for span in scope.from_root() {
50 write!(writer, "{}", span.name().purple())?;
51
52 let ext = span.extensions();
53 let fields = &ext.get::<FormattedFields<N>>().unwrap();
54
55 if !fields.is_empty() {
56 write!(writer, "{{{}}}", fields.cyan())?;
57 }
58
59 write!(writer, ": ")?;
60 }
61 }
62
63 write!(writer, "{}: ", metadata.name().yellow().bold().underline())?;
64
65 ctx.field_format().format_fields(writer.by_ref(), event)?;
66
67 writeln!(writer)
68 }
69}
70
71pub fn initialize_tracing() {
73 use tracing_subscriber::filter::EnvFilter;
74
75 initialize_tracing_with_directive(
76 EnvFilter::try_from_default_env()
77 .unwrap_or_else(|_| EnvFilter::new("trace"))
78 .to_string(),
79 );
80}
81
82pub fn initialize_tracing_with_directive(directive: impl AsRef<str>) {
85 use tracing::subscriber::set_global_default;
86 use tracing_subscriber::filter::EnvFilter;
87 use tracing_subscriber::fmt::format::FmtSpan;
88 use tracing_subscriber::prelude::*;
89 use tracing_subscriber::{Layer, fmt, registry};
90
91 let filter = EnvFilter::new(directive.as_ref());
92
93 set_global_default(
94 registry().with(
95 fmt::layer()
96 .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
97 .event_format(Formatter)
98 .with_filter(filter),
99 ),
100 )
101 .unwrap();
102
103 tracing::trace!("Tracing Initialized");
104}