use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchConfig {
pub max_batch_size: usize,
#[serde(with = "duration_secs")]
pub max_wait: Duration,
pub max_concurrent_exports: usize,
}
impl Default for BatchConfig {
fn default() -> Self {
Self {
max_batch_size: 512,
max_wait: Duration::from_secs(5),
max_concurrent_exports: 4,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TracingConfig {
pub enabled: bool,
pub service_name: String,
pub content_filter: super::TraceContentFilter,
pub batch: BatchConfig,
}
impl Default for TracingConfig {
fn default() -> Self {
Self {
enabled: false,
service_name: "synwire".to_owned(),
content_filter: super::TraceContentFilter::default(),
batch: BatchConfig::default(),
}
}
}
impl TracingConfig {
pub fn builder() -> TracingConfigBuilder {
TracingConfigBuilder::default()
}
}
#[derive(Debug, Default)]
pub struct TracingConfigBuilder {
config: TracingConfig,
}
impl TracingConfigBuilder {
pub const fn enabled(mut self, value: bool) -> Self {
self.config.enabled = value;
self
}
pub fn service_name(mut self, name: String) -> Self {
self.config.service_name = name;
self
}
pub const fn content_filter(mut self, filter: super::TraceContentFilter) -> Self {
self.config.content_filter = filter;
self
}
pub const fn batch(mut self, batch: BatchConfig) -> Self {
self.config.batch = batch;
self
}
pub fn build(self) -> TracingConfig {
self.config
}
}
mod duration_secs {
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::time::Duration;
pub fn serialize<S: Serializer>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error> {
duration.as_secs_f64().serialize(serializer)
}
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Duration, D::Error> {
let secs = f64::deserialize(deserializer)?;
Ok(Duration::from_secs_f64(secs))
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn default_config_is_disabled() {
let config = TracingConfig::default();
assert!(!config.enabled);
assert_eq!(config.service_name, "synwire");
}
#[test]
fn builder_overrides() {
let config = TracingConfig::builder()
.enabled(true)
.service_name("test-agent".to_owned())
.build();
assert!(config.enabled);
assert_eq!(config.service_name, "test-agent");
}
#[test]
fn batch_config_defaults() {
let batch = BatchConfig::default();
assert_eq!(batch.max_batch_size, 512);
assert_eq!(batch.max_wait, Duration::from_secs(5));
assert_eq!(batch.max_concurrent_exports, 4);
}
#[test]
fn tracing_config_serialization_roundtrip() {
let config = TracingConfig::builder()
.enabled(true)
.service_name("roundtrip".to_owned())
.build();
let json = serde_json::to_string(&config).unwrap();
let deserialized: TracingConfig = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.enabled, config.enabled);
assert_eq!(deserialized.service_name, config.service_name);
}
}