forge_core/config/
observability.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ObservabilityConfig {
6 #[serde(default = "default_true")]
8 pub metrics_enabled: bool,
9
10 #[serde(default = "default_true")]
12 pub logging_enabled: bool,
13
14 #[serde(default = "default_true")]
16 pub tracing_enabled: bool,
17
18 #[serde(default = "default_true")]
20 pub dashboard_enabled: bool,
21
22 #[serde(default)]
24 pub logging: LoggingConfig,
25
26 #[serde(default)]
28 pub metrics: MetricsConfig,
29
30 #[serde(default)]
32 pub tracing: TracingConfig,
33
34 #[serde(default)]
36 pub retention: RetentionConfig,
37}
38
39impl Default for ObservabilityConfig {
40 fn default() -> Self {
41 Self {
42 metrics_enabled: true,
43 logging_enabled: true,
44 tracing_enabled: true,
45 dashboard_enabled: true,
46 logging: LoggingConfig::default(),
47 metrics: MetricsConfig::default(),
48 tracing: TracingConfig::default(),
49 retention: RetentionConfig::default(),
50 }
51 }
52}
53
54fn default_true() -> bool {
55 true
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct LoggingConfig {
61 #[serde(default = "default_log_level")]
63 pub level: String,
64
65 #[serde(default = "default_slow_query_threshold")]
67 pub slow_query_threshold_ms: u64,
68
69 #[serde(default)]
71 pub json_format: bool,
72}
73
74impl Default for LoggingConfig {
75 fn default() -> Self {
76 Self {
77 level: default_log_level(),
78 slow_query_threshold_ms: default_slow_query_threshold(),
79 json_format: false,
80 }
81 }
82}
83
84fn default_log_level() -> String {
85 "info".to_string()
86}
87
88fn default_slow_query_threshold() -> u64 {
89 100
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct MetricsConfig {
95 #[serde(default = "default_flush_interval")]
97 pub flush_interval_secs: u64,
98
99 #[serde(default)]
101 pub prometheus_enabled: bool,
102
103 #[serde(default = "default_prometheus_path")]
105 pub prometheus_path: String,
106}
107
108impl Default for MetricsConfig {
109 fn default() -> Self {
110 Self {
111 flush_interval_secs: default_flush_interval(),
112 prometheus_enabled: false,
113 prometheus_path: default_prometheus_path(),
114 }
115 }
116}
117
118fn default_flush_interval() -> u64 {
119 10
120}
121
122fn default_prometheus_path() -> String {
123 "/metrics".to_string()
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct TracingConfig {
129 #[serde(default = "default_sample_rate")]
131 pub sample_rate: f64,
132
133 pub otlp_endpoint: Option<String>,
135}
136
137impl Default for TracingConfig {
138 fn default() -> Self {
139 Self {
140 sample_rate: default_sample_rate(),
141 otlp_endpoint: None,
142 }
143 }
144}
145
146fn default_sample_rate() -> f64 {
147 1.0
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct RetentionConfig {
153 #[serde(default = "default_metrics_retention")]
155 pub metrics_days: u32,
156
157 #[serde(default = "default_logs_retention")]
159 pub logs_days: u32,
160
161 #[serde(default = "default_traces_retention")]
163 pub traces_days: u32,
164
165 #[serde(default = "default_jobs_retention")]
167 pub completed_jobs_days: u32,
168}
169
170impl Default for RetentionConfig {
171 fn default() -> Self {
172 Self {
173 metrics_days: default_metrics_retention(),
174 logs_days: default_logs_retention(),
175 traces_days: default_traces_retention(),
176 completed_jobs_days: default_jobs_retention(),
177 }
178 }
179}
180
181fn default_metrics_retention() -> u32 {
182 30
183}
184
185fn default_logs_retention() -> u32 {
186 7
187}
188
189fn default_traces_retention() -> u32 {
190 7
191}
192
193fn default_jobs_retention() -> u32 {
194 7
195}
196
197#[cfg(test)]
198mod tests {
199 use super::*;
200
201 #[test]
202 fn test_default_observability_config() {
203 let config = ObservabilityConfig::default();
204 assert!(config.metrics_enabled);
205 assert!(config.logging_enabled);
206 assert!(config.tracing_enabled);
207 assert_eq!(config.logging.level, "info");
208 }
209
210 #[test]
211 fn test_parse_observability_config() {
212 let toml = r#"
213 metrics_enabled = true
214 logging_enabled = true
215 dashboard_enabled = false
216
217 [logging]
218 level = "debug"
219 slow_query_threshold_ms = 50
220
221 [metrics]
222 flush_interval_secs = 5
223 prometheus_enabled = true
224 "#;
225
226 let config: ObservabilityConfig = toml::from_str(toml).unwrap();
227 assert!(!config.dashboard_enabled);
228 assert_eq!(config.logging.level, "debug");
229 assert!(config.metrics.prometheus_enabled);
230 }
231}