fregate/observability/
tracing.rs1mod event_formatter;
4pub mod floor_char_boundary;
5mod log_layer;
6mod otlp_layer;
7mod tracing_fields;
8
9pub use event_formatter::*;
10pub use log_layer::*;
11pub use otlp_layer::*;
12pub use tracing_fields::*;
13
14use crate::error::Result;
15use crate::observability::{HeadersFilter, HEADERS_FILTER};
16use opentelemetry::global::set_error_handler;
17use std::sync::OnceLock;
18use tracing_appender::non_blocking::WorkerGuard;
19use tracing_subscriber::layer::Layered;
20use tracing_subscriber::util::SubscriberInitExt;
21use tracing_subscriber::{
22 filter::EnvFilter, layer::SubscriberExt, registry, reload::Handle, Layer, Registry,
23};
24
25pub const SANITIZED_VALUE: &str = "*****";
27
28pub static LOG_LAYER_HANDLE: OnceLock<LogLayerHandle> = OnceLock::new();
32
33pub static OTLP_LAYER_HANDLE: OnceLock<TraceLayerHandle> = OnceLock::new();
37
38pub type LogLayerHandle =
40 Handle<EnvFilter, Layered<Option<Box<dyn Layer<Registry> + Send + Sync>>, Registry>>;
41
42pub type TraceLayerHandle = Handle<EnvFilter, Registry>;
44
45#[allow(clippy::too_many_arguments)]
53pub fn init_tracing(
54 log_level: &str,
55 trace_level: &str,
56 version: &str,
57 service_name: &str,
58 component_name: &str,
59 traces_endpoint: Option<&str>,
60 log_msg_length: Option<usize>,
61 buffered_lines_limit: Option<usize>,
62 headers_filter: Option<HeadersFilter>,
63) -> Result<WorkerGuard> {
64 let (log_layer, log_reload, worker) = log_layer(
65 log_level,
66 version,
67 service_name,
68 component_name,
69 log_msg_length,
70 buffered_lines_limit,
71 )?;
72 let (otlp_layer, otlp_reload) = otlp_layer(trace_level, component_name, traces_endpoint)?;
73 registry().with(otlp_layer).with(log_layer).try_init()?;
74
75 let _ = LOG_LAYER_HANDLE.get_or_init(|| log_reload);
76 if let Some(otlp_reload) = otlp_reload {
77 let _ = OTLP_LAYER_HANDLE.get_or_init(|| otlp_reload);
78 }
79 if let Some(headers_filter) = headers_filter {
80 let _ = HEADERS_FILTER.get_or_init(|| headers_filter);
81 }
82
83 set_error_handler(|err| {
84 tracing::error!("{err}");
85 })?;
86 set_panic_hook();
87
88 Ok(worker)
89}
90
91fn set_panic_hook() {
92 std::panic::set_hook(Box::new(|panic| {
94 if let Some(location) = panic.location() {
96 tracing::error!(
97 message = %panic,
98 panic.file = location.file(),
99 panic.line = location.line(),
100 panic.column = location.column(),
101 );
102 } else {
103 tracing::error!(message = %panic);
104 }
105 }));
106}