|
4 | 4 | //! to send traces to the Datadog agent in batches over gRPC. |
5 | 5 | //! |
6 | 6 | //! It also contains a convenience function to build a layer with the tracer. |
7 | | -use opentelemetry::sdk::trace::{RandomIdGenerator, Sampler, Tracer}; |
8 | | -use opentelemetry::sdk::{trace, Resource}; |
9 | | -pub use opentelemetry::trace::{TraceError, TraceResult}; |
10 | | -use opentelemetry::KeyValue; |
| 7 | +use crate::error::Error; |
| 8 | +use opentelemetry::trace::TracerProvider; |
11 | 9 | use opentelemetry_otlp::WithExportConfig; |
| 10 | +use opentelemetry_sdk::trace::{RandomIdGenerator, Sampler, SdkTracerProvider, Tracer}; |
| 11 | +use opentelemetry_sdk::Resource; |
12 | 12 | use std::time::Duration; |
13 | 13 | use tracing::Subscriber; |
14 | 14 | use tracing_opentelemetry::{OpenTelemetryLayer, PreSampledTracer}; |
15 | 15 | use tracing_subscriber::registry::LookupSpan; |
16 | 16 |
|
17 | | -pub fn build_tracer(service_name: &str) -> TraceResult<Tracer> { |
18 | | - let exporter = opentelemetry_otlp::new_exporter() |
19 | | - .tonic() |
20 | | - .with_timeout(Duration::from_secs(3)); |
| 17 | +pub struct ProviderGuard { |
| 18 | + tracer_provider: SdkTracerProvider, |
| 19 | +} |
| 20 | + |
| 21 | +impl Drop for ProviderGuard { |
| 22 | + fn drop(&mut self) { |
| 23 | + let _ = self.tracer_provider.force_flush(); |
| 24 | + let _ = self.tracer_provider.shutdown(); |
| 25 | + } |
| 26 | +} |
| 27 | + |
| 28 | +pub fn build_tracer_provider(service_name: String) -> Result<SdkTracerProvider, Error> { |
| 29 | + let exporter = opentelemetry_otlp::SpanExporter::builder() |
| 30 | + .with_tonic() |
| 31 | + .with_timeout(Duration::from_secs(3)) |
| 32 | + .build()?; |
| 33 | + let resource = Resource::builder().with_service_name(service_name).build(); |
| 34 | + |
| 35 | + let provider = SdkTracerProvider::builder() |
| 36 | + .with_sampler(Sampler::AlwaysOn) |
| 37 | + .with_resource(resource) |
| 38 | + .with_id_generator(RandomIdGenerator::default()) |
| 39 | + .with_batch_exporter(exporter) |
| 40 | + .build(); |
21 | 41 |
|
22 | | - opentelemetry_otlp::new_pipeline() |
23 | | - .tracing() |
24 | | - .with_trace_config( |
25 | | - trace::config() |
26 | | - .with_sampler(Sampler::AlwaysOn) |
27 | | - .with_resource(Resource::new(vec![KeyValue::new( |
28 | | - "service.name", |
29 | | - service_name.to_string(), |
30 | | - )])) |
31 | | - .with_id_generator(RandomIdGenerator::default()), |
32 | | - ) |
33 | | - .with_exporter(exporter) |
34 | | - .install_batch(opentelemetry::runtime::Tokio) |
| 42 | + Ok(provider) |
35 | 43 | } |
36 | 44 |
|
37 | | -pub fn build_layer<S>(service_name: &str) -> TraceResult<OpenTelemetryLayer<S, Tracer>> |
| 45 | +pub fn build_layer<S>( |
| 46 | + service_name: String, |
| 47 | +) -> Result<(OpenTelemetryLayer<S, Tracer>, ProviderGuard), Error> |
38 | 48 | where |
39 | 49 | Tracer: opentelemetry::trace::Tracer + PreSampledTracer + 'static, |
40 | 50 | S: Subscriber + for<'span> LookupSpan<'span>, |
41 | 51 | { |
42 | | - let tracer = build_tracer(service_name)?; |
43 | | - Ok(tracing_opentelemetry::layer().with_tracer(tracer)) |
| 52 | + let tracer_provider = build_tracer_provider(service_name)?; |
| 53 | + let layer = tracing_opentelemetry::layer().with_tracer(tracer_provider.tracer("")); |
| 54 | + let guard = ProviderGuard { tracer_provider }; |
| 55 | + Ok((layer, guard)) |
44 | 56 | } |
0 commit comments