Skip to content

Commit fbd1fd4

Browse files
committed
A rough first implementation of getting tests passing with the opentelemetry based backend
Signed-off-by: Caleb Schoepp <caleb.schoepp@fermyon.com>
1 parent d34a601 commit fbd1fd4

File tree

8 files changed

+220
-198
lines changed

8 files changed

+220
-198
lines changed

crates/factor-observe/src/future.rs

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,75 +6,75 @@ use std::{
66

77
use crate::State;
88

9-
pin_project! {
10-
struct Instrumented<F> {
11-
#[pin]
12-
inner: F,
13-
observe_context: ObserveContext,
14-
}
9+
// pin_project! {
10+
// struct Instrumented<F> {
11+
// #[pin]
12+
// inner: F,
13+
// observe_context: ObserveContext,
14+
// }
1515

16-
impl<F> PinnedDrop for Instrumented<F> {
17-
fn drop(this: Pin<&mut Self>) {
18-
this.project().observe_context.drop_all();
19-
}
20-
}
21-
}
16+
// impl<F> PinnedDrop for Instrumented<F> {
17+
// fn drop(this: Pin<&mut Self>) {
18+
// this.project().observe_context.drop_all();
19+
// }
20+
// }
21+
// }
2222

23-
pub trait FutureExt: Future + Sized {
24-
/// Manage WASI Observe guest spans.
25-
fn manage_wasi_observe_spans(
26-
self,
27-
observe_context: ObserveContext,
28-
) -> impl Future<Output = Self::Output>;
29-
}
23+
// pub trait FutureExt: Future + Sized {
24+
// /// Manage WASI Observe guest spans.
25+
// fn manage_wasi_observe_spans(
26+
// self,
27+
// observe_context: ObserveContext,
28+
// ) -> impl Future<Output = Self::Output>;
29+
// }
3030

31-
impl<F: Future> FutureExt for F {
32-
fn manage_wasi_observe_spans(
33-
self,
34-
observe_context: ObserveContext,
35-
) -> impl Future<Output = Self::Output> {
36-
Instrumented {
37-
inner: self,
38-
observe_context,
39-
}
40-
}
41-
}
31+
// impl<F: Future> FutureExt for F {
32+
// fn manage_wasi_observe_spans(
33+
// self,
34+
// observe_context: ObserveContext,
35+
// ) -> impl Future<Output = Self::Output> {
36+
// Instrumented {
37+
// inner: self,
38+
// observe_context,
39+
// }
40+
// }
41+
// }
4242

43-
impl<F: Future> Future for Instrumented<F> {
44-
type Output = F::Output;
43+
// impl<F: Future> Future for Instrumented<F> {
44+
// type Output = F::Output;
4545

46-
/// Maintains the invariant that all active spans are entered before polling the inner future
47-
/// and exited otherwise. If we don't do this then the timing (among many other things) of the
48-
/// spans becomes wildly incorrect.
49-
fn poll(
50-
self: std::pin::Pin<&mut Self>,
51-
cx: &mut std::task::Context<'_>,
52-
) -> std::task::Poll<Self::Output> {
53-
let this = self.project();
46+
// /// Maintains the invariant that all active spans are entered before polling the inner future
47+
// /// and exited otherwise. If we don't do this then the timing (among many other things) of the
48+
// /// spans becomes wildly incorrect.
49+
// fn poll(
50+
// self: std::pin::Pin<&mut Self>,
51+
// cx: &mut std::task::Context<'_>,
52+
// ) -> std::task::Poll<Self::Output> {
53+
// let this = self.project();
5454

55-
// Enter the active spans before entering the inner poll
56-
{
57-
this.observe_context.state.write().unwrap().enter_all();
58-
}
55+
// // Enter the active spans before entering the inner poll
56+
// {
57+
// this.observe_context.state.write().unwrap().enter_all();
58+
// }
5959

60-
let ret = this.inner.poll(cx);
60+
// let ret = this.inner.poll(cx);
6161

62-
// Exit the active spans after exiting the inner poll
63-
{
64-
this.observe_context.state.write().unwrap().exit_all();
65-
}
62+
// // Exit the active spans after exiting the inner poll
63+
// {
64+
// this.observe_context.state.write().unwrap().exit_all();
65+
// }
6666

67-
ret
68-
}
69-
}
67+
// ret
68+
// }
69+
// }
7070

7171
/// The context necessary for the observe host component to function.
7272
pub struct ObserveContext {
7373
pub(crate) state: Arc<RwLock<State>>,
7474
}
7575

76-
impl ObserveContext {
77-
fn drop_all(&self) {
78-
self.state.write().unwrap().close_from_back_to(0);
79-
}
80-
}
76+
// impl ObserveContext {
77+
// fn drop_all(&self) {
78+
// self.state.write().unwrap().close_from_back_to(0);
79+
// }
80+
// }

crates/factor-observe/src/host.rs

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
use anyhow::Result;
2+
use opentelemetry::global::ObjectSafeSpan;
23
use opentelemetry::trace::TraceContextExt;
4+
use opentelemetry::trace::Tracer;
5+
use opentelemetry::Context;
36
use spin_core::async_trait;
47
use spin_core::wasmtime::component::Resource;
8+
use spin_telemetry::traces::WASI_OBSERVE_TRACER;
59
use spin_world::wasi::clocks0_2_0::wall_clock::Datetime;
610
use spin_world::wasi::observe::traces::{self, KeyValue, Span as WitSpan};
711
use tracing_opentelemetry::OpenTelemetrySpanExt;
@@ -13,25 +17,38 @@ impl traces::Host for InstanceState {}
1317

1418
#[async_trait]
1519
impl traces::HostSpan for InstanceState {
20+
// TODO(Caleb): Make this implicit logic make more sense (the indexmap seems wrong)
1621
async fn start(&mut self, name: String) -> Result<Resource<WitSpan>> {
17-
// Create the underlying tracing span
18-
let tracing_span = tracing::info_span!("WASI Observe guest", "otel.name" = name);
19-
let span_id = tracing_span
20-
.context()
21-
.span()
22-
.span_context()
23-
.span_id()
24-
.to_string();
22+
let mut state = self.state.write().unwrap();
2523

26-
// Wrap it in a GuestSpan for our own bookkeeping purposes and enter it
27-
let guest_span = GuestSpan {
28-
name: name.clone(),
29-
inner: tracing_span,
24+
// TODO(Caleb): Make this cleaner
25+
let parent_context = match state.active_spans.is_empty() {
26+
true => tracing::Span::current().context(),
27+
false => Context::new().with_remote_span_context(
28+
state
29+
.guest_spans
30+
.get(*state.active_spans.last().unwrap().1)
31+
.unwrap()
32+
.inner
33+
.span_context()
34+
.clone(),
35+
),
3036
};
31-
guest_span.enter();
37+
38+
// Create the underlying opentelemetry span
39+
let otel_span = WASI_OBSERVE_TRACER
40+
.lock()
41+
.unwrap()
42+
.clone()
43+
.unwrap()
44+
.start_with_context(name, &parent_context);
45+
46+
let span_id = otel_span.span_context().span_id().to_string();
47+
48+
// Wrap it in a GuestSpan for our own bookkeeping purposes
49+
let guest_span = GuestSpan { inner: otel_span };
3250

3351
// Put the GuestSpan in our resource table and push it to our stack of active spans
34-
let mut state = self.state.write().unwrap();
3552
let resource_id = state.guest_spans.push(guest_span).unwrap();
3653
state.active_spans.insert(span_id, resource_id);
3754

@@ -45,14 +62,12 @@ impl traces::HostSpan for InstanceState {
4562
) -> Result<()> {
4663
if let Some(guest_span) = self
4764
.state
48-
.try_write()
65+
.write()
4966
.unwrap()
5067
.guest_spans
5168
.get_mut(resource.rep())
5269
{
53-
guest_span
54-
.inner
55-
.set_attribute(attribute.key, attribute.value);
70+
guest_span.inner.set_attribute(attribute.into())
5671
} else {
5772
tracing::debug!("can't find guest span to set attribute on")
5873
}
@@ -72,9 +87,7 @@ impl traces::HostSpan for InstanceState {
7287
.get_mut(resource.rep())
7388
{
7489
for attribute in attributes {
75-
guest_span
76-
.inner
77-
.set_attribute(attribute.key, attribute.value);
90+
guest_span.inner.set_attribute(attribute.into());
7891
}
7992
} else {
8093
tracing::debug!("can't find guest span to set attributes on")
@@ -94,12 +107,24 @@ impl traces::HostSpan for InstanceState {
94107
}
95108

96109
async fn end(&mut self, resource: Resource<WitSpan>) -> Result<()> {
97-
self.safely_close(resource.rep(), false);
110+
if let Some(guest_span) = self
111+
.state
112+
.write()
113+
.unwrap()
114+
.guest_spans
115+
.get_mut(resource.rep())
116+
{
117+
guest_span.inner.end()
118+
} else {
119+
tracing::debug!("can't find guest span to end")
120+
}
98121
Ok(())
99122
}
100123

101-
fn drop(&mut self, resource: Resource<WitSpan>) -> Result<()> {
102-
self.safely_close(resource.rep(), true);
124+
fn drop(&mut self, _resource: Resource<WitSpan>) -> Result<()> {
125+
// TODO(Caleb): What do we want the dropping behavior to be?
103126
Ok(())
104127
}
105128
}
129+
130+
// TODO(Caleb): Improve debug tracing in failure cases

0 commit comments

Comments
 (0)