use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
#[cfg(any(feature = "adk", feature = "observability"))]
use tracing::info;
#[cfg(any(feature = "adk", feature = "observability"))]
use crate::error::Result;
#[cfg(feature = "adk")]
use crate::agents::factory::MonitoringConfig;
pub fn init_console_tracing() {
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
tracing_subscriber::registry()
.with(filter)
.with(
tracing_subscriber::fmt::layer()
.compact()
.with_target(false)
.with_thread_ids(false)
.with_thread_names(false),
)
.init();
}
pub fn init_tracing() {
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
tracing_subscriber::registry()
.with(filter)
.with(tracing_subscriber::fmt::layer().json())
.init();
}
#[cfg(feature = "observability")]
pub struct TelemetryHandle {
_provider: opentelemetry_sdk::trace::TracerProvider,
}
#[cfg(feature = "observability")]
impl TelemetryHandle {
pub fn shutdown(self) {
use opentelemetry::global;
global::shutdown_tracer_provider();
}
}
#[cfg(feature = "observability")]
pub fn init_otlp_tracing(
endpoint: &str,
service_name: &str,
) -> Result<TelemetryHandle> {
use opentelemetry::global;
use opentelemetry_otlp::WithExportConfig;
use opentelemetry_sdk::{runtime, trace::TracerProvider};
use crate::error::AgentKitError;
let exporter = opentelemetry_otlp::new_exporter()
.tonic()
.with_endpoint(endpoint)
.build_span_exporter()
.map_err(|e| AgentKitError::Observability(e.to_string()))?;
let provider = TracerProvider::builder()
.with_batch_exporter(exporter, runtime::Tokio)
.build();
global::set_tracer_provider(provider.clone());
info!("OTLP tracing initialised → {endpoint} (service: {service_name})");
Ok(TelemetryHandle { _provider: provider })
}
#[cfg(feature = "adk")]
pub fn setup_from_config(monitoring: &MonitoringConfig) -> Result<()> {
if let Some(phoenix) = &monitoring.phoenix {
let endpoint = format!("http://{}:{}", phoenix.host, phoenix.port);
#[cfg(feature = "observability")]
{
let service_name = phoenix.project_name.as_deref().unwrap_or("default");
let _ = init_otlp_tracing(&endpoint, service_name)?;
}
#[cfg(not(feature = "observability"))]
info!("Phoenix configured at {endpoint} but 'observability' feature is not enabled");
}
if let Some(arize) = &monitoring.arize {
let _api_key = std::env::var("ARIZE_API_KEY").unwrap_or_default();
let project = arize.arize_project_name.as_deref().unwrap_or("default");
info!(
"Arize observability configured: space={}, project={project}",
arize.arize_space_id
);
}
Ok(())
}