mas_config/sections/
telemetry.rs1use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use serde_with::skip_serializing_none;
10use url::Url;
11
12use super::ConfigurationSection;
13
14#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
16#[serde(rename_all = "lowercase")]
17pub enum Propagator {
18 TraceContext,
20
21 Baggage,
23
24 Jaeger,
26}
27
28#[allow(clippy::unnecessary_wraps)]
29fn otlp_endpoint_default() -> Option<String> {
30 Some("https://localhost:4318".to_owned())
31}
32
33#[skip_serializing_none]
35#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, Default)]
36#[serde(rename_all = "lowercase")]
37pub enum TracingExporterKind {
38 #[default]
40 None,
41
42 Stdout,
44
45 Otlp,
47}
48
49#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
51pub struct TracingConfig {
52 #[serde(default)]
54 pub exporter: TracingExporterKind,
55
56 #[serde(skip_serializing_if = "Option::is_none")]
58 #[schemars(url, default = "otlp_endpoint_default")]
59 pub endpoint: Option<Url>,
60
61 #[serde(default)]
63 pub propagators: Vec<Propagator>,
64}
65
66impl TracingConfig {
67 fn is_default(&self) -> bool {
69 matches!(self.exporter, TracingExporterKind::None)
70 && self.endpoint.is_none()
71 && self.propagators.is_empty()
72 }
73}
74
75#[skip_serializing_none]
77#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, Default)]
78#[serde(rename_all = "lowercase")]
79pub enum MetricsExporterKind {
80 #[default]
82 None,
83
84 Stdout,
86
87 Otlp,
89
90 Prometheus,
93}
94
95#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
97pub struct MetricsConfig {
98 #[serde(default)]
100 pub exporter: MetricsExporterKind,
101
102 #[serde(skip_serializing_if = "Option::is_none")]
104 #[schemars(url, default = "otlp_endpoint_default")]
105 pub endpoint: Option<Url>,
106}
107
108impl MetricsConfig {
109 fn is_default(&self) -> bool {
111 matches!(self.exporter, MetricsExporterKind::None) && self.endpoint.is_none()
112 }
113}
114
115fn sentry_dsn_example() -> &'static str {
116 "https://public@host:port/1"
117}
118
119#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
121pub struct SentryConfig {
122 #[schemars(url, example = "sentry_dsn_example")]
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub dsn: Option<String>,
126}
127
128impl SentryConfig {
129 fn is_default(&self) -> bool {
131 self.dsn.is_none()
132 }
133}
134
135#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
137pub struct TelemetryConfig {
138 #[serde(default, skip_serializing_if = "TracingConfig::is_default")]
140 pub tracing: TracingConfig,
141
142 #[serde(default, skip_serializing_if = "MetricsConfig::is_default")]
144 pub metrics: MetricsConfig,
145
146 #[serde(default, skip_serializing_if = "SentryConfig::is_default")]
148 pub sentry: SentryConfig,
149}
150
151impl TelemetryConfig {
152 pub(crate) fn is_default(&self) -> bool {
154 self.tracing.is_default() && self.metrics.is_default() && self.sentry.is_default()
155 }
156}
157
158impl ConfigurationSection for TelemetryConfig {
159 const PATH: Option<&'static str> = Some("telemetry");
160}