1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-31 09:24:31 +03:00

Make the OTEL propagator configurable

This commit is contained in:
Quentin Gliech
2021-10-14 18:55:47 +02:00
parent 29f3edd833
commit f016019553
3 changed files with 80 additions and 41 deletions

View File

@ -14,8 +14,9 @@
use std::time::Duration; use std::time::Duration;
use anyhow::bail;
use futures::stream::{Stream, StreamExt}; use futures::stream::{Stream, StreamExt};
use mas_config::{MetricsConfig, TelemetryConfig, TracingConfig}; use mas_config::{MetricsExporterConfig, Propagator, TelemetryConfig, TracingExporterConfig};
use opentelemetry::{ use opentelemetry::{
global, global,
propagation::TextMapPropagator, propagation::TextMapPropagator,
@ -30,15 +31,15 @@ use opentelemetry_semantic_conventions as semcov;
pub fn setup(config: &TelemetryConfig) -> anyhow::Result<Option<Tracer>> { pub fn setup(config: &TelemetryConfig) -> anyhow::Result<Option<Tracer>> {
global::set_error_handler(|e| tracing::error!("{}", e))?; global::set_error_handler(|e| tracing::error!("{}", e))?;
let propagator = propagator(); let propagator = propagator(&config.tracing.propagators)?;
// The CORS filter needs to know what headers it should whitelist for // The CORS filter needs to know what headers it should whitelist for
// CORS-protected requests. // CORS-protected requests.
mas_core::filters::cors::set_propagator(&propagator); mas_core::filters::cors::set_propagator(&propagator);
global::set_text_map_propagator(propagator); global::set_text_map_propagator(propagator);
let tracer = tracer(&config.tracing)?; let tracer = tracer(&config.tracing.exporter)?;
meter(&config.metrics)?; meter(&config.metrics.exporter)?;
Ok(tracer) Ok(tracer)
} }
@ -46,15 +47,24 @@ pub fn shutdown() {
global::shutdown_tracer_provider(); global::shutdown_tracer_provider();
} }
fn propagator() -> impl TextMapPropagator { fn match_propagator(
// TODO: make this configurable propagator: Propagator,
let baggage_propagator = BaggagePropagator::new(); ) -> anyhow::Result<Box<dyn TextMapPropagator + Send + Sync>> {
let trace_context_propagator = TraceContextPropagator::new(); match propagator {
Propagator::TraceContext => Ok(Box::new(TraceContextPropagator::new())),
Propagator::Baggage => Ok(Box::new(BaggagePropagator::new())),
p => bail!(
"The service was compiled without support for the {:?} propagator, but config uses it.",
p
),
}
}
TextMapCompositePropagator::new(vec![ fn propagator(propagators: &[Propagator]) -> anyhow::Result<impl TextMapPropagator> {
Box::new(baggage_propagator), let propagators: Result<Vec<_>, _> =
Box::new(trace_context_propagator), propagators.iter().cloned().map(match_propagator).collect();
])
Ok(TextMapCompositePropagator::new(propagators?))
} }
#[cfg(feature = "otlp")] #[cfg(feature = "otlp")]
@ -87,11 +97,11 @@ fn stdout_tracer() -> Tracer {
.install_simple() .install_simple()
} }
fn tracer(config: &TracingConfig) -> anyhow::Result<Option<Tracer>> { fn tracer(config: &TracingExporterConfig) -> anyhow::Result<Option<Tracer>> {
let tracer = match config { let tracer = match config {
TracingConfig::None => return Ok(None), TracingExporterConfig::None => return Ok(None),
TracingConfig::Stdout => stdout_tracer(), TracingExporterConfig::Stdout => stdout_tracer(),
TracingConfig::Otlp { endpoint } => otlp_tracer(endpoint)?, TracingExporterConfig::Otlp { endpoint } => otlp_tracer(endpoint)?,
}; };
Ok(Some(tracer)) Ok(Some(tracer))
@ -131,11 +141,11 @@ fn stdout_meter() {
.init(); .init();
} }
fn meter(config: &MetricsConfig) -> anyhow::Result<()> { fn meter(config: &MetricsExporterConfig) -> anyhow::Result<()> {
match config { match config {
MetricsConfig::None => {} MetricsExporterConfig::None => {}
MetricsConfig::Stdout => stdout_meter(), MetricsExporterConfig::Stdout => stdout_meter(),
MetricsConfig::Otlp { endpoint } => otlp_meter(endpoint)?, MetricsExporterConfig::Otlp { endpoint } => otlp_meter(endpoint)?,
}; };
Ok(()) Ok(())

View File

@ -31,7 +31,10 @@ pub use self::{
database::DatabaseConfig, database::DatabaseConfig,
http::HttpConfig, http::HttpConfig,
oauth2::{Algorithm, KeySet, OAuth2ClientConfig, OAuth2Config}, oauth2::{Algorithm, KeySet, OAuth2ClientConfig, OAuth2Config},
telemetry::{MetricsConfig, TelemetryConfig, TracingConfig}, telemetry::{
MetricsConfig, MetricsExporterConfig, Propagator, TelemetryConfig, TracingConfig,
TracingExporterConfig,
},
templates::TemplatesConfig, templates::TemplatesConfig,
util::ConfigurationSection, util::ConfigurationSection,
}; };

View File

@ -19,10 +19,21 @@ use serde_with::skip_serializing_none;
use super::ConfigurationSection; use super::ConfigurationSection;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "lowercase")]
#[non_exhaustive]
pub enum Propagator {
TraceContext,
Baggage,
Jaeger,
B3,
B3Multi,
}
#[skip_serializing_none] #[skip_serializing_none]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "exporter", rename_all = "lowercase")] #[serde(tag = "exporter", rename_all = "lowercase")]
pub enum TracingConfig { pub enum TracingExporterConfig {
None, None,
Stdout, Stdout,
Otlp { Otlp {
@ -31,34 +42,49 @@ pub enum TracingConfig {
}, },
} }
impl Default for TracingConfig { impl Default for TracingExporterConfig {
fn default() -> Self {
Self::None
}
}
#[skip_serializing_none]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "exporter", rename_all = "lowercase")]
pub enum MetricsConfig {
None,
Stdout,
Otlp {
#[serde(default)]
endpoint: Option<url::Url>,
},
}
impl Default for MetricsConfig {
fn default() -> Self { fn default() -> Self {
Self::None Self::None
} }
} }
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct TracingConfig {
#[serde(default, flatten)]
pub exporter: TracingExporterConfig,
pub propagators: Vec<Propagator>,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "exporter", rename_all = "lowercase")]
pub enum MetricsExporterConfig {
None,
Stdout,
Otlp {
#[serde(default)]
endpoint: Option<url::Url>,
},
}
impl Default for MetricsExporterConfig {
fn default() -> Self {
Self::None
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct MetricsConfig {
#[serde(default, flatten)]
pub exporter: MetricsExporterConfig,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct TelemetryConfig { pub struct TelemetryConfig {
#[serde(default)] #[serde(default)]
pub tracing: TracingConfig, pub tracing: TracingConfig,
#[serde(default)] #[serde(default)]
pub metrics: MetricsConfig, pub metrics: MetricsConfig,
} }