44// SPDX-License-Identifier: AGPL-3.0-only
55// Please see LICENSE in the repository root for full details.
66
7- use std:: {
8- sync:: { LazyLock , OnceLock } ,
9- time:: Duration ,
10- } ;
7+ use std:: sync:: { LazyLock , OnceLock } ;
118
129use anyhow:: Context as _;
1310use bytes:: Bytes ;
@@ -27,9 +24,11 @@ use opentelemetry_otlp::{WithExportConfig, WithHttpConfig};
2724use opentelemetry_prometheus:: PrometheusExporter ;
2825use opentelemetry_sdk:: {
2926 Resource ,
30- metrics:: { ManualReader , PeriodicReader , SdkMeterProvider } ,
27+ metrics:: { ManualReader , SdkMeterProvider , periodic_reader_with_async_runtime :: PeriodicReader } ,
3128 propagation:: { BaggagePropagator , TraceContextPropagator } ,
32- trace:: { Sampler , Tracer , TracerProvider } ,
29+ trace:: {
30+ Sampler , SdkTracerProvider , Tracer , span_processor_with_async_runtime:: BatchSpanProcessor ,
31+ } ,
3332} ;
3433use opentelemetry_semantic_conventions as semcov;
3534use prometheus:: Registry ;
@@ -47,6 +46,7 @@ pub static METER: LazyLock<Meter> =
4746
4847pub static TRACER : OnceLock < Tracer > = OnceLock :: new ( ) ;
4948static METER_PROVIDER : OnceLock < SdkMeterProvider > = OnceLock :: new ( ) ;
49+ static TRACER_PROVIDER : OnceLock < SdkTracerProvider > = OnceLock :: new ( ) ;
5050static PROMETHEUS_REGISTRY : OnceLock < Registry > = OnceLock :: new ( ) ;
5151
5252pub fn setup ( config : & TelemetryConfig ) -> anyhow:: Result < ( ) > {
@@ -63,12 +63,16 @@ pub fn setup(config: &TelemetryConfig) -> anyhow::Result<()> {
6363 Ok ( ( ) )
6464}
6565
66- pub fn shutdown ( ) {
67- opentelemetry:: global:: shutdown_tracer_provider ( ) ;
66+ pub fn shutdown ( ) -> opentelemetry_sdk:: error:: OTelSdkResult {
67+ if let Some ( tracer_provider) = TRACER_PROVIDER . get ( ) {
68+ tracer_provider. shutdown ( ) ?;
69+ }
6870
6971 if let Some ( meter_provider) = METER_PROVIDER . get ( ) {
70- meter_provider. shutdown ( ) . unwrap ( ) ;
72+ meter_provider. shutdown ( ) ? ;
7173 }
74+
75+ Ok ( ( ) )
7276}
7377
7478fn match_propagator ( propagator : Propagator ) -> Box < dyn TextMapPropagator + Send + Sync > {
@@ -86,14 +90,14 @@ fn propagator(propagators: &[Propagator]) -> TextMapCompositePropagator {
8690 TextMapCompositePropagator :: new ( propagators)
8791}
8892
89- fn stdout_tracer_provider ( ) -> TracerProvider {
93+ fn stdout_tracer_provider ( ) -> SdkTracerProvider {
9094 let exporter = opentelemetry_stdout:: SpanExporter :: default ( ) ;
91- TracerProvider :: builder ( )
95+ SdkTracerProvider :: builder ( )
9296 . with_simple_exporter ( exporter)
9397 . build ( )
9498}
9599
96- fn otlp_tracer_provider ( endpoint : Option < & Url > ) -> anyhow:: Result < TracerProvider > {
100+ fn otlp_tracer_provider ( endpoint : Option < & Url > ) -> anyhow:: Result < SdkTracerProvider > {
97101 let mut exporter = opentelemetry_otlp:: SpanExporter :: builder ( )
98102 . with_http ( )
99103 . with_http_client ( mas_http:: reqwest_client ( ) ) ;
@@ -104,8 +108,11 @@ fn otlp_tracer_provider(endpoint: Option<&Url>) -> anyhow::Result<TracerProvider
104108 . build ( )
105109 . context ( "Failed to configure OTLP trace exporter" ) ?;
106110
107- let tracer_provider = opentelemetry_sdk:: trace:: TracerProvider :: builder ( )
108- . with_batch_exporter ( exporter, opentelemetry_sdk:: runtime:: Tokio )
111+ let batch_processor =
112+ BatchSpanProcessor :: builder ( exporter, opentelemetry_sdk:: runtime:: Tokio ) . build ( ) ;
113+
114+ let tracer_provider = SdkTracerProvider :: builder ( )
115+ . with_span_processor ( batch_processor)
109116 . with_resource ( resource ( ) )
110117 . with_sampler ( Sampler :: AlwaysOn )
111118 . build ( ) ;
@@ -119,6 +126,9 @@ fn init_tracer(config: &TracingConfig) -> anyhow::Result<()> {
119126 TracingExporterKind :: Stdout => stdout_tracer_provider ( ) ,
120127 TracingExporterKind :: Otlp => otlp_tracer_provider ( config. endpoint . as_ref ( ) ) ?,
121128 } ;
129+ TRACER_PROVIDER
130+ . set ( tracer_provider. clone ( ) )
131+ . map_err ( |_| anyhow:: anyhow!( "TRACER_PROVIDER was set twice" ) ) ?;
122132
123133 let tracer = tracer_provider. tracer_with_scope ( SCOPE . clone ( ) ) ;
124134 TRACER
@@ -232,25 +242,20 @@ fn init_meter(config: &MetricsConfig) -> anyhow::Result<()> {
232242}
233243
234244fn resource ( ) -> Resource {
235- let resource = Resource :: new ( [
236- KeyValue :: new ( semcov:: resource:: SERVICE_NAME , env ! ( "CARGO_PKG_NAME" ) ) ,
237- KeyValue :: new ( semcov:: resource:: SERVICE_VERSION , crate :: VERSION ) ,
238- KeyValue :: new ( semcov:: resource:: PROCESS_RUNTIME_NAME , "rust" ) ,
239- KeyValue :: new (
240- semcov:: resource:: PROCESS_RUNTIME_VERSION ,
241- env ! ( "VERGEN_RUSTC_SEMVER" ) ,
242- ) ,
243- ] ) ;
244-
245- let detected = Resource :: from_detectors (
246- Duration :: from_secs ( 5 ) ,
247- vec ! [
248- Box :: new( opentelemetry_sdk:: resource:: EnvResourceDetector :: new( ) ) ,
245+ Resource :: builder ( )
246+ . with_service_name ( env ! ( "CARGO_PKG_NAME" ) )
247+ . with_detectors ( & [
248+ Box :: new ( opentelemetry_resource_detectors:: HostResourceDetector :: default ( ) ) ,
249249 Box :: new ( opentelemetry_resource_detectors:: OsResourceDetector ) ,
250250 Box :: new ( opentelemetry_resource_detectors:: ProcessResourceDetector ) ,
251- Box :: new( opentelemetry_sdk:: resource:: TelemetryResourceDetector ) ,
252- ] ,
253- ) ;
254-
255- resource. merge ( & detected)
251+ ] )
252+ . with_attributes ( [
253+ KeyValue :: new ( semcov:: resource:: SERVICE_VERSION , crate :: VERSION ) ,
254+ KeyValue :: new ( semcov:: resource:: PROCESS_RUNTIME_NAME , "rust" ) ,
255+ KeyValue :: new (
256+ semcov:: resource:: PROCESS_RUNTIME_VERSION ,
257+ env ! ( "VERGEN_RUSTC_SEMVER" ) ,
258+ ) ,
259+ ] )
260+ . build ( )
256261}
0 commit comments