forge_runtime/observability/
config.rs1use std::time::Duration;
2
3use serde::{Deserialize, Serialize};
4
5use forge_core::LogLevel;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct ObservabilityConfig {
10 pub enabled: bool,
12 pub database_url: Option<String>,
14 pub pool_size: u32,
16 pub pool_timeout: Duration,
18 pub metrics: MetricsConfig,
20 pub logs: LogsConfig,
22 pub traces: TracesConfig,
24 pub export: ExportConfig,
26}
27
28impl Default for ObservabilityConfig {
29 fn default() -> Self {
30 Self {
31 enabled: true,
32 database_url: None,
33 pool_size: 10,
34 pool_timeout: Duration::from_secs(5),
35 metrics: MetricsConfig::default(),
36 logs: LogsConfig::default(),
37 traces: TracesConfig::default(),
38 export: ExportConfig::default(),
39 }
40 }
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct MetricsConfig {
46 pub interval: Duration,
48 pub raw_retention: Duration,
50 pub downsampled_1m: Duration,
52 pub downsampled_5m: Duration,
54 pub downsampled_1h: Duration,
56 pub buffer_size: usize,
58 pub flush_interval: Duration,
60}
61
62impl Default for MetricsConfig {
63 fn default() -> Self {
64 Self {
65 interval: Duration::from_secs(10),
66 raw_retention: Duration::from_secs(3600), downsampled_1m: Duration::from_secs(86400), downsampled_5m: Duration::from_secs(604800), downsampled_1h: Duration::from_secs(7776000), buffer_size: 10000,
71 flush_interval: Duration::from_secs(10),
72 }
73 }
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct LogsConfig {
79 pub level: LogLevel,
81 pub retention: Duration,
83 pub slow_query_threshold: Duration,
85 pub async_writes: bool,
87 pub buffer_size: usize,
89}
90
91impl Default for LogsConfig {
92 fn default() -> Self {
93 Self {
94 level: LogLevel::Info,
95 retention: Duration::from_secs(604800), slow_query_threshold: Duration::from_millis(100),
97 async_writes: true,
98 buffer_size: 5000,
99 }
100 }
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct TracesConfig {
106 pub sample_rate: f64,
108 pub retention: Duration,
110 pub always_trace_errors: bool,
112}
113
114impl Default for TracesConfig {
115 fn default() -> Self {
116 Self {
117 sample_rate: 1.0,
118 retention: Duration::from_secs(86400), always_trace_errors: true,
120 }
121 }
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct ExportConfig {
127 pub destinations: Vec<ExportDestination>,
129 pub otlp: Option<OtlpConfig>,
131 pub prometheus: Option<PrometheusConfig>,
133}
134
135impl Default for ExportConfig {
136 fn default() -> Self {
137 Self {
138 destinations: vec![ExportDestination::Postgres],
139 otlp: None,
140 prometheus: None,
141 }
142 }
143}
144
145#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
147#[serde(rename_all = "lowercase")]
148pub enum ExportDestination {
149 Postgres,
151 Otlp,
153 Prometheus,
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct OtlpConfig {
160 pub endpoint: String,
162 pub protocol: String,
164 pub headers: std::collections::HashMap<String, String>,
166 pub metrics: bool,
168 pub logs: bool,
170 pub traces: bool,
172 pub trace_sample_rate: f64,
174 pub always_export_errors: bool,
176}
177
178impl Default for OtlpConfig {
179 fn default() -> Self {
180 Self {
181 endpoint: "http://localhost:4317".to_string(),
182 protocol: "grpc".to_string(),
183 headers: std::collections::HashMap::new(),
184 metrics: true,
185 logs: true,
186 traces: true,
187 trace_sample_rate: 1.0,
188 always_export_errors: true,
189 }
190 }
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
195pub struct PrometheusConfig {
196 pub enabled: bool,
198 pub path: String,
200}
201
202impl Default for PrometheusConfig {
203 fn default() -> Self {
204 Self {
205 enabled: false,
206 path: "/metrics".to_string(),
207 }
208 }
209}
210
211#[cfg(test)]
212mod tests {
213 use super::*;
214
215 #[test]
216 fn test_observability_config_default() {
217 let config = ObservabilityConfig::default();
218 assert!(config.enabled);
219 assert!(config.database_url.is_none());
220 assert_eq!(config.pool_size, 10);
221 }
222
223 #[test]
224 fn test_metrics_config_default() {
225 let config = MetricsConfig::default();
226 assert_eq!(config.interval, Duration::from_secs(10));
227 assert_eq!(config.buffer_size, 10000);
228 }
229
230 #[test]
231 fn test_logs_config_default() {
232 let config = LogsConfig::default();
233 assert_eq!(config.level, LogLevel::Info);
234 assert!(config.async_writes);
235 }
236
237 #[test]
238 fn test_traces_config_default() {
239 let config = TracesConfig::default();
240 assert_eq!(config.sample_rate, 1.0);
241 assert!(config.always_trace_errors);
242 }
243
244 #[test]
245 fn test_export_config_default() {
246 let config = ExportConfig::default();
247 assert_eq!(config.destinations, vec![ExportDestination::Postgres]);
248 }
249}