use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use url::Url;
use super::ConfigurationSection;
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum Propagator {
TraceContext,
Baggage,
Jaeger,
}
#[allow(clippy::unnecessary_wraps)]
fn otlp_endpoint_default() -> Option<String> {
Some("https://localhost:4318".to_owned())
}
#[skip_serializing_none]
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, Default)]
#[serde(rename_all = "lowercase")]
pub enum TracingExporterKind {
#[default]
None,
Stdout,
Otlp,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct TracingConfig {
#[serde(default)]
pub exporter: TracingExporterKind,
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(url, default = "otlp_endpoint_default")]
pub endpoint: Option<Url>,
pub propagators: Vec<Propagator>,
}
impl TracingConfig {
fn is_default(&self) -> bool {
matches!(self.exporter, TracingExporterKind::None)
&& self.endpoint.is_none()
&& self.propagators.is_empty()
}
}
#[skip_serializing_none]
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, Default)]
#[serde(rename_all = "lowercase")]
pub enum MetricsExporterKind {
#[default]
None,
Stdout,
Otlp,
Prometheus,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct MetricsConfig {
#[serde(default)]
pub exporter: MetricsExporterKind,
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(url, default = "otlp_endpoint_default")]
pub endpoint: Option<Url>,
}
impl MetricsConfig {
fn is_default(&self) -> bool {
matches!(self.exporter, MetricsExporterKind::None) && self.endpoint.is_none()
}
}
fn sentry_dsn_example() -> &'static str {
"https://public@host:port/1"
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct SentryConfig {
#[schemars(url, example = "sentry_dsn_example")]
#[serde(skip_serializing_if = "Option::is_none")]
pub dsn: Option<String>,
}
impl SentryConfig {
fn is_default(&self) -> bool {
self.dsn.is_none()
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct TelemetryConfig {
#[serde(default, skip_serializing_if = "TracingConfig::is_default")]
pub tracing: TracingConfig,
#[serde(default, skip_serializing_if = "MetricsConfig::is_default")]
pub metrics: MetricsConfig,
#[serde(default, skip_serializing_if = "SentryConfig::is_default")]
pub sentry: SentryConfig,
}
impl TelemetryConfig {
pub(crate) fn is_default(&self) -> bool {
self.tracing.is_default() && self.metrics.is_default() && self.sentry.is_default()
}
}
impl ConfigurationSection for TelemetryConfig {
const PATH: Option<&'static str> = Some("telemetry");
}