Skip to content

Commit 12fb33f

Browse files
committed
♻️ split tools into modules jaeger & otlp, and allow to customize pipeline
1 parent 38fdbf1 commit 12fb33f

File tree

4 files changed

+136
-114
lines changed

4 files changed

+136
-114
lines changed

src/tools.rs

Lines changed: 0 additions & 114 deletions
This file was deleted.

src/tools/jaeger.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use opentelemetry::sdk::Resource;
2+
use opentelemetry::{sdk::trace as sdktrace, trace::TraceError};
3+
use opentelemetry_semantic_conventions as semcov;
4+
5+
pub fn identity(v: opentelemetry_jaeger::PipelineBuilder) -> opentelemetry_jaeger::PipelineBuilder {
6+
v
7+
}
8+
9+
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#jaeger-exporter
10+
pub fn init_tracer<F>(resource: Resource, transform: F) -> Result<sdktrace::Tracer, TraceError>
11+
where
12+
F: FnOnce(opentelemetry_jaeger::PipelineBuilder) -> opentelemetry_jaeger::PipelineBuilder,
13+
{
14+
opentelemetry::global::set_text_map_propagator(
15+
opentelemetry::sdk::propagation::TraceContextPropagator::new(),
16+
);
17+
18+
let mut pipeline = opentelemetry_jaeger::new_pipeline();
19+
if let Some(name) = resource.get(semcov::resource::SERVICE_NAME) {
20+
pipeline = pipeline.with_service_name(name.to_string());
21+
}
22+
pipeline = pipeline.with_trace_config(
23+
sdktrace::config()
24+
.with_resource(resource)
25+
.with_sampler(sdktrace::Sampler::AlwaysOn),
26+
);
27+
pipeline = transform(pipeline);
28+
pipeline.install_batch(opentelemetry::runtime::Tokio)
29+
}

src/tools/mod.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use opentelemetry::sdk::Resource;
2+
use opentelemetry::{sdk::trace as sdktrace, trace::TraceError};
3+
use opentelemetry_semantic_conventions as semcov;
4+
5+
#[cfg(feature = "jaeger")]
6+
mod jaeger;
7+
#[cfg(feature = "otlp")]
8+
mod otlp;
9+
10+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11+
pub enum CollectorKind {
12+
#[cfg(feature = "otlp")]
13+
Otlp,
14+
#[cfg(feature = "jaeger")]
15+
Jaeger,
16+
// Stdout,
17+
}
18+
19+
#[cfg(any(feature = "jaeger", feature = "otlp"))]
20+
pub fn init_tracer(
21+
kind: CollectorKind,
22+
resource: Resource,
23+
) -> Result<sdktrace::Tracer, TraceError> {
24+
match kind {
25+
#[cfg(feature = "otlp")]
26+
CollectorKind::Otlp => {
27+
// if let Some(url) = std::env::var_os("OTEL_COLLECTOR_URL")
28+
// "http://localhost:14499/otlp/v1/traces"
29+
// let collector_url = url.to_str().ok_or(TraceError::Other(
30+
// anyhow!("failed to parse OTEL_COLLECTOR_URL").into(),
31+
// ))?;
32+
otlp::init_tracer(resource, otlp::identity)
33+
}
34+
#[cfg(feature = "jaeger")]
35+
CollectorKind::Jaeger => {
36+
// Or "OTEL_EXPORTER_JAEGER_ENDPOINT"
37+
// or now variable
38+
jaeger::init_tracer(resource, jaeger::identity)
39+
}
40+
}
41+
}
42+
43+
/// call with service name and version
44+
///
45+
/// ```rust
46+
/// make_resource(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))
47+
/// ```
48+
pub fn make_resource<S>(service_name: S, service_version: S) -> Resource
49+
where
50+
S: Into<String>,
51+
{
52+
Resource::new(vec![
53+
semcov::resource::SERVICE_NAME.string(service_name.into()),
54+
semcov::resource::SERVICE_VERSION.string(service_version.into()),
55+
])
56+
}
57+
58+
/// Search the current opentelemetry trace id into the Context from the current tracing'span.
59+
/// This function can be used to report the trace id into the error message send back to user.
60+
pub fn find_current_trace_id() -> Option<String> {
61+
use opentelemetry::trace::TraceContextExt;
62+
use tracing_opentelemetry::OpenTelemetrySpanExt;
63+
// let context = opentelemetry::Context::current();
64+
// OpenTelemetry Context is propagation inside code is done via tracing crate
65+
let context = tracing::Span::current().context();
66+
let span = context.span();
67+
let span_context = span.span_context();
68+
span_context
69+
.is_valid()
70+
.then(|| span_context.trace_id().to_string())
71+
}

src/tools/otlp.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use opentelemetry::sdk::Resource;
2+
use opentelemetry::{
3+
global, sdk::propagation::TraceContextPropagator, sdk::trace as sdktrace, trace::TraceError,
4+
};
5+
6+
pub fn identity(v: opentelemetry_otlp::OtlpTracePipeline) -> opentelemetry_otlp::OtlpTracePipeline {
7+
v
8+
}
9+
10+
pub fn init_tracer<F>(resource: Resource, transform: F) -> Result<sdktrace::Tracer, TraceError>
11+
where
12+
F: FnOnce(opentelemetry_otlp::OtlpTracePipeline) -> opentelemetry_otlp::OtlpTracePipeline,
13+
{
14+
use opentelemetry_otlp::WithExportConfig;
15+
16+
global::set_text_map_propagator(TraceContextPropagator::new());
17+
// FIXME choice the right/official env variable `OTEL_COLLECTOR_URL` or `OTEL_EXPORTER_OTLP_ENDPOINT`
18+
// TODO try to autodetect if http or grpc should be used (eg based on env variable, port ???)
19+
//endpoint (default = 0.0.0.0:4317 for grpc protocol, 0.0.0.0:4318 http protocol):
20+
//.http().with_endpoint(collector_url),
21+
let endpoint_grpc = std::env::var("OTEL_EXPORTER_OTLP_ENDPOINT")
22+
.unwrap_or_else(|_| "http://0.0.0.0:4317".to_string());
23+
let exporter = opentelemetry_otlp::new_exporter()
24+
.tonic()
25+
.with_endpoint(endpoint_grpc);
26+
let mut pipeline = opentelemetry_otlp::new_pipeline()
27+
.tracing()
28+
.with_exporter(exporter)
29+
.with_trace_config(
30+
sdktrace::config()
31+
.with_resource(resource)
32+
.with_sampler(sdktrace::Sampler::AlwaysOn),
33+
);
34+
pipeline = transform(pipeline);
35+
pipeline.install_batch(opentelemetry::runtime::Tokio)
36+
}

0 commit comments

Comments
 (0)