tracing_opentelemetry_instrumentation_sdk/
lib.rs

1//#![warn(missing_docs)]
2#![forbid(unsafe_code)]
3#![warn(clippy::perf)]
4#![warn(clippy::pedantic)]
5#![allow(clippy::module_name_repetitions)]
6#![doc = include_str!("../README.md")]
7
8#[cfg(feature = "http")]
9pub mod http;
10mod span_type;
11
12use opentelemetry::Context;
13
14/// tracing's target used by instrumentation library to create span
15pub const TRACING_TARGET: &str = "otel::tracing";
16
17#[cfg(not(feature = "tracing_level_info"))]
18pub const TRACING_LEVEL: tracing::Level = tracing::Level::TRACE;
19
20#[cfg(feature = "tracing_level_info")]
21pub const TRACING_LEVEL: tracing::Level = tracing::Level::INFO;
22
23// const SPAN_NAME_FIELD: &str = "otel.name";
24// const SPAN_KIND_FIELD: &str = "otel.kind";
25// const SPAN_STATUS_CODE_FIELD: &str = "otel.status_code";
26// const SPAN_STATUS_MESSAGE_FIELD: &str = "otel.status_message";
27
28// const FIELD_EXCEPTION_MESSAGE: &str = "exception.message";
29// const FIELD_EXCEPTION_STACKTRACE: &str = "exception.stacktrace";
30// const HTTP_TARGET: &str = opentelemetry_semantic_conventions::trace::HTTP_TARGET.as_str();
31
32/// Constructs a span for the target `TRACING_TARGET` with the level `TRACING_LEVEL`.
33///
34/// [Fields] and [attributes] are set using the same syntax as the [`tracing::span!`]
35/// macro.
36//TODO find a way to use opentelemetry_semantic_conventions::attribute::* as part of the field
37#[macro_export]
38macro_rules! otel_trace_span {
39    (parent: $parent:expr, $name:expr, $($field:tt)*) => {
40        tracing::span!(
41            target: $crate::TRACING_TARGET,
42            parent: $parent,
43            $crate::TRACING_LEVEL,
44            $name,
45            $($field)*
46        )
47    };
48    (parent: $parent:expr, $name:expr) => {
49        $crate::otel_trace_span!(parent: $parent, $name,)
50    };
51    ($name:expr, $($field:tt)*) => {
52        tracing::span!(
53            target: $crate::TRACING_TARGET,
54            $crate::TRACING_LEVEL,
55            $name,
56            $($field)*
57        )
58    };
59    ($name:expr) => {
60        $crate::otel_trace_span!($name,)
61    };
62}
63
64#[inline]
65#[must_use]
66pub fn find_current_context() -> Context {
67    use tracing_opentelemetry::OpenTelemetrySpanExt;
68    // let context = opentelemetry::Context::current();
69    // OpenTelemetry Context is propagation inside code is done via tracing crate
70    tracing::Span::current().context()
71}
72
73/// Search the current opentelemetry trace id into the Context from the current tracing'span.
74/// This function can be used to report the trace id into the error message send back to user.
75///
76/// ```rust
77/// let trace_id = tracing_opentelemetry_instrumentation_sdk::find_current_trace_id();
78/// // json!({ "error" :  "xxxxxx", "trace_id": trace_id})
79///
80/// ```
81#[inline]
82#[must_use]
83pub fn find_current_trace_id() -> Option<String> {
84    find_trace_id(&find_current_context())
85}
86
87#[inline]
88#[must_use]
89pub fn find_context_from_tracing(span: &tracing::Span) -> Context {
90    use tracing_opentelemetry::OpenTelemetrySpanExt;
91    // let context = opentelemetry::Context::current();
92    // OpenTelemetry Context is propagation inside code is done via tracing crate
93    span.context()
94}
95
96#[inline]
97#[must_use]
98pub fn find_trace_id_from_tracing(span: &tracing::Span) -> Option<String> {
99    use tracing_opentelemetry::OpenTelemetrySpanExt;
100    // let context = opentelemetry::Context::current();
101    // OpenTelemetry Context is propagation inside code is done via tracing crate
102    find_trace_id(&span.context())
103}
104
105#[inline]
106#[must_use]
107pub fn find_trace_id(context: &Context) -> Option<String> {
108    use opentelemetry::trace::TraceContextExt;
109
110    let span = context.span();
111    let span_context = span.span_context();
112    span_context
113        .is_valid()
114        .then(|| span_context.trace_id().to_string())
115
116    // #[cfg(not(any(
117    //     feature = "opentelemetry_0_17",
118    //     feature = "opentelemetry_0_18",
119    //     feature = "opentelemetry_0_19"
120    // )))]
121    // let trace_id = span.context().span().span_context().trace_id().to_hex();
122
123    // #[cfg(any(
124    //     feature = "opentelemetry_0_17",
125    //     feature = "opentelemetry_0_18",
126    //     feature = "opentelemetry_0_19"
127    // ))]
128    // let trace_id = {
129    //     let id = span.context().span().span_context().trace_id();
130    //     format!("{:032x}", id)
131    // };
132}
133
134#[inline]
135#[must_use]
136pub fn find_span_id(context: &Context) -> Option<String> {
137    use opentelemetry::trace::TraceContextExt;
138
139    let span = context.span();
140    let span_context = span.span_context();
141    span_context
142        .is_valid()
143        .then(|| span_context.span_id().to_string())
144}
145
146// pub(crate) fn set_otel_parent(parent_context: Context, span: &tracing::Span) {
147//     use opentelemetry::trace::TraceContextExt as _;
148//     use tracing_opentelemetry::OpenTelemetrySpanExt as _;
149
150//     // let parent_context = opentelemetry::global::get_text_map_propagator(|propagator| {
151//     //     propagator.extract(&RequestHeaderCarrier::new(req.headers()))
152//     // });
153//     span.set_parent(parent_context);
154//     // If we have a remote parent span, this will be the parent's trace identifier.
155//     // If not, it will be the newly generated trace identifier with this request as root span.
156
157//     if let Some(trace_id) = find_trace_id_from_tracing(&span) {
158//         span.record("trace_id", trace_id);
159//     }
160// }
161
162pub type BoxError = Box<dyn std::error::Error + Send + Sync>;