Skip to main content

o_sfu/config/
telemetry.rs

1use std::time::Duration;
2
3use anyhow::{Result, anyhow};
4pub use o_sfu_telemetry::{
5    DEFAULT_MEDIA_QUALITY_INTERVAL, DEFAULT_TELEMETRY_DEPLOYMENT_ENVIRONMENT,
6    DEFAULT_TELEMETRY_SERVICE_NAME, TelemetryConfig, TelemetryLogFormat, TelemetryResource,
7    TraceExportConfig,
8};
9
10use super::env::{Env, EnvParse, EnvValue, non_empty};
11
12const OTEL_TRACING_FEATURE_NAME: &str = "otel-tracing";
13const MEDIA_QUALITY_INTERVAL_ENV: &str = "TELEMETRY_MEDIA_QUALITY_INTERVAL_MS";
14
15impl EnvParse for TelemetryLogFormat {
16    fn parse(value: EnvValue) -> Result<Self> {
17        let key = value.key();
18        match value.as_str() {
19            "compact" => Ok(Self::Compact),
20            "json" => Ok(Self::Json),
21            _ => Err(anyhow!("{key} must be either `compact` or `json`")),
22        }
23    }
24}
25
26pub(super) fn load_telemetry_config(env: &Env<'_>) -> Result<TelemetryConfig> {
27    let log_format = env
28        .var("TELEMETRY_LOG_FORMAT")
29        .default(TelemetryLogFormat::default())?;
30    let otlp_endpoint = env
31        .var("TELEMETRY_OTLP_ENDPOINT")
32        .check(non_empty)
33        .optional()?;
34    if !cfg!(feature = "otel-tracing") && otlp_endpoint.is_some() {
35        return Err(anyhow!(
36            "TELEMETRY_OTLP_ENDPOINT requires the `{OTEL_TRACING_FEATURE_NAME}` cargo feature"
37        ));
38    }
39    let media_quality_interval_ms = env
40        .var(MEDIA_QUALITY_INTERVAL_ENV)
41        .default(u64::try_from(DEFAULT_MEDIA_QUALITY_INTERVAL.as_millis()).unwrap_or(5_000))?;
42    let service_name = env
43        .var("TELEMETRY_SERVICE_NAME")
44        .check(non_empty)
45        .optional()?;
46    let deployment_environment = env
47        .var("TELEMETRY_DEPLOYMENT_ENVIRONMENT")
48        .check(non_empty)
49        .optional()?;
50    let service_instance_id = env
51        .var("TELEMETRY_SERVICE_INSTANCE_ID")
52        .check(non_empty)
53        .optional()?;
54    Ok(TelemetryConfig {
55        log_format,
56        resource: TelemetryResource {
57            service_name: service_name.unwrap_or_else(|| DEFAULT_TELEMETRY_SERVICE_NAME.to_owned()),
58            deployment_environment: deployment_environment
59                .unwrap_or_else(|| DEFAULT_TELEMETRY_DEPLOYMENT_ENVIRONMENT.to_owned()),
60            service_instance_id,
61        },
62        trace_export: TraceExportConfig { otlp_endpoint },
63        media_quality_interval: (media_quality_interval_ms > 0)
64            .then(|| Duration::from_millis(media_quality_interval_ms)),
65    })
66}
67
68#[cfg(test)]
69#[path = "TESTS/telemetry.rs"]
70mod tests;