Skip to content

Commit b19158a

Browse files
committed
Type conversions and some more impls for observe host
Signed-off-by: Caleb Schoepp <caleb.schoepp@fermyon.com>
1 parent 0a7b128 commit b19158a

File tree

5 files changed

+100
-19
lines changed

5 files changed

+100
-19
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/factor-observe/src/host.rs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::time::Duration;
22
use std::time::SystemTime;
33
use std::time::UNIX_EPOCH;
44

5+
use anyhow::anyhow;
56
use anyhow::Result;
67
use opentelemetry::global::ObjectSafeSpan;
78
use opentelemetry::trace::TraceContextExt;
@@ -68,17 +69,20 @@ impl traces::HostSpan for InstanceState {
6869

6970
async fn span_context(
7071
&mut self,
71-
_resource: Resource<traces::Span>,
72+
resource: Resource<traces::Span>,
7273
) -> Result<traces::SpanContext> {
73-
todo!()
74+
if let Some(guest_span) = self.state.read().unwrap().guest_spans.get(resource.rep()) {
75+
Ok(guest_span.inner.span_context().clone().into())
76+
} else {
77+
Err(anyhow!("BUG: cannot find resource in table"))
78+
}
7479
}
7580

7681
async fn is_recording(&mut self, resource: Resource<traces::Span>) -> Result<bool> {
7782
if let Some(guest_span) = self.state.read().unwrap().guest_spans.get(resource.rep()) {
7883
Ok(guest_span.inner.is_recording())
7984
} else {
80-
tracing::debug!("can't find guest span to read");
81-
Err(anyhow::anyhow!("can't find guest span to read"))
85+
Err(anyhow!("BUG: cannot find resource in table"))
8286
}
8387
}
8488

@@ -97,10 +101,10 @@ impl traces::HostSpan for InstanceState {
97101
for attribute in attributes {
98102
guest_span.inner.set_attribute(attribute.into());
99103
}
104+
Ok(())
100105
} else {
101-
tracing::debug!("can't find guest span to set attributes on")
106+
Err(anyhow!("BUG: cannot find resource in table"))
102107
}
103-
Ok(())
104108
}
105109

106110
async fn add_event(
@@ -126,26 +130,37 @@ impl traces::HostSpan for InstanceState {
126130
};
127131

128132
let attributes = if let Some(attributes) = attributes {
129-
attributes.into_iter().map(|a| a.into()).collect()
133+
attributes.into_iter().map(Into::into).collect()
130134
} else {
131135
vec![]
132136
};
133137

134138
guest_span
135139
.inner
136140
.add_event_with_timestamp(name.into(), timestamp, attributes);
141+
142+
Ok(())
137143
} else {
138-
tracing::debug!("can't find guest span to add events too")
144+
Err(anyhow!("BUG: cannot find resource in table"))
139145
}
140-
Ok(())
141146
}
142147

143148
async fn add_link(
144149
&mut self,
145-
_resource: Resource<traces::Span>,
150+
resource: Resource<traces::Span>,
146151
_link: traces::Link,
147152
) -> Result<()> {
148-
todo!()
153+
if let Some(_guest_span) = self
154+
.state
155+
.write()
156+
.unwrap()
157+
.guest_spans
158+
.get_mut(resource.rep())
159+
{
160+
todo!("update otel versions -> guest_span.inner.add_link(link.into());");
161+
} else {
162+
Err(anyhow!("BUG: cannot find resource in table"))
163+
}
149164
}
150165

