use crate::extensions::DeserializeExt;
use crate::observability::HeadersFilter;
use serde::de::Error;
use serde::{Deserialize, Deserializer};
use serde_json::{from_value, Value};
#[cfg(feature = "tokio-metrics")]
const SERVER_METRICS_UPDATE_INTERVAL_PTR: &str = "/server/metrics/update_interval";
const LOG_LEVEL_PTR: &str = "/log/level";
const LOG_MSG_LENGTH_PTR: &str = "/log/msg/length";
const BUFFERED_LINES_LIMIT_PTR: &str = "/buffered/lines/limit";
const TRACE_LEVEL_PTR: &str = "/trace/level";
const SERVICE_NAME_PTR: &str = "/service/name";
const COMPONENT_NAME_PTR: &str = "/component/name";
const COMPONENT_VERSION_PTR: &str = "/component/version";
const TRACES_ENDPOINT_PTR: &str = "/exporter/otlp/traces/endpoint";
const HEADERS_PTR: &str = "/headers";
#[derive(Debug, Clone, Default)]
pub struct ObservabilityConfig {
pub log_level: String,
pub msg_length: Option<usize>,
pub buffered_lines_limit: Option<usize>,
pub trace_level: String,
pub service_name: String,
pub component_name: String,
pub version: String,
#[cfg(feature = "tokio-metrics")]
pub metrics_update_interval: std::time::Duration,
pub traces_endpoint: Option<String>,
pub headers_filter: Option<HeadersFilter>,
}
impl<'de> Deserialize<'de> for ObservabilityConfig {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let mut config = Value::deserialize(deserializer)?;
let log_level = config.pointer_and_deserialize(LOG_LEVEL_PTR)?;
let trace_level = config.pointer_and_deserialize(TRACE_LEVEL_PTR)?;
let service_name = config.pointer_and_deserialize(SERVICE_NAME_PTR)?;
let component_name = config.pointer_and_deserialize(COMPONENT_NAME_PTR)?;
let version = config.pointer_and_deserialize(COMPONENT_VERSION_PTR)?;
let traces_endpoint = config
.pointer_mut(TRACES_ENDPOINT_PTR)
.map(Value::take)
.map(from_value::<String>)
.transpose()
.map_err(D::Error::custom)?;
#[cfg(feature = "tokio-metrics")]
let metrics_update_interval =
config.pointer_and_deserialize::<u64, D::Error>(SERVER_METRICS_UPDATE_INTERVAL_PTR)?;
let msg_length = config
.pointer_and_deserialize::<_, D::Error>(LOG_MSG_LENGTH_PTR)
.ok();
let buffered_lines_limit = config
.pointer_and_deserialize::<_, D::Error>(BUFFERED_LINES_LIMIT_PTR)
.ok();
let headers_filter: Option<HeadersFilter> = config
.pointer_and_deserialize::<_, D::Error>(HEADERS_PTR)
.ok();
Ok(ObservabilityConfig {
log_level,
msg_length,
version,
trace_level,
service_name,
component_name,
traces_endpoint,
buffered_lines_limit,
headers_filter,
#[cfg(feature = "tokio-metrics")]
metrics_update_interval: std::time::Duration::from_millis(metrics_update_interval),
})
}
}