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
65 changes: 18 additions & 47 deletions opentelemetry-otlp/src/exporter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,17 @@ 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.
/// Learn about the relationship between this constant and metrics/spans/logs at
/// <https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#endpoint-urls-for-otlphttp>
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")]
Expand All @@ -36,7 +33,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.
Expand Down Expand Up @@ -129,18 +126,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
Expand All @@ -159,17 +153,20 @@ 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)
Expand All @@ -187,31 +184,5 @@ 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());
}
}
13 changes: 9 additions & 4 deletions opentelemetry-otlp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,21 @@ 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,
OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT,
};

use opentelemetry::sdk::export::ExportError;
Expand Down
28 changes: 25 additions & 3 deletions opentelemetry-otlp/src/metric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,25 @@ use opentelemetry_proto::tonic::collector::metrics::v1::{
metrics_service_client::MetricsServiceClient, ExportMetricsServiceRequest,
};
use std::fmt::{Debug, Formatter};
#[cfg(feature = "grpc-tonic")]
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.
/// Learn about the relationship between this constant and default/spans/logs at
/// <https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#endpoint-urls-for-otlphttp>
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>(
Expand Down Expand Up @@ -263,8 +273,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 {
Expand All @@ -273,7 +295,7 @@ impl MetricsExporter {
.map_err::<crate::Error, _>(Into::into)?,
None => endpoint,
}
.timeout(config.timeout)
.timeout(_timeout)
.connect_lazy();

#[cfg(not(feature = "tls"))]
Expand Down
28 changes: 25 additions & 3 deletions opentelemetry-otlp/src/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use std::fmt::{self, Debug};
use std::time::Duration;

#[cfg(feature = "grpc-tonic")]
use std::str::FromStr;
#[cfg(feature = "grpc-tonic")]
use {
crate::exporter::tonic::{TonicConfig, TonicExporterBuilder},
Expand Down Expand Up @@ -63,6 +65,13 @@ use opentelemetry::{

use async_trait::async_trait;

/// Target to which the exporter is going to send spans, defaults to https://localhost:4317/v1/traces.
/// Learn about the relationship between this constant and default/metrics/logs at
/// <https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#endpoint-urls-for-otlphttp>
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 {
Expand Down Expand Up @@ -313,18 +322,31 @@ 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"))]
let channel = endpoint.timeout(config.timeout).connect_lazy();
let channel = endpoint.timeout(_timeout).connect_lazy();

SpanExporter::from_tonic_channel(config, tonic_config, channel)
}
Expand Down