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 log_reader;
26pub mod logging;
27pub mod logs;
28pub mod metrics;
29pub mod propagation;
30pub mod tracing_otel;
31
32pub use config::*;
33pub use container_spans::*;
34pub use error::{ObservabilityError, Result};
35pub use logging::{init_logging, LogGuard};
36pub use metrics::{init_metrics, metrics, HealthStatus, ZLayerMetrics};
37pub use tracing_otel::{create_otel_layer, init_tracing, TracingGuard};
38
39/// Combined guards for all observability components
40pub struct ObservabilityGuards {
41 /// Guard for the logging system (keeps async file writer running)
42 pub log_guard: LogGuard,
43 /// Guard for the tracing system (flushes traces on drop)
44 pub tracing_guard: TracingGuard,
45}
46
47/// Initialize all observability components
48///
49/// This is the recommended way to set up observability. It initializes:
50/// - Logging (always)
51/// - Metrics (always)
52/// - Tracing (if enabled in config)
53///
54/// Returns guards that must be held for the lifetime of the application.
55///
56/// # Example
57///
58/// ```no_run
59/// use zlayer_observability::{init_observability, ObservabilityConfig};
60///
61/// #[tokio::main]
62/// async fn main() {
63/// let config = ObservabilityConfig::default();
64/// let _guards = init_observability(&config).expect("Failed to init observability");
65///
66/// tracing::info!("Application started");
67/// // guards are dropped when main exits, flushing logs and traces
68/// }
69/// ```
70///
71/// # Errors
72/// Returns an error if any observability component fails to initialize.
73pub fn init_observability(config: &ObservabilityConfig) -> Result<ObservabilityGuards> {
74 // Initialize logging first so we can log from other init functions
75 let log_guard = init_logging(&config.logging)?;
76
77 // Initialize metrics
78 let _ = init_metrics(&config.metrics)?;
79
80 // Initialize tracing (may be disabled)
81 let tracing_guard = init_tracing(&config.tracing)?;
82
83 tracing::info!("Observability initialized");
84
85 Ok(ObservabilityGuards {
86 log_guard,
87 tracing_guard,
88 })
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn test_default_config() {
97 let config = ObservabilityConfig::default();
98 assert!(!config.tracing.enabled);
99 assert!(config.metrics.enabled);
100 }
101}