Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

automatically add traces / metrics paths #806

Merged
67 changes: 20 additions & 47 deletions opentelemetry-otlp/src/exporter/mod.rs
Original file line number Diff line number Diff line change
@@ -12,20 +12,15 @@ use crate::Protocol;
use std::str::FromStr;
use std::time::Duration;

/// Target to which the exporter is going to send spans or metrics, defaults to https://localhost:4317.
/// Target to which the exporter is going to send signals, defaults to https://localhost:4317.
pub const OTEL_EXPORTER_OTLP_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_ENDPOINT";
/// Default target to which the exporter is going to send spans or metrics.
/// Default target to which the exporter is going to send signals.
pub const OTEL_EXPORTER_OTLP_ENDPOINT_DEFAULT: &str = "https://localhost:4317";
/// Max waiting time for the backend to process each spans or metrics batch, defaults to 10 seconds.
/// Max waiting time for the backend to process each signal batch, defaults to 10 seconds.
pub const OTEL_EXPORTER_OTLP_TIMEOUT: &str = "OTEL_EXPORTER_OTLP_TIMEOUT";
/// Default max waiting time for the backend to process each spans or metrics batch.
/// Default max waiting time for the backend to process each signal batch.
pub const OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT: u64 = 10;

/// Target to which the exporter is going to send spans, defaults to https://localhost:4317.
pub const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
/// Max waiting time for the backend to process each spans batch, defaults to 10s.
pub const OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: &str = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT";

