main
use opentelemetry::trace::TracerProvider as _;
use opentelemetry_appender_tracing::layer::{OpenTelemetryTracingBridge, TracingSpanAttributes};
use tracing_subscriber::EnvFilter;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use crate::Telemetry;
use crate::config::TelemetryConfig;
pub fn install(config: &TelemetryConfig, telemetry: &Telemetry) {
let base = std::env::var(EnvFilter::DEFAULT_ENV)
.ok()
.filter(|value| !value.trim().is_empty())
.unwrap_or_else(|| config.log_filter.clone());
// 连接池与查询执行器自身不产出业务日志,慢查询告警也与请求日志重复。
// 默认静默,但配置里显式写了 sqlx 目标时以用户的选择为准,方便临时排查。
let mut spec = base.clone();
if !base.contains("sqlx") {
spec.push_str(",sqlx=off");
}
// RocketMQ 客户端每 5s 打印一次定时任务、拉取与路由刷新,属于库内部心跳。
// 默认只保留 warn 及以上:路由缺失、连接异常照样可见,周期性噪音不再进日志。
if !base.contains("rocketmq") {
spec.push_str(",rocketmq_client_rust=warn,rocketmq_transport=warn");
}
let filter =
EnvFilter::try_new(&spec).unwrap_or_else(|_| EnvFilter::new(config.log_filter.as_str()));
let tracer = telemetry
.tracer_provider()
.tracer(config.service_name.clone());
let trace_layer = tracing_opentelemetry::layer().with_tracer(tracer);
let log_layer = OpenTelemetryTracingBridge::builder(telemetry.logger_provider())
.with_tracing_span_attributes(TracingSpanAttributes::allowlist(["request_id"]))
.build();
let format_layer = tracing_subscriber::fmt::layer()
.with_target(true)
.with_writer(OutputWriter {
enabled: config.stdout,
});
let result = tracing_subscriber::registry()
.with(filter)
.with(format_layer)
.with(trace_layer)
.with(log_layer)
.try_init();
if let Err(error) = result {
tracing::warn!(%error, "tracing subscriber already installed");
}
for warning in telemetry.warnings() {
tracing::warn!("{warning}");
}
}
#[derive(Debug, Clone, Copy)]
struct OutputWriter {
enabled: bool,
}
impl<'a> tracing_subscriber::fmt::MakeWriter<'a> for OutputWriter {
type Writer = Box<dyn std::io::Write + 'a>;
fn make_writer(&'a self) -> Self::Writer {
if self.enabled {
Box::new(std::io::stdout())
} else {
Box::new(std::io::sink())
}
}
}