mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-08 03:01:12 -04:00
feat: Support for sending logs through OTLP (#21039)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@@ -26,7 +26,7 @@ pub use log::{ColorMode, LogArgs, Verbosity};
|
||||
|
||||
/// `TraceArgs` for tracing and spans support
|
||||
mod trace;
|
||||
pub use trace::{OtlpInitStatus, TraceArgs};
|
||||
pub use trace::{OtlpInitStatus, OtlpLogsStatus, TraceArgs};
|
||||
|
||||
/// `MetricArgs` to configure metrics.
|
||||
mod metric;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Opentelemetry tracing configuration through CLI args.
|
||||
//! Opentelemetry tracing and logging configuration through CLI args.
|
||||
|
||||
use clap::Parser;
|
||||
use eyre::WrapErr;
|
||||
@@ -6,7 +6,7 @@ use reth_tracing::{tracing_subscriber::EnvFilter, Layers};
|
||||
use reth_tracing_otlp::OtlpProtocol;
|
||||
use url::Url;
|
||||
|
||||
/// CLI arguments for configuring `Opentelemetry` trace and span export.
|
||||
/// CLI arguments for configuring `Opentelemetry` trace and logs export.
|
||||
#[derive(Debug, Clone, Parser)]
|
||||
pub struct TraceArgs {
|
||||
/// Enable `Opentelemetry` tracing export to an OTLP endpoint.
|
||||
@@ -30,9 +30,29 @@ pub struct TraceArgs {
|
||||
)]
|
||||
pub otlp: Option<Url>,
|
||||
|
||||
/// OTLP transport protocol to use for exporting traces.
|
||||
/// Enable `Opentelemetry` logs export to an OTLP endpoint.
|
||||
///
|
||||
/// - `http`: expects endpoint path to end with `/v1/traces`
|
||||
/// If no value provided, defaults based on protocol:
|
||||
/// - HTTP: `http://localhost:4318/v1/logs`
|
||||
/// - gRPC: `http://localhost:4317`
|
||||
///
|
||||
/// Example: --logs-otlp=http://collector:4318/v1/logs
|
||||
#[arg(
|
||||
long = "logs-otlp",
|
||||
env = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT",
|
||||
global = true,
|
||||
value_name = "URL",
|
||||
num_args = 0..=1,
|
||||
default_missing_value = "http://localhost:4318/v1/logs",
|
||||
require_equals = true,
|
||||
value_parser = parse_otlp_endpoint,
|
||||
help_heading = "Logging"
|
||||
)]
|
||||
pub logs_otlp: Option<Url>,
|
||||
|
||||
/// OTLP transport protocol to use for exporting traces and logs.
|
||||
///
|
||||
/// - `http`: expects endpoint path to end with `/v1/traces` or `/v1/logs`
|
||||
/// - `grpc`: expects endpoint without a path
|
||||
///
|
||||
/// Defaults to HTTP if not specified.
|
||||
@@ -62,6 +82,22 @@ pub struct TraceArgs {
|
||||
)]
|
||||
pub otlp_filter: EnvFilter,
|
||||
|
||||
/// Set a filter directive for the OTLP logs exporter. This controls the verbosity
|
||||
/// of logs sent to the OTLP endpoint. It follows the same syntax as the
|
||||
/// `RUST_LOG` environment variable.
|
||||
///
|
||||
/// Example: --logs-otlp.filter=info,reth=debug
|
||||
///
|
||||
/// Defaults to INFO if not specified.
|
||||
#[arg(
|
||||
long = "logs-otlp.filter",
|
||||
global = true,
|
||||
value_name = "FILTER",
|
||||
default_value = "info",
|
||||
help_heading = "Logging"
|
||||
)]
|
||||
pub logs_otlp_filter: EnvFilter,
|
||||
|
||||
/// Service name to use for OTLP tracing export.
|
||||
///
|
||||
/// This name will be used to identify the service in distributed tracing systems
|
||||
@@ -101,8 +137,10 @@ impl Default for TraceArgs {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
otlp: None,
|
||||
logs_otlp: None,
|
||||
protocol: OtlpProtocol::Http,
|
||||
otlp_filter: EnvFilter::from_default_env(),
|
||||
logs_otlp_filter: EnvFilter::try_new("info").expect("valid filter"),
|
||||
sample_ratio: None,
|
||||
service_name: "reth".to_string(),
|
||||
}
|
||||
@@ -150,6 +188,37 @@ impl TraceArgs {
|
||||
Ok(OtlpInitStatus::Disabled)
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize OTLP logs export with the given layers.
|
||||
///
|
||||
/// This method handles OTLP logs initialization based on the configured options,
|
||||
/// including validation and protocol selection.
|
||||
///
|
||||
/// Returns the initialization status to allow callers to log appropriate messages.
|
||||
pub async fn init_otlp_logs(&mut self, _layers: &mut Layers) -> eyre::Result<OtlpLogsStatus> {
|
||||
if let Some(endpoint) = self.logs_otlp.as_mut() {
|
||||
self.protocol.validate_logs_endpoint(endpoint)?;
|
||||
|
||||
#[cfg(feature = "otlp-logs")]
|
||||
{
|
||||
let config = reth_tracing_otlp::OtlpLogsConfig::new(
|
||||
self.service_name.clone(),
|
||||
endpoint.clone(),
|
||||
self.protocol,
|
||||
)?;
|
||||
|
||||
_layers.with_log_layer(config.clone(), self.logs_otlp_filter.clone())?;
|
||||
|
||||
Ok(OtlpLogsStatus::Started(config.endpoint().clone()))
|
||||
}
|
||||
#[cfg(not(feature = "otlp-logs"))]
|
||||
{
|
||||
Ok(OtlpLogsStatus::NoFeature)
|
||||
}
|
||||
} else {
|
||||
Ok(OtlpLogsStatus::Disabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Status of OTLP tracing initialization.
|
||||
@@ -163,6 +232,17 @@ pub enum OtlpInitStatus {
|
||||
NoFeature,
|
||||
}
|
||||
|
||||
/// Status of OTLP logs initialization.
|
||||
#[derive(Debug)]
|
||||
pub enum OtlpLogsStatus {
|
||||
/// OTLP logs export was successfully started with the given endpoint.
|
||||
Started(Url),
|
||||
/// OTLP logs export is disabled (no endpoint configured).
|
||||
Disabled,
|
||||
/// OTLP logs arguments provided but feature is not compiled.
|
||||
NoFeature,
|
||||
}
|
||||
|
||||
// Parses an OTLP endpoint url.
|
||||
fn parse_otlp_endpoint(arg: &str) -> eyre::Result<Url> {
|
||||
Url::parse(arg).wrap_err("Invalid URL for OTLP trace output")
|
||||
|
||||
Reference in New Issue
Block a user