#[cfg(feature = "grpc-sys")]
pub(crate) mod grpcio;
#[cfg(feature = "http-proto")]
@@ -36,7 +31,7 @@ pub(crate) mod tonic;
/// Configuration for the OTLP exporter.
#[derive(Debug)]
pub struct ExportConfig {
/// The address of the OTLP collector. If not set, the default address is used.
/// The base address of the OTLP collector. If not set, the default address is used.
pub endpoint: String,

/// The protocol to use when communicating with the collector.
@@ -129,18 +124,15 @@ impl<B: HasExportConfig> WithExportConfig for B {
}

fn with_env(mut self) -> Self {
let endpoint = match std::env::var(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) {
let endpoint = match std::env::var(OTEL_EXPORTER_OTLP_ENDPOINT) {
Ok(val) => val,
Err(_) => std::env::var(OTEL_EXPORTER_OTLP_ENDPOINT)
.unwrap_or_else(|_| OTEL_EXPORTER_OTLP_ENDPOINT_DEFAULT.to_string()),
Err(_) => OTEL_EXPORTER_OTLP_ENDPOINT_DEFAULT.to_string()
};
self.export_config().endpoint = endpoint;

let timeout = match std::env::var(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT) {
let timeout = match std::env::var(OTEL_EXPORTER_OTLP_TIMEOUT) {
Ok(val) => u64::from_str(&val).unwrap_or(OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT),
Err(_) => std::env::var(OTEL_EXPORTER_OTLP_TIMEOUT)
.map(|val| u64::from_str(&val).unwrap_or(OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT))
.unwrap_or(OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT),
Err(_) => OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT,
};
self.export_config().timeout = Duration::from_secs(timeout);
self
@@ -159,17 +151,23 @@ impl<B: HasExportConfig> WithExportConfig for B {
mod tests {
use crate::exporter::{
WithExportConfig, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_TIMEOUT,
OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
OTEL_EXPORTER_OTLP_TRACES_TIMEOUT,
OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT
};
use crate::new_exporter;

#[test]
fn test_pipeline_builder_from_env() {
std::env::set_var(OTEL_EXPORTER_OTLP_ENDPOINT, "https://otlp_endpoint:4317");
fn test_pipeline_builder_from_env_default_vars() {
let expected_endpoint = "https://otlp_endpoint:4317";
std::env::set_var(OTEL_EXPORTER_OTLP_ENDPOINT, expected_endpoint);
std::env::set_var(OTEL_EXPORTER_OTLP_TIMEOUT, "bad_timeout");

let mut exporter_builder = new_exporter().tonic().with_env();
assert_eq!(
exporter_builder.exporter_config.endpoint,
expected_endpoint
);

exporter_builder = new_exporter().tonic().with_env();
assert_eq!(
exporter_builder.exporter_config.timeout,
std::time::Duration::from_secs(OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT)
@@ -187,31 +185,6 @@ mod tests {
std::env::remove_var(OTEL_EXPORTER_OTLP_TIMEOUT);
assert!(std::env::var(OTEL_EXPORTER_OTLP_ENDPOINT).is_err());
assert!(std::env::var(OTEL_EXPORTER_OTLP_TIMEOUT).is_err());
}

// test from traces env var
std::env::set_var(
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
"https://otlp_traces_endpoint:4317",
);
std::env::set_var(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, "bad_timeout");

let mut exporter_builder = new_exporter().tonic().with_env();
assert_eq!(
exporter_builder.exporter_config.timeout,
std::time::Duration::from_secs(OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT)
);

std::env::set_var(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, "60");

exporter_builder = new_exporter().tonic().with_env();
assert_eq!(
exporter_builder.exporter_config.timeout,
std::time::Duration::from_secs(60)
);

std::env::remove_var(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT);
std::env::remove_var(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT);
assert!(std::env::var(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT).is_err());
assert!(std::env::var(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT).is_err());
}
}
16 changes: 10 additions & 6 deletions opentelemetry-otlp/src/lib.rs
Original file line number Diff line number Diff line change
@@ -189,16 +189,20 @@ mod transform;

pub use crate::exporter::ExportConfig;
#[cfg(feature = "trace")]
pub use crate::span::{OtlpTracePipeline, SpanExporter, SpanExporterBuilder};
pub use crate::span::{
OtlpTracePipeline, SpanExporter, SpanExporterBuilder, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
OTEL_EXPORTER_OTLP_TRACES_TIMEOUT,
};

#[cfg(feature = "metrics")]
pub use crate::metric::{MetricsExporter, OtlpMetricPipeline};
pub use crate::metric::{
MetricsExporter, OtlpMetricPipeline, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
OTEL_EXPORTER_OTLP_METRICS_TIMEOUT,
};

pub use crate::exporter::{
HasExportConfig, WithExportConfig, OTEL_EXPORTER_OTLP_ENDPOINT,
OTEL_EXPORTER_OTLP_ENDPOINT_DEFAULT, OTEL_EXPORTER_OTLP_TIMEOUT,
OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
OTEL_EXPORTER_OTLP_TRACES_TIMEOUT,
HasExportConfig, WithExportConfig, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_TIMEOUT,
OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT, OTEL_EXPORTER_OTLP_ENDPOINT_DEFAULT
};

use opentelemetry::sdk::export::ExportError;
25 changes: 22 additions & 3 deletions opentelemetry-otlp/src/metric.rs
Original file line number Diff line number Diff line change
@@ -25,15 +25,22 @@ use opentelemetry_proto::tonic::collector::metrics::v1::{
metrics_service_client::MetricsServiceClient, ExportMetricsServiceRequest,
};
use std::fmt::{Debug, Formatter};
use std::str::FromStr;
use std::sync::Arc;
use std::sync::Mutex;
use std::time;
use std::time::Duration;
use tonic::metadata::KeyAndValueRef;
#[cfg(feature = "grpc-tonic")]
use tonic::transport::Channel;
#[cfg(feature = "grpc-tonic")]
use tonic::Request;

/// Target to which the exporter is going to send metrics, defaults to https://localhost:4317/v1/metrics.
pub const OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT";
/// Max waiting time for the backend to process each metrics batch, defaults to 10s.
pub const OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: &str = "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT";

impl OtlpPipeline {
/// Create a OTLP metrics pipeline.
pub fn metrics<SP, SO, I, IO>(
@@ -263,8 +270,20 @@ impl MetricsExporter {
mut tonic_config: TonicConfig,
export_selector: T,
) -> Result<MetricsExporter> {
let endpoint =
Channel::from_shared(config.endpoint).map_err::<crate::Error, _>(Into::into)?;
let endpoint = match std::env::var(OTEL_EXPORTER_OTLP_METRICS_ENDPOINT) {
Ok(val) => val,
Err(_) => format!("{}{}", config.endpoint, "/v1/metrics"),
};

let timeout = match std::env::var(OTEL_EXPORTER_OTLP_METRICS_TIMEOUT) {
Ok(val) => match u64::from_str(&val) {
Ok(seconds) => Duration::from_secs(seconds),
Err(_) => config.timeout,
},
Err(_) => config.timeout,
};

let endpoint = Channel::from_shared(endpoint).map_err::<crate::Error, _>(Into::into)?;

#[cfg(all(feature = "tls"))]
let channel = match tonic_config.tls_config {
@@ -273,7 +292,7 @@ impl MetricsExporter {
.map_err::<crate::Error, _>(Into::into)?,
None => endpoint,
}
.timeout(config.timeout)
.timeout(timeout)
.connect_lazy();

#[cfg(not(feature = "tls"))]
23 changes: 21 additions & 2 deletions opentelemetry-otlp/src/span.rs
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
//! Defines a [SpanExporter] to send trace data via the OpenTelemetry Protocol (OTLP)
use std::fmt::{self, Debug};
use std::str::FromStr;
use std::time::Duration;

#[cfg(feature = "grpc-tonic")]
@@ -63,6 +64,11 @@ use opentelemetry::{

use async_trait::async_trait;

/// Target to which the exporter is going to send spans, defaults to https://localhost:4317.
pub const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
/// Max waiting time for the backend to process each spans batch, defaults to 10s.
pub const OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: &str = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT";

impl OtlpPipeline {
/// Create a OTLP tracing pipeline.
pub fn tracing(self) -> OtlpTracePipeline {
@@ -313,14 +319,27 @@ impl SpanExporter {
config: ExportConfig,
tonic_config: TonicConfig,
) -> Result<Self, crate::Error> {
let endpoint = TonicChannel::from_shared(config.endpoint.clone())?;
let endpoint_str = match std::env::var(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) {
Ok(val) => val,
Err(_) => format!("{}{}", config.endpoint, "/v1/traces"),
};

let endpoint = TonicChannel::from_shared(endpoint_str)?;

let timeout = match std::env::var(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT) {
Ok(val) => match u64::from_str(&val) {
Ok(seconds) => Duration::from_secs(seconds),
Err(_) => config.timeout,
},
Err(_) => config.timeout,
};

#[cfg(feature = "tls")]
let channel = match tonic_config.tls_config.as_ref() {
Some(tls_config) => endpoint.tls_config(tls_config.clone())?,
None => endpoint,
}
.timeout(config.timeout)
.timeout(timeout)
.connect_lazy();

#[cfg(not(feature = "tls"))]