#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TraceContext {
pub trace_id: String,
pub span_id: String,
pub trace_flags: u8,
}
#[derive(Clone, Debug)]
pub enum OtelAttributeValue {
String(String),
Int(i64),
Bool(bool),
}
#[derive(Clone, Debug)]
pub struct OtelAttribute {
pub key: &'static str,
pub value: OtelAttributeValue,
}
impl OtelAttribute {
pub fn string(key: &'static str, value: impl Into<String>) -> Self {
Self {
key,
value: OtelAttributeValue::String(value.into()),
}
}
pub fn int(key: &'static str, value: i64) -> Self {
Self {
key,
value: OtelAttributeValue::Int(value),
}
}
pub fn bool(key: &'static str, value: bool) -> Self {
Self {
key,
value: OtelAttributeValue::Bool(value),
}
}
}
pub struct SpanGuard {
inner: Option<Box<dyn Send + Sync>>,
}
impl SpanGuard {
pub fn noop() -> Self {
Self { inner: None }
}
pub(crate) fn new(inner: Box<dyn Send + Sync>) -> Self {
Self {
inner: Some(inner),
}
}
}
impl Drop for SpanGuard {
fn drop(&mut self) {
let _ = self.inner.take();
}
}
pub trait RuntimeTracing: Send + Sync {
fn start_span(&self, name: &'static str, attributes: &[OtelAttribute]) -> SpanGuard;
fn start_span_with_trace_context(
&self,
name: &'static str,
attributes: &[OtelAttribute],
parent: Option<&TraceContext>,
) -> SpanGuard;
fn active_trace_context(&self) -> Option<TraceContext>;
}
pub fn in_span<F, R>(
tracing: &dyn RuntimeTracing,
name: &'static str,
attributes: &[OtelAttribute],
f: F,
) -> R
where
F: FnOnce() -> R,
{
let _guard = tracing.start_span(name, attributes);
f()
}