Expose more Sentry configuration (#4352)
This commit is contained in:
@@ -109,17 +109,18 @@ async fn try_main() -> anyhow::Result<ExitCode> {
|
||||
// Load the base configuration files
|
||||
let figment = opts.figment();
|
||||
|
||||
// Telemetry config could fail to load, but that's probably OK, since the whole
|
||||
// config will be loaded afterwards, and crash if there is a problem.
|
||||
// Falling back to default.
|
||||
let telemetry_config = TelemetryConfig::extract(&figment).unwrap_or_default();
|
||||
let telemetry_config =
|
||||
TelemetryConfig::extract(&figment).context("Failed to load telemetry config")?;
|
||||
|
||||
// Setup Sentry
|
||||
let sentry = sentry::init((
|
||||
telemetry_config.sentry.dsn.as_deref(),
|
||||
sentry::ClientOptions {
|
||||
transport: Some(Arc::new(SentryTransportFactory::new())),
|
||||
traces_sample_rate: 1.0,
|
||||
environment: telemetry_config.sentry.environment.clone().map(Into::into),
|
||||
release: Some(VERSION.into()),
|
||||
sample_rate: telemetry_config.sentry.sample_rate.unwrap_or(1.0),
|
||||
traces_sample_rate: telemetry_config.sentry.traces_sample_rate.unwrap_or(0.0),
|
||||
auto_session_tracking: true,
|
||||
session_mode: sentry::SessionMode::Request,
|
||||
..Default::default()
|
||||
|
||||
@@ -102,7 +102,10 @@ fn stdout_tracer_provider() -> SdkTracerProvider {
|
||||
.build()
|
||||
}
|
||||
|
||||
fn otlp_tracer_provider(endpoint: Option<&Url>) -> anyhow::Result<SdkTracerProvider> {
|
||||
fn otlp_tracer_provider(
|
||||
endpoint: Option<&Url>,
|
||||
sample_rate: f64,
|
||||
) -> anyhow::Result<SdkTracerProvider> {
|
||||
let mut exporter = opentelemetry_otlp::SpanExporter::builder()
|
||||
.with_http()
|
||||
.with_http_client(mas_http::reqwest_client());
|
||||
@@ -119,17 +122,18 @@ fn otlp_tracer_provider(endpoint: Option<&Url>) -> anyhow::Result<SdkTracerProvi
|
||||
let tracer_provider = SdkTracerProvider::builder()
|
||||
.with_span_processor(batch_processor)
|
||||
.with_resource(resource())
|
||||
.with_sampler(Sampler::AlwaysOn)
|
||||
.with_sampler(Sampler::TraceIdRatioBased(sample_rate))
|
||||
.build();
|
||||
|
||||
Ok(tracer_provider)
|
||||
}
|
||||
|
||||
fn init_tracer(config: &TracingConfig) -> anyhow::Result<()> {
|
||||
let sample_rate = config.sample_rate.unwrap_or(1.0);
|
||||
let tracer_provider = match config.exporter {
|
||||
TracingExporterKind::None => return Ok(()),
|
||||
TracingExporterKind::Stdout => stdout_tracer_provider(),
|
||||
TracingExporterKind::Otlp => otlp_tracer_provider(config.endpoint.as_ref())?,
|
||||
TracingExporterKind::Otlp => otlp_tracer_provider(config.endpoint.as_ref(), sample_rate)?,
|
||||
};
|
||||
TRACER_PROVIDER
|
||||
.set(tracer_provider.clone())
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
// Please see LICENSE in the repository root for full details.
|
||||
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize, de::Error as _};
|
||||
use serde_with::skip_serializing_none;
|
||||
use url::Url;
|
||||
|
||||
use super::ConfigurationSection;
|
||||
|
||||
fn sample_rate_example() -> f64 {
|
||||
0.5
|
||||
}
|
||||
|
||||
/// Propagation format for incoming and outgoing requests
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
@@ -61,6 +65,13 @@ pub struct TracingConfig {
|
||||
/// List of propagation formats to use for incoming and outgoing requests
|
||||
#[serde(default)]
|
||||
pub propagators: Vec<Propagator>,
|
||||
|
||||
/// Sample rate for traces
|
||||
///
|
||||
/// Defaults to `1.0` if not set.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[schemars(example = "sample_rate_example", range(min = 0.0, max = 1.0))]
|
||||
pub sample_rate: Option<f64>,
|
||||
}
|
||||
|
||||
impl TracingConfig {
|
||||
@@ -116,6 +127,10 @@ fn sentry_dsn_example() -> &'static str {
|
||||
"https://public@host:port/1"
|
||||
}
|
||||
|
||||
fn sentry_environment_example() -> &'static str {
|
||||
"production"
|
||||
}
|
||||
|
||||
/// Configuration related to the Sentry integration
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct SentryConfig {
|
||||
@@ -123,6 +138,27 @@ pub struct SentryConfig {
|
||||
#[schemars(url, example = "sentry_dsn_example")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub dsn: Option<String>,
|
||||
|
||||
/// Environment to use when sending events to Sentry
|
||||
///
|
||||
/// Defaults to `production` if not set.
|
||||
#[schemars(example = "sentry_environment_example")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub environment: Option<String>,
|
||||
|
||||
/// Sample rate for event submissions
|
||||
///
|
||||
/// Defaults to `1.0` if not set.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[schemars(example = "sample_rate_example", range(min = 0.0, max = 1.0))]
|
||||
pub sample_rate: Option<f32>,
|
||||
|
||||
/// Sample rate for tracing transactions
|
||||
///
|
||||
/// Defaults to `0.0` if not set.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[schemars(example = "sample_rate_example", range(min = 0.0, max = 1.0))]
|
||||
pub traces_sample_rate: Option<f32>,
|
||||
}
|
||||
|
||||
impl SentryConfig {
|
||||
@@ -157,4 +193,35 @@ impl TelemetryConfig {
|
||||
|
||||
impl ConfigurationSection for TelemetryConfig {
|
||||
const PATH: Option<&'static str> = Some("telemetry");
|
||||
|
||||
fn validate(&self, _figment: &figment::Figment) -> Result<(), figment::Error> {
|
||||
if let Some(sample_rate) = self.sentry.sample_rate {
|
||||
if !(0.0..=1.0).contains(&sample_rate) {
|
||||
return Err(figment::error::Error::custom(
|
||||
"Sentry sample rate must be between 0.0 and 1.0",
|
||||
)
|
||||
.with_path("sentry.sample_rate"));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(sample_rate) = self.sentry.traces_sample_rate {
|
||||
if !(0.0..=1.0).contains(&sample_rate) {
|
||||
return Err(figment::error::Error::custom(
|
||||
"Sentry sample rate must be between 0.0 and 1.0",
|
||||
)
|
||||
.with_path("sentry.traces_sample_rate"));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(sample_rate) = self.tracing.sample_rate {
|
||||
if !(0.0..=1.0).contains(&sample_rate) {
|
||||
return Err(figment::error::Error::custom(
|
||||
"Tracing sample rate must be between 0.0 and 1.0",
|
||||
)
|
||||
.with_path("tracing.sample_rate"));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1213,6 +1213,16 @@
|
||||
"items": {
|
||||
"$ref": "#/definitions/Propagator"
|
||||
}
|
||||
},
|
||||
"sample_rate": {
|
||||
"description": "Sample rate for traces\n\nDefaults to `1.0` if not set.",
|
||||
"examples": [
|
||||
0.5
|
||||
],
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1333,6 +1343,33 @@
|
||||
],
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"environment": {
|
||||
"description": "Environment to use when sending events to Sentry\n\nDefaults to `production` if not set.",
|
||||
"examples": [
|
||||
"production"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"sample_rate": {
|
||||
"description": "Sample rate for event submissions\n\nDefaults to `1.0` if not set.",
|
||||
"examples": [
|
||||
0.5
|
||||
],
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0
|
||||
},
|
||||
"traces_sample_rate": {
|
||||
"description": "Sample rate for tracing transactions\n\nDefaults to `0.0` if not set.",
|
||||
"examples": [
|
||||
0.5
|
||||
],
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"maximum": 1.0,
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user