Skip to main content

vibesql_server/observability/
config.rs

1use serde::{Deserialize, Serialize};
2
3/// Observability configuration
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ObservabilityConfig {
6    /// Enable observability (default: false)
7    #[serde(default)]
8    pub enabled: bool,
9
10    /// Observability level: TRACE, DEBUG, INFO, WARN, ERROR (default: INFO)
11    #[serde(default = "default_level")]
12    pub level: String,
13
14    /// OTLP exporter configuration
15    #[serde(default)]
16    pub otlp: OtlpConfig,
17
18    /// Metrics configuration
19    #[serde(default)]
20    pub metrics: MetricsConfig,
21
22    /// Traces configuration
23    #[serde(default)]
24    pub traces: TracesConfig,
25
26    /// Logs configuration
27    #[serde(default)]
28    pub logs: LogsConfig,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct OtlpConfig {
33    /// OTLP endpoint (default: http://localhost:4317)
34    #[serde(default = "default_otlp_endpoint")]
35    pub endpoint: String,
36
37    /// Protocol: grpc or http (default: grpc)
38    #[serde(default = "default_otlp_protocol")]
39    pub protocol: String,
40
41    /// Timeout in seconds (default: 10)
42    #[serde(default = "default_otlp_timeout")]
43    pub timeout_seconds: u64,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct MetricsConfig {
48    /// Enable metrics export (default: true)
49    #[serde(default = "default_true")]
50    pub enabled: bool,
51
52    /// Export interval in seconds (default: 60)
53    #[serde(default = "default_metrics_interval")]
54    pub export_interval_seconds: u64,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct TracesConfig {
59    /// Enable traces export (default: true)
60    #[serde(default = "default_true")]
61    pub enabled: bool,
62
63    /// Sampler type: always_on, always_off, parent_based_always_on, trace_id_ratio
64    #[serde(default = "default_sampler")]
65    pub sampler: String,
66
67    /// Sampling ratio for trace_id_ratio sampler (0.0-1.0, default: 1.0)
68    #[serde(default = "default_sampling_ratio")]
69    pub sampling_ratio: f64,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct LogsConfig {
74    /// Enable logs export (default: true)
75    #[serde(default = "default_true")]
76    pub enabled: bool,
77
78    /// Bridge existing tracing logs to OpenTelemetry (default: true)
79    #[serde(default = "default_true")]
80    pub bridge_tracing: bool,
81}
82
83// Default value functions
84fn default_level() -> String {
85    "INFO".to_string()
86}
87
88fn default_otlp_endpoint() -> String {
89    "http://localhost:4317".to_string()
90}
91
92fn default_otlp_protocol() -> String {
93    "grpc".to_string()
94}
95
96fn default_otlp_timeout() -> u64 {
97    10
98}
99
100fn default_true() -> bool {
101    true
102}
103
104fn default_metrics_interval() -> u64 {
105    60
106}
107
108fn default_sampler() -> String {
109    "parent_based_always_on".to_string()
110}
111
112fn default_sampling_ratio() -> f64 {
113    1.0
114}
115
116impl Default for ObservabilityConfig {
117    fn default() -> Self {
118        Self {
119            enabled: false,
120            level: default_level(),
121            otlp: OtlpConfig::default(),
122            metrics: MetricsConfig::default(),
123            traces: TracesConfig::default(),
124            logs: LogsConfig::default(),
125        }
126    }
127}
128
129impl Default for OtlpConfig {
130    fn default() -> Self {
131        Self {
132            endpoint: default_otlp_endpoint(),
133            protocol: default_otlp_protocol(),
134            timeout_seconds: default_otlp_timeout(),
135        }
136    }
137}
138
139impl Default for MetricsConfig {
140    fn default() -> Self {
141        Self { enabled: default_true(), export_interval_seconds: default_metrics_interval() }
142    }
143}
144
145impl Default for TracesConfig {
146    fn default() -> Self {
147        Self {
148            enabled: default_true(),
149            sampler: default_sampler(),
150            sampling_ratio: default_sampling_ratio(),
151        }
152    }
153}
154
155impl Default for LogsConfig {
156    fn default() -> Self {
157        Self { enabled: default_true(), bridge_tracing: default_true() }
158    }
159}
160
161#[cfg(test)]
162mod tests {
163    use super::*;
164
165    #[test]
166    fn test_default_config() {
167        let config = ObservabilityConfig::default();
168        assert!(!config.enabled);
169        assert_eq!(config.level, "INFO");
170        assert_eq!(config.otlp.endpoint, "http://localhost:4317");
171        assert_eq!(config.otlp.protocol, "grpc");
172        assert!(config.metrics.enabled);
173        assert!(config.traces.enabled);
174        assert!(config.logs.enabled);
175    }
176
177    #[test]
178    fn test_config_serialization() {
179        let config = ObservabilityConfig::default();
180        let toml_str = toml::to_string(&config).unwrap();
181        let deserialized: ObservabilityConfig = toml::from_str(&toml_str).unwrap();
182        assert_eq!(config.level, deserialized.level);
183    }
184}