use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ObservabilityConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default = "default_level")]
pub level: String,
#[serde(default)]
pub otlp: OtlpConfig,
#[serde(default)]
pub metrics: MetricsConfig,
#[serde(default)]
pub traces: TracesConfig,
#[serde(default)]
pub logs: LogsConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OtlpConfig {
#[serde(default = "default_otlp_endpoint")]
pub endpoint: String,
#[serde(default = "default_otlp_protocol")]
pub protocol: String,
#[serde(default = "default_otlp_timeout")]
pub timeout_seconds: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetricsConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_metrics_interval")]
pub export_interval_seconds: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TracesConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_sampler")]
pub sampler: String,
#[serde(default = "default_sampling_ratio")]
pub sampling_ratio: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LogsConfig {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_true")]
pub bridge_tracing: bool,
}
fn default_level() -> String {
"INFO".to_string()
}
fn default_otlp_endpoint() -> String {
"http://localhost:4317".to_string()
}
fn default_otlp_protocol() -> String {
"grpc".to_string()
}
fn default_otlp_timeout() -> u64 {
10
}
fn default_true() -> bool {
true
}
fn default_metrics_interval() -> u64 {
60
}
fn default_sampler() -> String {
"parent_based_always_on".to_string()
}
fn default_sampling_ratio() -> f64 {
1.0
}
impl Default for ObservabilityConfig {
fn default() -> Self {
Self {
enabled: false,
level: default_level(),
otlp: OtlpConfig::default(),
metrics: MetricsConfig::default(),
traces: TracesConfig::default(),
logs: LogsConfig::default(),
}
}
}
impl Default for OtlpConfig {
fn default() -> Self {
Self {
endpoint: default_otlp_endpoint(),
protocol: default_otlp_protocol(),
timeout_seconds: default_otlp_timeout(),
}
}
}
impl Default for MetricsConfig {
fn default() -> Self {
Self { enabled: default_true(), export_interval_seconds: default_metrics_interval() }
}
}
impl Default for TracesConfig {
fn default() -> Self {
Self {
enabled: default_true(),
sampler: default_sampler(),
sampling_ratio: default_sampling_ratio(),
}
}
}
impl Default for LogsConfig {
fn default() -> Self {
Self { enabled: default_true(), bridge_tracing: default_true() }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = ObservabilityConfig::default();
assert!(!config.enabled);
assert_eq!(config.level, "INFO");
assert_eq!(config.otlp.endpoint, "http://localhost:4317");
assert_eq!(config.otlp.protocol, "grpc");
assert!(config.metrics.enabled);
assert!(config.traces.enabled);
assert!(config.logs.enabled);
}
#[test]
fn test_config_serialization() {
let config = ObservabilityConfig::default();
let toml_str = toml::to_string(&config).unwrap();
let deserialized: ObservabilityConfig = toml::from_str(&toml_str).unwrap();
assert_eq!(config.level, deserialized.level);
}
}