@@ -8,7 +8,7 @@ use tracing_core::Level;
88use tracing_core:: Metadata ;
99#[ cfg( feature = "experimental_metadata_attributes" ) ]
1010use tracing_log:: NormalizeEvent ;
11- use tracing_subscriber:: Layer ;
11+ use tracing_subscriber:: { registry :: LookupSpan , Layer } ;
1212
1313const INSTRUMENTATION_LIBRARY_NAME : & str = "opentelemetry-appender-tracing" ;
1414
@@ -149,7 +149,7 @@ where
149149
150150impl < S , P , L > Layer < S > for OpenTelemetryTracingBridge < P , L >
151151where
152- S : tracing:: Subscriber ,
152+ S : tracing:: Subscriber + for < ' a > LookupSpan < ' a > ,
153153 P : LoggerProvider < Logger = L > + Send + Sync + ' static ,
154154 L : Logger + Send + Sync + ' static ,
155155{
@@ -180,6 +180,26 @@ where
180180 // Visit fields.
181181 event. record ( & mut visitor) ;
182182
183+ #[ cfg( feature = "experimental_use_tracing_span_context" ) ]
184+ if let Some ( span) = _ctx. event_span ( event) {
185+ use tracing_opentelemetry:: OtelData ;
186+ let opt_span_id = span
187+ . extensions ( )
188+ . get :: < OtelData > ( )
189+ . and_then ( |otd| otd. builder . span_id ) ;
190+
191+ let opt_trace_id = span. scope ( ) . last ( ) . and_then ( |root_span| {
192+ root_span
193+ . extensions ( )
194+ . get :: < OtelData > ( )
195+ . and_then ( |otd| otd. builder . trace_id )
196+ } ) ;
197+
198+ if let Some ( ( trace_id, span_id) ) = opt_trace_id. zip ( opt_span_id) {
199+ log_record. set_trace_context ( trace_id, span_id, None ) ;
200+ }
201+ }
202+
183203 //emit record
184204 self . logger . emit ( log_record) ;
185205 }
@@ -213,9 +233,9 @@ mod tests {
213233 use opentelemetry:: trace:: TracerProvider as _;
214234 use opentelemetry:: trace:: { TraceContextExt , TraceFlags , Tracer } ;
215235 use opentelemetry:: { logs:: AnyValue , Key } ;
216- use opentelemetry_sdk:: export:: logs:: { LogBatch , LogExporter } ;
236+ use opentelemetry_sdk:: logs:: InMemoryLogExporter ;
237+ use opentelemetry_sdk:: logs:: { LogBatch , LogExporter } ;
217238 use opentelemetry_sdk:: logs:: { LogRecord , LogResult , LoggerProvider } ;
218- use opentelemetry_sdk:: testing:: logs:: InMemoryLogExporter ;
219239 use opentelemetry_sdk:: trace:: { Sampler , TracerProvider } ;
220240 use tracing:: { error, warn} ;
221241 use tracing_subscriber:: prelude:: __tracing_subscriber_SubscriberExt;
@@ -495,6 +515,67 @@ mod tests {
495515 }
496516 }
497517
518+ #[ cfg( feature = "experimental_use_tracing_span_context" ) ]
519+ #[ test]
520+ fn tracing_appender_inside_tracing_crate_context ( ) {
521+ use opentelemetry_sdk:: trace:: InMemorySpanExporterBuilder ;
522+
523+ // Arrange
524+ let exporter: InMemoryLogExporter = InMemoryLogExporter :: default ( ) ;
525+ let logger_provider = LoggerProvider :: builder ( )
526+ . with_simple_exporter ( exporter. clone ( ) )
527+ . build ( ) ;
528+
529+ // setup tracing layer to compare trace/span IDs against
530+ let span_exporter = InMemorySpanExporterBuilder :: new ( ) . build ( ) ;
531+ let tracer_provider = TracerProvider :: builder ( )
532+ . with_simple_exporter ( span_exporter. clone ( ) )
533+ . build ( ) ;
534+ let tracer = tracer_provider. tracer ( "test-tracer" ) ;
535+
536+ let level_filter = tracing_subscriber:: filter:: LevelFilter :: INFO ;
537+ let log_layer =
538+ layer:: OpenTelemetryTracingBridge :: new ( & logger_provider) . with_filter ( level_filter) ;
539+
540+ let subscriber = tracing_subscriber:: registry ( )
541+ . with ( log_layer)
542+ . with ( tracing_opentelemetry:: layer ( ) . with_tracer ( tracer) ) ;
543+
544+ // Avoiding global subscriber.init() as that does not play well with unit tests.
545+ let _guard = tracing:: subscriber:: set_default ( subscriber) ;
546+
547+ // Act
548+ tracing:: info_span!( "outer-span" ) . in_scope ( || {
549+ error ! ( "first-event" ) ;
550+
551+ tracing:: info_span!( "inner-span" ) . in_scope ( || {
552+ error ! ( "second-event" ) ;
553+ } ) ;
554+ } ) ;
555+
556+ logger_provider. force_flush ( ) ;
557+
558+ let logs = exporter. get_emitted_logs ( ) . expect ( "No emitted logs" ) ;
559+ assert_eq ! ( logs. len( ) , 2 ) ;
560+
561+ let spans = span_exporter. get_finished_spans ( ) . unwrap ( ) ;
562+ assert_eq ! ( spans. len( ) , 2 ) ;
563+
564+ let trace_id = spans[ 0 ] . span_context . trace_id ( ) ;
565+ assert_eq ! ( trace_id, spans[ 1 ] . span_context. trace_id( ) ) ;
566+ let inner_span_id = spans[ 0 ] . span_context . span_id ( ) ;
567+ let outer_span_id = spans[ 1 ] . span_context . span_id ( ) ;
568+ assert_eq ! ( outer_span_id, spans[ 0 ] . parent_span_id) ;
569+
570+ let trace_ctx0 = logs[ 0 ] . record . trace_context ( ) . unwrap ( ) ;
571+ let trace_ctx1 = logs[ 1 ] . record . trace_context ( ) . unwrap ( ) ;
572+
573+ assert_eq ! ( trace_ctx0. trace_id, trace_id) ;
574+ assert_eq ! ( trace_ctx1. trace_id, trace_id) ;
575+ assert_eq ! ( trace_ctx0. span_id, outer_span_id) ;
576+ assert_eq ! ( trace_ctx1. span_id, inner_span_id) ;
577+ }
578+
498579 #[ test]
499580 fn tracing_appender_standalone_with_tracing_log ( ) {
500581 // Arrange
0 commit comments