use std::collections::HashMap;
use serde::{Deserialize, Serialize};
mod from_env;
mod parse;
pub(crate) mod probe;
mod redact;
mod validate;
pub use redact::redact_config;
pub(crate) const MAX_EXPORTER_RETRIES: usize = 100;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)]
#[serde(default)]
pub struct RuntimeOverrides {
pub sampling: Option<SamplingConfig>,
pub backpressure: Option<BackpressureConfig>,
pub exporter: Option<ExporterPolicyConfig>,
pub security: Option<SecurityConfig>,
pub slo: Option<SLOConfig>,
pub pii_max_depth: Option<usize>,
pub strict_schema: Option<bool>,
pub event_schema: Option<EventSchemaConfig>,
pub logging: Option<LoggingConfig>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default)]
pub struct LoggingConfig {
pub level: String,
pub fmt: String,
pub include_timestamp: bool,
pub otlp_headers: HashMap<String, String>,
pub otlp_endpoint: Option<String>,
pub otlp_enabled: bool,
pub otlp_protocol: String,
pub module_levels: HashMap<String, String>,
}
impl Default for LoggingConfig {
fn default() -> Self {
Self {
level: "INFO".to_string(),
fmt: "console".to_string(),
include_timestamp: true,
otlp_headers: HashMap::new(),
otlp_endpoint: None,
otlp_enabled: true,
otlp_protocol: String::new(),
module_levels: HashMap::new(),
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct TracingConfig {
pub enabled: bool,
pub sample_rate: f64,
pub otlp_headers: HashMap<String, String>,
pub otlp_endpoint: Option<String>,
pub otlp_protocol: String,
}
impl Default for TracingConfig {
fn default() -> Self {
Self {
enabled: true,
sample_rate: 1.0,
otlp_headers: HashMap::new(),
otlp_endpoint: None,
otlp_protocol: String::new(),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default)]
pub struct MetricsConfig {
pub enabled: bool,
pub otlp_headers: HashMap<String, String>,
pub otlp_endpoint: Option<String>,
pub otlp_protocol: String,
pub metric_export_interval_ms: u64,
}
fn default_metric_export_interval_ms() -> u64 {
60_000
}
impl Default for MetricsConfig {
fn default() -> Self {
Self {
enabled: true,
otlp_headers: HashMap::new(),
otlp_endpoint: None,
otlp_protocol: String::new(),
metric_export_interval_ms: default_metric_export_interval_ms(),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(default)]
pub struct EventSchemaConfig {
pub strict_event_name: bool,
pub required_keys: Vec<String>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct SamplingConfig {
pub logs_rate: f64,
pub traces_rate: f64,
pub metrics_rate: f64,
}
impl Default for SamplingConfig {
fn default() -> Self {
Self {
logs_rate: 1.0,
traces_rate: 1.0,
metrics_rate: 1.0,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(default)]
pub struct BackpressureConfig {
pub logs_maxsize: usize,
pub traces_maxsize: usize,
pub metrics_maxsize: usize,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct ExporterPolicyConfig {
pub logs_retries: usize,
pub traces_retries: usize,
pub metrics_retries: usize,
pub logs_backoff_seconds: f64,
pub traces_backoff_seconds: f64,
pub metrics_backoff_seconds: f64,
pub logs_timeout_seconds: f64,
pub traces_timeout_seconds: f64,
pub metrics_timeout_seconds: f64,
pub logs_shutdown_timeout_seconds: f64,
pub logs_fail_open: bool,
pub traces_fail_open: bool,
pub metrics_fail_open: bool,
}
impl Default for ExporterPolicyConfig {
fn default() -> Self {
Self {
logs_retries: 0,
traces_retries: 0,
metrics_retries: 0,
logs_backoff_seconds: 0.0,
traces_backoff_seconds: 0.0,
metrics_backoff_seconds: 0.0,
logs_timeout_seconds: 10.0,
traces_timeout_seconds: 10.0,
metrics_timeout_seconds: 10.0,
logs_shutdown_timeout_seconds: 5.0,
logs_fail_open: true,
traces_fail_open: true,
metrics_fail_open: true,
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default)]
pub struct SLOConfig {
pub enable_red_metrics: bool,
pub enable_use_metrics: bool,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default)]
pub struct SecurityConfig {
pub max_attr_value_length: usize,
pub max_attr_count: usize,
pub max_nesting_depth: usize,
}
impl Default for SecurityConfig {
fn default() -> Self {
Self {
max_attr_value_length: 1024,
max_attr_count: 64,
max_nesting_depth: 8,
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct TelemetryConfig {
pub service_name: String,
pub environment: String,
pub version: String,
pub strict_schema: bool,
pub pii_max_depth: usize,
pub logging: LoggingConfig,
pub tracing: TracingConfig,
pub metrics: MetricsConfig,
pub event_schema: EventSchemaConfig,
pub sampling: SamplingConfig,
pub backpressure: BackpressureConfig,
pub exporter: ExporterPolicyConfig,
pub slo: SLOConfig,
pub security: SecurityConfig,
}
impl Default for TelemetryConfig {
fn default() -> Self {
Self {
service_name: "provide-service".to_string(),
environment: "dev".to_string(),
version: "0.0.0".to_string(),
strict_schema: false,
pii_max_depth: 8,
logging: LoggingConfig::default(),
tracing: TracingConfig::default(),
metrics: MetricsConfig::default(),
event_schema: EventSchemaConfig::default(),
sampling: SamplingConfig::default(),
backpressure: BackpressureConfig::default(),
exporter: ExporterPolicyConfig::default(),
slo: SLOConfig::default(),
security: SecurityConfig::default(),
}
}
}