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