11mod host;
22
33use std:: {
4- collections:: HashMap ,
54 sync:: { Arc , RwLock } ,
65 time:: Duration ,
76} ;
87
98use anyhow:: bail;
10- use indexmap:: IndexSet ;
9+ use indexmap:: IndexMap ;
1110use opentelemetry:: {
1211 trace:: { SpanContext , SpanId , TraceContextExt } ,
1312 Context ,
@@ -53,7 +52,6 @@ impl Factor for OtelFactor {
5352 Ok ( InstanceState {
5453 state : Arc :: new ( RwLock :: new ( State {
5554 guest_span_contexts : Default :: default ( ) ,
56- active_spans : Default :: default ( ) ,
5755 original_host_span_id : None ,
5856 } ) ) ,
5957 processor : self . processor . clone ( ) ,
@@ -63,7 +61,6 @@ impl Factor for OtelFactor {
6361
6462impl OtelFactor {
6563 pub fn new ( ) -> anyhow:: Result < Self > {
66- // TODO: Configuring the processor should move to init
6764 // This will configure the exporter based on the OTEL_EXPORTER_* environment variables.
6865 let exporter = match OtlpProtocol :: traces_protocol_from_env ( ) {
6966 OtlpProtocol :: Grpc => opentelemetry_otlp:: SpanExporter :: builder ( )
@@ -111,16 +108,13 @@ impl SelfInstanceBuilder for InstanceState {}
111108/// This data lives here rather than directly on InstanceState so that we can have multiple things
112109/// take Arc references to it.
113110pub ( crate ) struct State {
114- /// A mapping between immutable [SpanId]s and the actual [BoxedSpan] created by our tracer.
115- // TODO: Rename to not include "guest"
116- // TODO: Merge with active_spans
117- pub ( crate ) guest_span_contexts : HashMap < SpanId , SpanContext > ,
118-
119- /// A stack of [SpanIds] for all the active spans. The topmost span is the active span.
111+ /// An order-preserved mapping between immutable [SpanId]s of guest created spans and their
112+ /// corresponding [SpanContext].
120113 ///
121- /// When a span is ended it is removed from this stack (regardless of whether is the
122- /// active span) and all other spans are shifted back to retain relative order.
123- pub ( crate ) active_spans : IndexSet < SpanId > ,
114+ /// The topmost [SpanId] is the last active span. When a span is ended it is removed from this
115+ /// map (regardless of whether it is the active span) and all other spans are shifted back to
116+ /// retain relative order.
117+ pub ( crate ) guest_span_contexts : IndexMap < SpanId , SpanContext > ,
124118
125119 /// Id of the last span emitted from within the host before entering the guest.
126120 ///
@@ -129,12 +123,6 @@ pub(crate) struct State {
129123 pub ( crate ) original_host_span_id : Option < SpanId > ,
130124}
131125
132- // /// The WIT resource Span. Effectively wraps an [opentelemetry::global::BoxedSpan].
133- // pub struct GuestSpan {
134- // /// The [opentelemetry::global::BoxedSpan] we use to do the actual tracing work.
135- // pub inner: BoxedSpan,
136- // }
137-
138126/// Manages access to the OtelFactor state for the purpose of maintaining proper span
139127/// parent/child relationships when WASI Otel spans are being created.
140128pub struct OtelContext {
@@ -170,10 +158,10 @@ impl OtelContext {
170158 /// | spin_key_value.get |
171159 /// ```
172160 ///
173- /// Setting the guest spans parent as the host is trivially done. However, the more difficult
174- /// task is having the host factor spans be children of the guest span.
175- /// [`OtelContext::reparent_tracing_span`] handles this by reparenting the current span to be
176- /// a child of the last active guest span (which is tracked internally in the otel factor).
161+ /// Setting the guest spans parent as the host is enabled through current_span_context.
162+ /// However, the more difficult task is having the host factor spans be children of the guest
163+ /// span. [`OtelContext::reparent_tracing_span`] handles this by reparenting the current span to
164+ /// be a child of the last active guest span (which is tracked internally in the otel factor).
177165 ///
178166 /// Note that if the otel factor is not in your [`RuntimeFactors`] than this is effectively a
179167 /// no-op.
@@ -191,7 +179,7 @@ impl OtelContext {
191179 } ;
192180
193181 // If there are no active guest spans then there is nothing to do
194- let Some ( active_span ) = state. active_spans . last ( ) else {
182+ let Some ( ( _ , active_span_context ) ) = state. guest_span_contexts . last ( ) else {
195183 return ;
196184 } ;
197185
@@ -209,8 +197,7 @@ impl OtelContext {
209197 }
210198
211199 // Now reparent the current span to the last active guest span
212- let span_context = state. guest_span_contexts . get ( active_span) . unwrap ( ) . clone ( ) ;
213- let parent_context = Context :: new ( ) . with_remote_span_context ( span_context) ;
200+ let parent_context = Context :: new ( ) . with_remote_span_context ( active_span_context. clone ( ) ) ;
214201 tracing:: Span :: current ( ) . set_parent ( parent_context) ;
215202 }
216203}
0 commit comments