Skip to main content

sh_layer1/observability/
config.rs

1//! Observability configuration.
2
3use serde::{Deserialize, Serialize};
4
5/// Log output format.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
7pub enum LogFormat {
8    /// Human-readable pretty output.
9    #[default]
10    Pretty,
11    /// JSON structured logs.
12    Json,
13}
14
15/// Observability configuration.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct ObservabilityConfig {
18    /// Service name for traces and metrics.
19    pub service_name: String,
20    /// Enable tracing collection.
21    pub tracing_enabled: bool,
22    /// Enable metrics collection.
23    pub metrics_enabled: bool,
24    /// Log output format.
25    pub log_format: LogFormat,
26    /// OTLP endpoint URL (e.g., "http://localhost:4317").
27    #[cfg(feature = "otel")]
28    pub otlp_endpoint: Option<String>,
29    /// Prometheus metrics HTTP port.
30    #[cfg(feature = "prometheus")]
31    pub prometheus_port: Option<u16>,
32}
33
34impl Default for ObservabilityConfig {
35    fn default() -> Self {
36        Self {
37            service_name: "continuum".to_string(),
38            tracing_enabled: true,
39            metrics_enabled: true,
40            log_format: LogFormat::default(),
41            #[cfg(feature = "otel")]
42            otlp_endpoint: None,
43            #[cfg(feature = "prometheus")]
44            prometheus_port: None,
45        }
46    }
47}
48
49impl ObservabilityConfig {
50    /// Create a new config with the given service name.
51    pub fn new(service_name: impl Into<String>) -> Self {
52        Self {
53            service_name: service_name.into(),
54            ..Default::default()
55        }
56    }
57
58    /// Set the log format.
59    pub fn with_log_format(mut self, format: LogFormat) -> Self {
60        self.log_format = format;
61        self
62    }
63
64    /// Disable tracing.
65    pub fn without_tracing(mut self) -> Self {
66        self.tracing_enabled = false;
67        self
68    }
69
70    /// Disable metrics.
71    pub fn without_metrics(mut self) -> Self {
72        self.metrics_enabled = false;
73        self
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn test_default_config() {
83        let config = ObservabilityConfig::default();
84        assert_eq!(config.service_name, "continuum");
85        assert!(config.tracing_enabled);
86        assert!(config.metrics_enabled);
87        assert_eq!(config.log_format, LogFormat::Pretty);
88    }
89
90    #[test]
91    fn test_config_builder() {
92        let config = ObservabilityConfig::new("my-service")
93            .with_log_format(LogFormat::Json)
94            .without_tracing();
95
96        assert_eq!(config.service_name, "my-service");
97        assert!(!config.tracing_enabled);
98        assert!(config.metrics_enabled);
99        assert_eq!(config.log_format, LogFormat::Json);
100    }
101
102    #[test]
103    fn test_log_format_default() {
104        assert_eq!(LogFormat::default(), LogFormat::Pretty);
105    }
106}