Skip to main content

forge_core/config/
observability.rs

1//! Observability configuration for OTLP telemetry export.
2
3use std::time::Duration;
4
5use serde::{Deserialize, Serialize};
6
7use super::default_true;
8use super::types::DurationStr;
9
10/// Observability configuration for OTLP telemetry.
11#[derive(Debug, Clone, Serialize, Deserialize)]
12#[non_exhaustive]
13pub struct ObservabilityConfig {
14    #[serde(default)]
15    pub enabled: bool,
16
17    #[serde(default = "default_otlp_endpoint")]
18    pub otlp_endpoint: String,
19
20    pub service_name: Option<String>,
21
22    #[serde(default = "default_true")]
23    pub enable_traces: bool,
24
25    #[serde(default = "default_true")]
26    pub enable_metrics: bool,
27
28    #[serde(default = "default_true")]
29    pub enable_logs: bool,
30
31    /// Trace sampling ratio (0.0 to 1.0).
32    #[serde(default = "default_sampling_ratio")]
33    pub sampling_ratio: f64,
34
35    /// Metrics export interval duration (e.g. "15s", "1m"). OTLP collectors typically prefer 15s-60s.
36    #[serde(default = "default_metrics_interval")]
37    pub metrics_interval: DurationStr,
38
39    #[serde(default = "default_log_level")]
40    pub log_level: String,
41}
42
43impl Default for ObservabilityConfig {
44    fn default() -> Self {
45        Self {
46            enabled: false,
47            otlp_endpoint: default_otlp_endpoint(),
48            service_name: None,
49            enable_traces: true,
50            enable_metrics: true,
51            enable_logs: true,
52            sampling_ratio: default_sampling_ratio(),
53            metrics_interval: default_metrics_interval(),
54            log_level: default_log_level(),
55        }
56    }
57}
58
59impl ObservabilityConfig {
60    /// Whether OTLP export is active (enabled + at least one signal on).
61    pub fn otlp_active(&self) -> bool {
62        self.enabled && (self.enable_traces || self.enable_metrics || self.enable_logs)
63    }
64}
65
66fn default_otlp_endpoint() -> String {
67    "http://localhost:4318".to_string()
68}
69
70/// Default trace sampling ratio. 100% so every span is visible out of the box.
71/// Users can tune down for high-traffic production deployments.
72fn default_sampling_ratio() -> f64 {
73    1.0
74}
75
76fn default_metrics_interval() -> DurationStr {
77    DurationStr::new(Duration::from_secs(15))
78}
79
80fn default_log_level() -> String {
81    "info".to_string()
82}