Skip to main content

tor_config_shared/
opentelemetry.rs

1//! Configuration for OpenTelemetry exporter
2
3use amplify::Getters;
4use derive_deftly::Deftly;
5use serde::{Deserialize, Serialize};
6use std::time::Duration;
7use tor_config::derive::prelude::*;
8use tor_config_path::CfgPath;
9
10/// Configuration for exporting spans with OpenTelemetry.
11#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize, Getters)]
12#[derive_deftly(TorConfig)]
13pub struct OpentelemetryConfig {
14    /// Write spans to a file in OTLP JSON format.
15    #[deftly(tor_config(default))]
16    file: Option<OpentelemetryFileExporterConfig>,
17    /// Export spans via HTTP.
18    #[deftly(tor_config(default))]
19    http: Option<OpentelemetryHttpExporterConfig>,
20}
21
22/// Configuration for the OpenTelemetry HTTP exporter.
23#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize, Getters)]
24#[derive_deftly(TorConfig)]
25#[deftly(tor_config(no_default_trait))]
26pub struct OpentelemetryHttpExporterConfig {
27    /// HTTP(S) endpoint to send spans to.
28    ///
29    /// For Jaeger, this should be something like: `http://localhost:4318/v1/traces`
30    #[deftly(tor_config(no_default))]
31    endpoint: String,
32    /// Configuration for how to batch exports.
33    #[deftly(tor_config(sub_builder))]
34    batch: OpentelemetryBatchConfig,
35    // TODO: A different approach to this may be better, as getting the default in this way
36    // prevents the use of environment variables to override this, and also is inconsistent with
37    // other aspects of configuration.
38    /// Timeout for sending data.
39    #[deftly(tor_config(default = "opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT"))]
40    timeout: Duration,
41    // TODO: Once opentelemetry-otlp supports more than one protocol over HTTP, add a config option
42    // to choose protocol here.
43}
44
45/// Configuration for the OpenTelemetry File exporter.
46#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize, Getters)]
47#[derive_deftly(TorConfig)]
48#[deftly(tor_config(no_default_trait))]
49pub struct OpentelemetryFileExporterConfig {
50    /// The path to write the JSON file to.
51    #[deftly(tor_config(no_default))]
52    path: CfgPath,
53    /// Configuration for how to batch writes.
54    #[deftly(tor_config(sub_builder))]
55    batch: OpentelemetryBatchConfig,
56}
57
58/// Configuration for the Opentelemetry batch exporting.
59///
60/// This is a copy of [`opentelemetry_sdk::trace::BatchConfig`].
61#[derive(Debug, Clone, Deftly, Eq, PartialEq, Serialize, Deserialize, Getters)]
62#[derive_deftly(TorConfig)]
63pub struct OpentelemetryBatchConfig {
64    /// Maximum queue size. See [`opentelemetry_sdk::trace::BatchConfig::max_queue_size`].
65    #[deftly(tor_config(default))]
66    max_queue_size: Option<usize>,
67    /// Maximum export batch size. See [`opentelemetry_sdk::trace::BatchConfig::max_export_batch_size`].
68    #[deftly(tor_config(default))]
69    max_export_batch_size: Option<usize>,
70    /// Scheduled delay. See [`opentelemetry_sdk::trace::BatchConfig::scheduled_delay`].
71    #[deftly(tor_config(default = "Duration::from_secs(5)"))]
72    scheduled_delay: Duration,
73}
74
75impl From<OpentelemetryBatchConfig> for opentelemetry_sdk::trace::BatchConfig {
76    fn from(config: OpentelemetryBatchConfig) -> opentelemetry_sdk::trace::BatchConfig {
77        let batch_config = opentelemetry_sdk::trace::BatchConfigBuilder::default();
78
79        let batch_config = if let Some(max_queue_size) = config.max_queue_size {
80            batch_config.with_max_queue_size(max_queue_size)
81        } else {
82            batch_config
83        };
84
85        let batch_config = if let Some(max_export_batch_size) = config.max_export_batch_size {
86            batch_config.with_max_export_batch_size(max_export_batch_size)
87        } else {
88            batch_config
89        };
90
91        let batch_config = batch_config.with_scheduled_delay(config.scheduled_delay);
92
93        batch_config.build()
94    }
95}