pub mod genai;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::layer::SubscriberExt;
pub const DEFAULT_SERVICE_NAME: &str = "agnosai";
pub struct TracingGuard {
_otel: Option<hoosh::telemetry::OtelGuard>,
}
pub fn init_tracing(
otlp_endpoint: Option<&str>,
) -> Result<TracingGuard, Box<dyn std::error::Error>> {
let service_name =
std::env::var("OTEL_SERVICE_NAME").unwrap_or_else(|_| DEFAULT_SERVICE_NAME.to_string());
let env_filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("agnosai=info"));
if let Some(endpoint) = otlp_endpoint {
let mut otel_guard = hoosh::telemetry::init_otel(endpoint, &service_name)?;
let otel_layer = otel_guard
.layer()
.ok_or("OtelGuard layer already taken — init_tracing called twice?")?;
let subscriber = tracing_subscriber::registry()
.with(otel_layer)
.with(tracing_subscriber::fmt::layer().with_writer(std::io::stderr))
.with(env_filter);
tracing::subscriber::set_global_default(subscriber)?;
tracing::info!(
endpoint,
service_name,
"OpenTelemetry OTLP export initialised"
);
Ok(TracingGuard {
_otel: Some(otel_guard),
})
} else {
let subscriber = tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().json())
.with(env_filter);
tracing::subscriber::set_global_default(subscriber)?;
Ok(TracingGuard { _otel: None })
}
}
#[must_use]
pub fn otlp_endpoint_from_env() -> Option<String> {
std::env::var("OTEL_EXPORTER_OTLP_ENDPOINT")
.ok()
.filter(|s| !s.is_empty())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_service_name_is_agnosai() {
assert_eq!(DEFAULT_SERVICE_NAME, "agnosai");
}
#[test]
fn otlp_endpoint_from_env_returns_none_when_unset() {
let result = otlp_endpoint_from_env();
let _ = result;
}
#[test]
fn tracing_guard_can_be_created_without_otel() {
let guard = TracingGuard { _otel: None };
drop(guard); }
#[test]
fn default_env_filter_parses() {
let filter = tracing_subscriber::EnvFilter::new("agnosai=info");
let _ = filter;
}
}