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#[macro_export]
37macro_rules! otel_trace_span {
38    (parent: $parent:expr, $name:expr, $($field:tt)*) => {
39        tracing::span!(
40            target: $crate::TRACING_TARGET,
41            parent: $parent,
42            $crate::TRACING_LEVEL,
43            $name,
44            $($field)*
45        )
46    };
47    (parent: $parent:expr, $name:expr) => {
48        $crate::otel_trace_span!(parent: $parent, $name,)
49    };
50    ($name:expr, $($field:tt)*) => {
51        tracing::span!(
52            target: $crate::TRACING_TARGET,
53            $crate::TRACING_LEVEL,
54            $name,
55            $($field)*
56        )
57    };
58    ($name:expr) => {
59        $crate::otel_trace_span!($name,)
60    };
61}
62
63#[inline]
64#[must_use]
65pub fn find_current_context() -> Context {
66    use tracing_opentelemetry::OpenTelemetrySpanExt;
67    // let context = opentelemetry::Context::current();
68    // OpenTelemetry Context is propagation inside code is done via tracing crate
69    tracing::Span::current().context()
70}
71
72/// Search the current opentelemetry trace id into the Context from the current tracing'span.
73/// This function can be used to report the trace id into the error message send back to user.
74///
75/// ```rust
76/// let trace_id = tracing_opentelemetry_instrumentation_sdk::find_current_trace_id();
77/// // json!({ "error" :  "xxxxxx", "trace_id": trace_id})
78///
79/// ```
80#[inline]
81#[must_use]
82pub fn find_current_trace_id() -> Option<String> {
83    find_trace_id(&find_current_context())
84}
85
86#[inline]
87#[must_use]
88pub fn find_context_from_tracing(span: &tracing::Span) -> Context {
89    use tracing_opentelemetry::OpenTelemetrySpanExt;
90    // let context = opentelemetry::Context::current();
91    // OpenTelemetry Context is propagation inside code is done via tracing crate
92    span.context()
93}
94
95#[inline]
96#[must_use]
97pub fn find_trace_id_from_tracing(span: &tracing::Span) -> Option<String> {
98    use tracing_opentelemetry::OpenTelemetrySpanExt;
99    // let context = opentelemetry::Context::current();
100    // OpenTelemetry Context is propagation inside code is done via tracing crate
101    find_trace_id(&span.context())
102}
103
104#[inline]
105#[must_use]
106pub fn find_trace_id(context: &Context) -> Option<String> {
107    use opentelemetry::trace::TraceContextExt;
108
109    let span = context.span();
110    let span_context = span.span_context();
111    span_context
112        .is_valid()
113        .then(|| span_context.trace_id().to_string())
114
115    // #[cfg(not(any(
116    //     feature = "opentelemetry_0_17",
117    //     feature = "opentelemetry_0_18",
118    //     feature = "opentelemetry_0_19"
119    // )))]
120    // let trace_id = span.context().span().span_context().trace_id().to_hex();
121
122    // #[cfg(any(
123    //     feature = "opentelemetry_0_17",
124    //     feature = "opentelemetry_0_18",
125    //     feature = "opentelemetry_0_19"
126    // ))]
127    // let trace_id = {
128    //     let id = span.context().span().span_context().trace_id();
129    //     format!("{:032x}", id)
130    // };
131}
132
133#[inline]
134#[must_use]
135pub fn find_span_id(context: &Context) -> Option<String> {
136    use opentelemetry::trace::TraceContextExt;
137
138    let span = context.span();
139    let span_context = span.span_context();
140    span_context
141        .is_valid()
142        .then(|| span_context.span_id().to_string())
143}
144
145// pub(crate) fn set_otel_parent(parent_context: Context, span: &tracing::Span) {
146//     use opentelemetry::trace::TraceContextExt as _;
147//     use tracing_opentelemetry::OpenTelemetrySpanExt as _;
148
149//     // let parent_context = opentelemetry::global::get_text_map_propagator(|propagator| {
150//     //     propagator.extract(&RequestHeaderCarrier::new(req.headers()))
151//     // });
152//     span.set_parent(parent_context);
153//     // If we have a remote parent span, this will be the parent's trace identifier.
154//     // If not, it will be the newly generated trace identifier with this request as root span.
155
156//     if let Some(trace_id) = find_trace_id_from_tracing(&span) {
157//         span.record("trace_id", trace_id);
158//     }
159// }
160
161pub type BoxError = Box<dyn std::error::Error + Send + Sync>;