Skip to main content

zlayer_observability/
lib.rs

1//! ZLayer Observability - Logging, Tracing, and Metrics
2//!
3//! Provides unified observability infrastructure:
4//! - Structured logging with JSON/pretty formats
5//! - OpenTelemetry distributed tracing
6//! - Prometheus metrics exposition
7//!
8//! # Quick Start
9//!
10//! ```no_run
11//! use zlayer_observability::{init_observability, ObservabilityConfig};
12//!
13//! #[tokio::main]
14//! async fn main() {
15//!     let config = ObservabilityConfig::default();
16//!     let _guards = init_observability(&config).expect("Failed to init observability");
17//!
18//!     tracing::info!("Application started");
19//! }
20//! ```
21
22pub mod config;
23pub mod container_spans;
24pub mod error;
25pub mod logging;
26pub mod metrics;
27pub mod propagation;
28pub mod tracing_otel;
29
30pub use config::*;
31pub use container_spans::*;
32pub use error::{ObservabilityError, Result};
33pub use logging::{init_logging, LogGuard};
34pub use metrics::{init_metrics, metrics, HealthStatus, ZLayerMetrics};
35pub use tracing_otel::{create_otel_layer, init_tracing, TracingGuard};
36
37/// Combined guards for all observability components
38pub struct ObservabilityGuards {
39    /// Guard for the logging system (keeps async file writer running)
40    pub log_guard: LogGuard,
41    /// Guard for the tracing system (flushes traces on drop)
42    pub tracing_guard: TracingGuard,
43}
44
45/// Initialize all observability components
46///
47/// This is the recommended way to set up observability. It initializes:
48/// - Logging (always)
49/// - Metrics (always)
50/// - Tracing (if enabled in config)
51///
52/// Returns guards that must be held for the lifetime of the application.
53///
54/// # Example
55///
56/// ```no_run
57/// use zlayer_observability::{init_observability, ObservabilityConfig};
58///
59/// #[tokio::main]
60/// async fn main() {
61///     let config = ObservabilityConfig::default();
62///     let _guards = init_observability(&config).expect("Failed to init observability");
63///
64///     tracing::info!("Application started");
65///     // guards are dropped when main exits, flushing logs and traces
66/// }
67/// ```
68pub fn init_observability(config: &ObservabilityConfig) -> Result<ObservabilityGuards> {
69    // Initialize logging first so we can log from other init functions
70    let log_guard = init_logging(&config.logging)?;
71
72    // Initialize metrics
73    let _ = init_metrics(&config.metrics)?;
74
75    // Initialize tracing (may be disabled)
76    let tracing_guard = init_tracing(&config.tracing)?;
77
78    tracing::info!("Observability initialized");
79
80    Ok(ObservabilityGuards {
81        log_guard,
82        tracing_guard,
83    })
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn test_default_config() {
92        let config = ObservabilityConfig::default();
93        assert!(!config.tracing.enabled);
94        assert!(config.metrics.enabled);
95    }
96}