diff --git a/crates/cli/src/telemetry.rs b/crates/cli/src/telemetry.rs index cf6cb664..9fd08913 100644 --- a/crates/cli/src/telemetry.rs +++ b/crates/cli/src/telemetry.rs @@ -16,7 +16,10 @@ use std::time::Duration; use anyhow::Context as _; use hyper::{header::CONTENT_TYPE, Body, Response}; -use mas_config::{MetricsExporterConfig, Propagator, TelemetryConfig, TracingExporterConfig}; +use mas_config::{ + MetricsConfig, MetricsExporterKind, Propagator, TelemetryConfig, TracingConfig, + TracingExporterKind, +}; use opentelemetry::{ global, propagation::{TextMapCompositePropagator, TextMapPropagator}, @@ -52,9 +55,9 @@ pub fn setup(config: &TelemetryConfig) -> anyhow::Result> { mas_http::set_propagator(&propagator); global::set_text_map_propagator(propagator); - let tracer = tracer(&config.tracing.exporter).context("Failed to configure traces exporter")?; + let tracer = tracer(&config.tracing).context("Failed to configure traces exporter")?; - init_meter(&config.metrics.exporter).context("Failed to configure metrics exporter")?; + init_meter(&config.metrics).context("Failed to configure metrics exporter")?; Ok(tracer) } @@ -114,13 +117,13 @@ fn otlp_tracer(endpoint: Option<&Url>) -> anyhow::Result { Ok(tracer) } -fn tracer(config: &TracingExporterConfig) -> anyhow::Result> { - let tracer_provider = match config { - TracingExporterConfig::None => return Ok(None), - TracingExporterConfig::Stdout => stdout_tracer_provider(), - TracingExporterConfig::Otlp { endpoint } => { +fn tracer(config: &TracingConfig) -> anyhow::Result> { + let tracer_provider = match config.exporter { + TracingExporterKind::None => return Ok(None), + TracingExporterKind::Stdout => stdout_tracer_provider(), + TracingExporterKind::Otlp => { // The OTLP exporter already creates a tracer and installs it - return Ok(Some(otlp_tracer(endpoint.as_ref())?)); + return Ok(Some(otlp_tracer(config.endpoint.as_ref())?)); } }; @@ -208,15 +211,15 @@ fn prometheus_metric_reader() -> anyhow::Result { Ok(exporter) } -fn init_meter(config: &MetricsExporterConfig) -> anyhow::Result<()> { +fn init_meter(config: &MetricsConfig) -> anyhow::Result<()> { let meter_provider_builder = SdkMeterProvider::builder(); - let meter_provider_builder = match config { - MetricsExporterConfig::None => meter_provider_builder.with_reader(ManualReader::default()), - MetricsExporterConfig::Stdout => meter_provider_builder.with_reader(stdout_metric_reader()), - MetricsExporterConfig::Otlp { endpoint } => { - meter_provider_builder.with_reader(otlp_metric_reader(endpoint.as_ref())?) + let meter_provider_builder = match config.exporter { + MetricsExporterKind::None => meter_provider_builder.with_reader(ManualReader::default()), + MetricsExporterKind::Stdout => meter_provider_builder.with_reader(stdout_metric_reader()), + MetricsExporterKind::Otlp => { + meter_provider_builder.with_reader(otlp_metric_reader(config.endpoint.as_ref())?) } - MetricsExporterConfig::Prometheus => { + MetricsExporterKind::Prometheus => { meter_provider_builder.with_reader(prometheus_metric_reader()?) } }; diff --git a/crates/config/src/sections/mod.rs b/crates/config/src/sections/mod.rs index 1cd05edc..ea0936be 100644 --- a/crates/config/src/sections/mod.rs +++ b/crates/config/src/sections/mod.rs @@ -46,8 +46,8 @@ pub use self::{ policy::PolicyConfig, secrets::SecretsConfig, telemetry::{ - MetricsConfig, MetricsExporterConfig, Propagator, TelemetryConfig, TracingConfig, - TracingExporterConfig, + MetricsConfig, MetricsExporterKind, Propagator, TelemetryConfig, TracingConfig, + TracingExporterKind, }, templates::TemplatesConfig, upstream_oauth2::{ diff --git a/crates/config/src/sections/telemetry.rs b/crates/config/src/sections/telemetry.rs index 1f5a77bc..4690a36a 100644 --- a/crates/config/src/sections/telemetry.rs +++ b/crates/config/src/sections/telemetry.rs @@ -35,42 +35,38 @@ pub enum Propagator { Jaeger, } -fn otlp_endpoint_example() -> &'static str { - "https://localhost:4318" +#[allow(clippy::unnecessary_wraps)] +fn otlp_endpoint_default() -> Option { + Some("https://localhost:4318".to_owned()) } /// Exporter to use when exporting traces #[skip_serializing_none] -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "exporter", rename_all = "lowercase", deny_unknown_fields)] -pub enum TracingExporterConfig { +#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, Default)] +#[serde(rename_all = "lowercase")] +pub enum TracingExporterKind { /// Don't export traces + #[default] None, /// Export traces to the standard output. Only useful for debugging Stdout, /// Export traces to an OpenTelemetry protocol compatible endpoint - Otlp { - /// OTLP compatible endpoint - #[schemars(url, example = "otlp_endpoint_example")] - #[serde(default)] - endpoint: Option, - }, -} - -impl Default for TracingExporterConfig { - fn default() -> Self { - Self::None - } + Otlp, } /// Configuration related to exporting traces #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] pub struct TracingConfig { /// Exporter to use when exporting traces - #[serde(default, flatten)] - pub exporter: TracingExporterConfig, + #[serde(default)] + pub exporter: TracingExporterKind, + + /// OTLP exporter: OTLP over HTTP compatible endpoint + #[serde(skip_serializing_if = "Option::is_none")] + #[schemars(url, default = "otlp_endpoint_default")] + pub endpoint: Option, /// List of propagation formats to use for incoming and outgoing requests pub propagators: Vec, @@ -78,40 +74,35 @@ pub struct TracingConfig { /// Exporter to use when exporting metrics #[skip_serializing_none] -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "exporter", rename_all = "lowercase")] -pub enum MetricsExporterConfig { +#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, Default)] +#[serde(rename_all = "lowercase")] +pub enum MetricsExporterKind { /// Don't export metrics + #[default] None, /// Export metrics to stdout. Only useful for debugging Stdout, /// Export metrics to an OpenTelemetry protocol compatible endpoint - Otlp { - /// OTLP compatible endpoint - #[schemars(url, example = "otlp_endpoint_example")] - #[serde(default)] - endpoint: Option, - }, + Otlp, /// Export metrics via Prometheus. An HTTP listener with the `prometheus` /// resource must be setup to expose the Promethes metrics. Prometheus, } -impl Default for MetricsExporterConfig { - fn default() -> Self { - Self::None - } -} - /// Configuration related to exporting metrics #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] pub struct MetricsConfig { /// Exporter to use when exporting metrics - #[serde(default, flatten)] - pub exporter: MetricsExporterConfig, + #[serde(default)] + pub exporter: MetricsExporterKind, + + /// OTLP exporter: OTLP over HTTP compatible endpoint + #[serde(skip_serializing_if = "Option::is_none")] + #[schemars(url, default = "otlp_endpoint_default")] + pub endpoint: Option, } fn sentry_dsn_example() -> &'static str { @@ -123,7 +114,7 @@ fn sentry_dsn_example() -> &'static str { pub struct SentryConfig { /// Sentry DSN #[schemars(url, example = "sentry_dsn_example")] - #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] pub dsn: Option, } diff --git a/docs/config.schema.json b/docs/config.schema.json index 76de3a2c..449666fb 100644 --- a/docs/config.schema.json +++ b/docs/config.schema.json @@ -110,9 +110,7 @@ "metrics": { "exporter": "none" }, - "sentry": { - "dsn": null - } + "sentry": {} }, "allOf": [ { @@ -1108,9 +1106,7 @@ }, "sentry": { "description": "Configuration related to the Sentry integration", - "default": { - "dsn": null - }, + "default": {}, "allOf": [ { "$ref": "#/definitions/SentryConfig" @@ -1122,68 +1118,25 @@ "TracingConfig": { "description": "Configuration related to exporting traces", "type": "object", - "oneOf": [ - { - "description": "Don't export traces", - "type": "object", - "required": [ - "exporter" - ], - "properties": { - "exporter": { - "type": "string", - "enum": [ - "none" - ] - } - }, - "additionalProperties": false - }, - { - "description": "Export traces to the standard output. Only useful for debugging", - "type": "object", - "required": [ - "exporter" - ], - "properties": { - "exporter": { - "type": "string", - "enum": [ - "stdout" - ] - } - }, - "additionalProperties": false - }, - { - "description": "Export traces to an OpenTelemetry protocol compatible endpoint", - "type": "object", - "required": [ - "exporter" - ], - "properties": { - "exporter": { - "type": "string", - "enum": [ - "otlp" - ] - }, - "endpoint": { - "description": "OTLP compatible endpoint", - "examples": [ - "https://localhost:4318" - ], - "type": "string", - "format": "uri" - } - }, - "additionalProperties": false - } - ], "required": [ "propagators" ], "properties": { + "exporter": { + "description": "Exporter to use when exporting traces", + "default": "none", + "allOf": [ + { + "$ref": "#/definitions/TracingExporterKind" + } + ] + }, + "endpoint": { + "description": "OTLP exporter: OTLP over HTTP compatible endpoint", + "default": "https://localhost:4318", + "type": "string", + "format": "uri" + }, "propagators": { "description": "List of propagation formats to use for incoming and outgoing requests", "type": "array", @@ -1193,6 +1146,32 @@ } } }, + "TracingExporterKind": { + "description": "Exporter to use when exporting traces", + "oneOf": [ + { + "description": "Don't export traces", + "type": "string", + "enum": [ + "none" + ] + }, + { + "description": "Export traces to the standard output. Only useful for debugging", + "type": "string", + "enum": [ + "stdout" + ] + }, + { + "description": "Export traces to an OpenTelemetry protocol compatible endpoint", + "type": "string", + "enum": [ + "otlp" + ] + } + ] + }, "Propagator": { "description": "Propagation format for incoming and outgoing requests", "oneOf": [ @@ -1222,74 +1201,54 @@ "MetricsConfig": { "description": "Configuration related to exporting metrics", "type": "object", + "properties": { + "exporter": { + "description": "Exporter to use when exporting metrics", + "default": "none", + "allOf": [ + { + "$ref": "#/definitions/MetricsExporterKind" + } + ] + }, + "endpoint": { + "description": "OTLP exporter: OTLP over HTTP compatible endpoint", + "default": "https://localhost:4318", + "type": "string", + "format": "uri" + } + } + }, + "MetricsExporterKind": { + "description": "Exporter to use when exporting metrics", "oneOf": [ { "description": "Don't export metrics", - "type": "object", - "required": [ - "exporter" - ], - "properties": { - "exporter": { - "type": "string", - "enum": [ - "none" - ] - } - } + "type": "string", + "enum": [ + "none" + ] }, { "description": "Export metrics to stdout. Only useful for debugging", - "type": "object", - "required": [ - "exporter" - ], - "properties": { - "exporter": { - "type": "string", - "enum": [ - "stdout" - ] - } - } + "type": "string", + "enum": [ + "stdout" + ] }, { "description": "Export metrics to an OpenTelemetry protocol compatible endpoint", - "type": "object", - "required": [ - "exporter" - ], - "properties": { - "exporter": { - "type": "string", - "enum": [ - "otlp" - ] - }, - "endpoint": { - "description": "OTLP compatible endpoint", - "examples": [ - "https://localhost:4318" - ], - "type": "string", - "format": "uri" - } - } + "type": "string", + "enum": [ + "otlp" + ] }, { "description": "Export metrics via Prometheus. An HTTP listener with the `prometheus` resource must be setup to expose the Promethes metrics.", - "type": "object", - "required": [ - "exporter" - ], - "properties": { - "exporter": { - "type": "string", - "enum": [ - "prometheus" - ] - } - } + "type": "string", + "enum": [ + "prometheus" + ] } ] }, @@ -1299,7 +1258,6 @@ "properties": { "dsn": { "description": "Sentry DSN", - "default": null, "examples": [ "https://public@host:port/1" ],