1
//! Configuration for OpenTelemetry exporter
2

            
3
use amplify::Getters;
4
use derive_deftly::Deftly;
5
use serde::{Deserialize, Serialize};
6
use std::time::Duration;
7
use tor_config::derive::prelude::*;
8
use 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)]
13
pub 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))]
26
pub 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))]
49
pub 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)]
63
pub 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

            
75
impl 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
}