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>;