2025-09-30 18:46:13 -07:00
|
|
|
use std::fmt;
|
2025-10-14 14:01:11 -07:00
|
|
|
use std::sync::OnceLock;
|
2025-05-27 20:28:22 -07:00
|
|
|
|
|
|
|
|
use opentelemetry::global;
|
|
|
|
|
use opentelemetry_sdk::{propagation::TraceContextPropagator, trace::SdkTracerProvider};
|
|
|
|
|
use opentelemetry_stdout::SpanExporter;
|
2025-09-30 18:46:13 -07:00
|
|
|
use time::macros::format_description;
|
2025-10-14 14:01:11 -07:00
|
|
|
use tracing::{Event, Subscriber};
|
|
|
|
|
use tracing_subscriber::fmt::{format, time::FormatTime, FmtContext, FormatEvent, FormatFields};
|
|
|
|
|
use tracing_subscriber::EnvFilter;
|
2025-09-30 18:46:13 -07:00
|
|
|
|
|
|
|
|
struct BracketedTime;
|
|
|
|
|
|
|
|
|
|
impl FormatTime for BracketedTime {
|
|
|
|
|
fn format_time(&self, w: &mut format::Writer<'_>) -> fmt::Result {
|
|
|
|
|
let now = time::OffsetDateTime::now_utc();
|
2025-10-14 14:01:11 -07:00
|
|
|
write!(
|
|
|
|
|
w,
|
|
|
|
|
"[{}]",
|
|
|
|
|
now.format(&format_description!(
|
|
|
|
|
"[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]"
|
|
|
|
|
))
|
|
|
|
|
.unwrap()
|
|
|
|
|
)
|
2025-09-30 18:46:13 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct BracketedFormatter;
|
|
|
|
|
|
|
|
|
|
impl<S, N> FormatEvent<S, N> for BracketedFormatter
|
|
|
|
|
where
|
|
|
|
|
S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
|
|
|
|
|
N: for<'a> FormatFields<'a> + 'static,
|
|
|
|
|
{
|
|
|
|
|
fn format_event(
|
|
|
|
|
&self,
|
|
|
|
|
ctx: &FmtContext<'_, S, N>,
|
|
|
|
|
mut writer: format::Writer<'_>,
|
|
|
|
|
event: &Event<'_>,
|
|
|
|
|
) -> fmt::Result {
|
|
|
|
|
let timer = BracketedTime;
|
|
|
|
|
timer.format_time(&mut writer)?;
|
|
|
|
|
|
2025-10-14 14:01:11 -07:00
|
|
|
write!(
|
|
|
|
|
writer,
|
|
|
|
|
"[{}] ",
|
|
|
|
|
event.metadata().level().to_string().to_lowercase()
|
|
|
|
|
)?;
|
2025-09-30 18:46:13 -07:00
|
|
|
|
|
|
|
|
ctx.field_format().format_fields(writer.by_ref(), event)?;
|
|
|
|
|
|
|
|
|
|
writeln!(writer)
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-27 20:28:22 -07:00
|
|
|
|
|
|
|
|
static INIT_LOGGER: OnceLock<SdkTracerProvider> = OnceLock::new();
|
|
|
|
|
|
|
|
|
|
pub fn init_tracer() -> &'static SdkTracerProvider {
|
|
|
|
|
INIT_LOGGER.get_or_init(|| {
|
|
|
|
|
global::set_text_map_propagator(TraceContextPropagator::new());
|
|
|
|
|
// Install stdout exporter pipeline to be able to retrieve the collected spans.
|
|
|
|
|
// For the demonstration, use `Sampler::AlwaysOn` sampler to sample all traces.
|
|
|
|
|
let provider = SdkTracerProvider::builder()
|
|
|
|
|
.with_simple_exporter(SpanExporter::default())
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
global::set_tracer_provider(provider.clone());
|
|
|
|
|
|
|
|
|
|
tracing_subscriber::fmt()
|
|
|
|
|
.with_env_filter(
|
|
|
|
|
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
|
|
|
|
|
)
|
2025-09-30 18:46:13 -07:00
|
|
|
.event_format(BracketedFormatter)
|
2025-05-27 20:28:22 -07:00
|
|
|
.init();
|
|
|
|
|
|
|
|
|
|
provider
|
|
|
|
|
})
|
|
|
|
|
}
|