151166
async fn set_status(
@@ -165,10 +180,10 @@ impl traces::HostSpan for InstanceState {
165180
.get_mut(resource.rep())
166181
{
167182
guest_span.inner.update_name(name.into());
183+
Ok(())
168184
} else {
169-
tracing::debug!("can't find guest span to set name on")
185+
Err(anyhow!("BUG: cannot find resource in table"))
170186
}
171-
Ok(())
172187
}
173188

174189
async fn end(
@@ -183,11 +198,11 @@ impl traces::HostSpan for InstanceState {
183198
.guest_spans
184199
.get_mut(resource.rep())
185200
{
186-
guest_span.inner.end()
201+
guest_span.inner.end();
202+
Ok(())
187203
} else {
188-
tracing::debug!("can't find guest span to end")
204+
Err(anyhow!("BUG: cannot find resource in table"))
189205
}
190-
Ok(())
191206
}
192207

193208
fn drop(&mut self, _resource: Resource<traces::Span>) -> Result<()> {
@@ -198,3 +213,5 @@ impl traces::HostSpan for InstanceState {
198213
}
199214

200215
// TODO(Caleb): Improve debug tracing in failure cases
216+
// TODO(Caleb): Move the tests from integration.rs to here
217+
// TODO(Caleb): Write tests somewhere for all the finicky type conversion stuff

crates/world/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ authors = { workspace = true }
55
edition = { workspace = true }
66

77
[dependencies]
8+
anyhow = { workspace = true }
89
async-trait = "0.1"
9-
wasmtime = { workspace = true }
1010
opentelemetry = { version = "0.22.0", features = [ "metrics", "trace"] }
11+
wasmtime = { workspace = true }

crates/world/src/conversions.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,66 @@ mod observe {
249249
opentelemetry::KeyValue::new(kv.key, kv.value)
250250
}
251251
}
252+
253+
impl From<traces::TraceFlags> for opentelemetry::trace::TraceFlags {
254+
fn from(flags: traces::TraceFlags) -> Self {
255+
Self::new(flags.as_array()[0] as u8)
256+
}
257+
}
258+
259+
impl TryFrom<traces::SpanContext> for opentelemetry::trace::SpanContext {
260+
type Error = wasmtime::Error;
261+
262+
fn try_from(sc: traces::SpanContext) -> anyhow::Result<Self> {
263+
// TODO: Endianess
264+
let trace_id: [u8; 16] = {
265+
let mut whole: [u8; 16] = [0; 16];
266+
let (one, two) = whole.split_at_mut(8);
267+
one.copy_from_slice(&sc.trace_id.0.to_le_bytes());
268+
two.copy_from_slice(&sc.trace_id.1.to_le_bytes());
269+
whole
270+
};
271+
Ok(Self::new(
272+
opentelemetry::trace::TraceId::from_bytes(trace_id),
273+
opentelemetry::trace::SpanId::from_bytes(sc.span_id.to_le_bytes()),
274+
sc.trace_flags.into(),
275+
sc.is_remote,
276+
opentelemetry::trace::TraceState::from_key_value(sc.trace_state)?,
277+
))
278+
}
279+
}
280+
281+
impl From<opentelemetry::trace::SpanContext> for traces::SpanContext {
282+
fn from(sc: opentelemetry::trace::SpanContext) -> Self {
283+
Self {
284+
trace_id: {
285+
let whole = u128::from_le_bytes(sc.trace_id().to_bytes());
286+
((whole >> 64) as u64, whole as u64)
287+
},
288+
span_id: u64::from_le_bytes(sc.span_id().to_bytes()),
289+
trace_flags: traces::TraceFlags::all(), // TODO(Caleb): This is broken
290+
is_remote: sc.is_remote(),
291+
trace_state: sc
292+
.trace_state()
293+
.header()
294+
.split(",")
295+
.map(|s| {
296+
let (key, value) = s.split_once('=').unwrap();
297+
(key.to_string(), value.to_string())
298+
})
299+
.collect(),
300+
}
301+
}
302+
}
303+
304+
impl TryFrom<traces::Link> for opentelemetry::trace::Link {
305+
type Error = wasmtime::Error;
306+
307+
fn try_from(link: traces::Link) -> anyhow::Result<Self> {
308+
Ok(Self::new(
309+
link.span_context.try_into()?,
310+
link.attributes.into_iter().map(Into::into).collect(),
311+
))
312+
}
313+
}
252314
}

wit/deps/observe/traces.wit

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ interface traces {
135135
/// Whether this `span-context` was propagated from a remote parent.
136136
is-remote: bool,
137137
/// The `trace-state` for this `span-context`.
138-
trace-state: string,
138+
trace-state: trace-state,
139139
}
140140

141141
/// The trace that this `span-context` belongs to.
@@ -151,5 +151,5 @@ interface traces {
151151
}
152152

153153
/// Carries system-specific configuration data, represented as a list of key-value pairs. `trace-state` allows multiple tracing systems to participate in the same trace.
154-
type trace-state = option<list<tuple<string, string>>>;
154+
type trace-state = list<tuple<string, string>>;
155155
}

0 commit comments

Comments
 (0)