use opentelemetry::Context;
use opentelemetry::KeyValue;
use opentelemetry::trace::SpanContext;
use opentelemetry::trace::TraceContextExt;
use super::layer::WithContext;
pub(crate) trait OpenTelemetrySpanExt {
fn add_link(&self, cx: SpanContext);
fn add_link_with_attributes(&self, cx: SpanContext, attributes: Vec<KeyValue>);
fn context(&self) -> Context;
}
impl OpenTelemetrySpanExt for tracing::Span {
fn add_link(&self, cx: SpanContext) {
self.add_link_with_attributes(cx, Vec::new())
}
fn add_link_with_attributes(&self, cx: SpanContext, attributes: Vec<KeyValue>) {
if cx.is_valid() {
let mut cx = Some(cx);
let mut att = Some(attributes);
self.with_subscriber(move |(id, subscriber)| {
if let Some(get_context) = subscriber.downcast_ref::<WithContext>() {
get_context.with_context(subscriber, id, move |data| {
if let Some(cx) = cx.take() {
let attr = att.take().unwrap_or_default();
data.current_cx.span().add_link(cx, attr);
}
});
}
});
}
}
fn context(&self) -> Context {
let mut cx = None;
self.with_subscriber(|(id, subscriber)| {
if let Some(get_context) = subscriber.downcast_ref::<WithContext>() {
get_context.with_context(subscriber, id, |data| {
cx = Some(data.current_cx.clone());
})
}
});
cx.unwrap_or_default()
}
}