reth_node_core/args/
trace.rs

1//! Opentelemetry tracing configuration through CLI args.
2
3use clap::Parser;
4use eyre::WrapErr;
5use reth_tracing::tracing_subscriber::EnvFilter;
6use reth_tracing_otlp::OtlpProtocol;
7use url::Url;
8
9/// CLI arguments for configuring `Opentelemetry` trace and span export.
10#[derive(Debug, Clone, Parser)]
11pub struct TraceArgs {
12    /// Enable `Opentelemetry` tracing export to an OTLP endpoint.
13    ///
14    /// If no value provided, defaults based on protocol:
15    /// - HTTP: `http://localhost:4318/v1/traces`
16    /// - gRPC: `http://localhost:4317`
17    ///
18    /// Example: --tracing-otlp=http://collector:4318/v1/traces
19    #[arg(
20        long = "tracing-otlp",
21        // Per specification.
22        env = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
23        global = true,
24        value_name = "URL",
25        num_args = 0..=1,
26        default_missing_value = "http://localhost:4318/v1/traces",
27        require_equals = true,
28        value_parser = parse_otlp_endpoint,
29        help_heading = "Tracing"
30    )]
31    pub otlp: Option<Url>,
32
33    /// OTLP transport protocol to use for exporting traces.
34    ///
35    /// - `http`: expects endpoint path to end with `/v1/traces`
36    /// - `grpc`: expects endpoint without a path
37    ///
38    /// Defaults to HTTP if not specified.
39    #[arg(
40        long = "tracing-otlp-protocol",
41        env = "OTEL_EXPORTER_OTLP_PROTOCOL",
42        global = true,
43        value_name = "PROTOCOL",
44        default_value = "http",
45        help_heading = "Tracing"
46    )]
47    pub protocol: OtlpProtocol,
48
49    /// Set a filter directive for the OTLP tracer. This controls the verbosity
50    /// of spans and events sent to the OTLP endpoint. It follows the same
51    /// syntax as the `RUST_LOG` environment variable.
52    ///
53    /// Example: --tracing-otlp.filter=info,reth=debug,hyper_util=off
54    ///
55    /// Defaults to TRACE if not specified.
56    #[arg(
57        long = "tracing-otlp.filter",
58        global = true,
59        value_name = "FILTER",
60        default_value = "debug",
61        help_heading = "Tracing"
62    )]
63    pub otlp_filter: EnvFilter,
64}
65
66impl Default for TraceArgs {
67    fn default() -> Self {
68        Self {
69            otlp: None,
70            protocol: OtlpProtocol::Http,
71            otlp_filter: EnvFilter::from_default_env(),
72        }
73    }
74}
75
76impl TraceArgs {
77    /// Validate the configuration
78    pub fn validate(&mut self) -> eyre::Result<()> {
79        if let Some(url) = &mut self.otlp {
80            self.protocol.validate_endpoint(url)?;
81        }
82        Ok(())
83    }
84}
85
86// Parses an OTLP endpoint url.
87fn parse_otlp_endpoint(arg: &str) -> eyre::Result<Url> {
88    Url::parse(arg).wrap_err("Invalid URL for OTLP trace output")
89}