use std::collections::HashMap; /// Module Distributed Tracing pour production use std::sync::Arc; use std::time::{Duration, SystemTime}; use tokio::sync::RwLock; // Note: Use tracing::info! macro directly instead of importing use crate::error::AppError; use serde::{Deserialize, Serialize}; use uuid::Uuid; #[derive(Debug)] pub struct TracingManager { config: TracingConfig, active_spans: Arc>>, } #[derive(Debug, Clone)] pub struct TracingConfig { pub jaeger_endpoint: String, pub service_name: String, pub service_version: String, pub sampling_rate: f64, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TraceSpan { pub span_id: String, pub trace_id: String, pub operation_name: String, pub start_time: SystemTime, pub end_time: Option, pub status: SpanStatus, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum SpanStatus { Ok, Error(String), } impl Default for TracingConfig { fn default() -> Self { Self { jaeger_endpoint: "http://localhost:14268".to_string(), service_name: "veza-stream-server".to_string(), service_version: "0.2.0".to_string(), sampling_rate: 1.0, } } } impl TracingManager { pub async fn new(config: TracingConfig) -> Result { tracing::info!("🔍 Initialisation Tracing Manager"); Ok(Self { config, active_spans: Arc::new(RwLock::new(HashMap::new())), }) } pub async fn start(&self) -> Result<(), AppError> { tracing::info!("🚀 Démarrage Tracing Manager"); Ok(()) } pub async fn stop(&self) -> Result<(), AppError> { tracing::info!("🛑 Arrêt Tracing Manager"); Ok(()) } pub async fn start_span( &self, operation_name: &str, _parent_id: Option, ) -> Result { let span_id = Uuid::new_v4().to_string(); let span = TraceSpan { span_id: span_id.clone(), trace_id: Uuid::new_v4().to_string(), operation_name: operation_name.to_string(), start_time: SystemTime::now(), end_time: None, status: SpanStatus::Ok, }; let mut spans = self.active_spans.write().await; spans.insert(span_id.clone(), span); tracing::debug!("🆕 Span créé: {}", span_id); Ok(span_id) } }