1
1
mod host;
2
2
3
3
use std:: {
4
- collections:: HashMap ,
5
4
sync:: { Arc , RwLock } ,
6
5
time:: Duration ,
7
6
} ;
8
7
9
8
use anyhow:: bail;
10
- use indexmap:: IndexSet ;
9
+ use indexmap:: IndexMap ;
11
10
use opentelemetry:: {
12
11
trace:: { SpanContext , SpanId , TraceContextExt } ,
13
12
Context ,
@@ -53,7 +52,6 @@ impl Factor for OtelFactor {
53
52
Ok ( InstanceState {
54
53
state : Arc :: new ( RwLock :: new ( State {
55
54
guest_span_contexts : Default :: default ( ) ,
56
- active_spans : Default :: default ( ) ,
57
55
original_host_span_id : None ,
58
56
} ) ) ,
59
57
processor : self . processor . clone ( ) ,
@@ -63,7 +61,6 @@ impl Factor for OtelFactor {
63
61
64
62
impl OtelFactor {
65
63
pub fn new ( ) -> anyhow:: Result < Self > {
66
- // TODO: Configuring the processor should move to init
67
64
// This will configure the exporter based on the OTEL_EXPORTER_* environment variables.
68
65
let exporter = match OtlpProtocol :: traces_protocol_from_env ( ) {
69
66
OtlpProtocol :: Grpc => opentelemetry_otlp:: SpanExporter :: builder ( )
@@ -111,16 +108,13 @@ impl SelfInstanceBuilder for InstanceState {}
111
108
/// This data lives here rather than directly on InstanceState so that we can have multiple things
112
109
/// take Arc references to it.
113
110
pub ( 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].
120
113
///
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 > ,
124
118
125
119
/// Id of the last span emitted from within the host before entering the guest.
126
120
///
@@ -129,12 +123,6 @@ pub(crate) struct State {
129
123
pub ( crate ) original_host_span_id : Option < SpanId > ,
130
124
}
131
125
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
-
138
126
/// Manages access to the OtelFactor state for the purpose of maintaining proper span
139
127
/// parent/child relationships when WASI Otel spans are being created.
140
128
pub struct OtelContext {
@@ -170,10 +158,10 @@ impl OtelContext {
170
158
/// | spin_key_value.get |
171
159
/// ```
172
160
///
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).
177
165
///
178
166
/// Note that if the otel factor is not in your [`RuntimeFactors`] than this is effectively a
179
167
/// no-op.
@@ -191,7 +179,7 @@ impl OtelContext {
191
179
} ;
192
180
193
181
// 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 {
195
183
return ;
196
184
} ;
197
185
@@ -209,8 +197,7 @@ impl OtelContext {
209
197
}
210
198
211
199
// 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 ( ) ) ;
214
201
tracing:: Span :: current ( ) . set_parent ( parent_context) ;
215
202
}
216
203
}
0 commit comments