Skip to content

Commit e07cc03

Browse files
authored
Impl default tracer methods and update docs (#740)
Added `Tracer::start_with_context` and `Tracer::span_builder` sensible default implementations and updated docs.
1 parent 354c83f commit e07cc03

File tree

19 files changed

+393
-388
lines changed

19 files changed

+393
-388
lines changed

opentelemetry-api/src/global/trace.rs

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -240,30 +240,6 @@ impl trace::Tracer for BoxedTracer {
240240
/// which is not possible if it takes generic type parameters.
241241
type Span = BoxedSpan;
242242

243-
/// Starts a new `Span`.
244-
///
245-
/// Each span has zero or one parent spans and zero or more child spans, which
246-
/// represent causally related operations. A tree of related spans comprises a
247-
/// trace. A span is said to be a _root span_ if it does not have a parent. Each
248-
/// trace includes a single root span, which is the shared ancestor of all other
249-
/// spans in the trace.
250-
fn start_with_context<T>(&self, name: T, parent_cx: &Context) -> Self::Span
251-
where
252-
T: Into<Cow<'static, str>>,
253-
{
254-
BoxedSpan(self.0.start_with_context_boxed(name.into(), parent_cx))
255-
}
256-
257-
/// Creates a span builder
258-
///
259-
/// An ergonomic way for attributes to be configured before the `Span` is started.
260-
fn span_builder<T>(&self, name: T) -> trace::SpanBuilder
261-
where
262-
T: Into<Cow<'static, str>>,
263-
{
264-
trace::SpanBuilder::from_name(name)
265-
}
266-
267243
/// Create a span from a `SpanBuilder`
268244
fn build_with_context(&self, builder: trace::SpanBuilder, parent_cx: &Context) -> Self::Span {
269245
BoxedSpan(self.0.build_with_context_boxed(builder, parent_cx))
@@ -275,14 +251,6 @@ impl trace::Tracer for BoxedTracer {
275251
///
276252
/// [`Tracer`]: crate::trace::Tracer
277253
pub trait ObjectSafeTracer {
278-
/// Returns a trait object so the underlying implementation can be swapped
279-
/// out at runtime.
280-
fn start_with_context_boxed(
281-
&self,
282-
name: Cow<'static, str>,
283-
parent_cx: &Context,
284-
) -> Box<dyn ObjectSafeSpan + Send + Sync>;
285-
286254
/// Returns a trait object so the underlying implementation can be swapped
287255
/// out at runtime.
288256
fn build_with_context_boxed(
@@ -297,16 +265,6 @@ where
297265
S: trace::Span + Send + Sync + 'static,
298266
T: trace::Tracer<Span = S>,
299267
{
300-
/// Returns a trait object so the underlying implementation can be swapped
301-
/// out at runtime.
302-
fn start_with_context_boxed(
303-
&self,
304-
name: Cow<'static, str>,
305-
parent_cx: &Context,
306-
) -> Box<dyn ObjectSafeSpan + Send + Sync> {
307-
Box::new(self.start_with_context(name, parent_cx))
308-
}
309-
310268
/// Returns a trait object so the underlying implementation can be swapped
311269
/// out at runtime.
312270
fn build_with_context_boxed(

opentelemetry-api/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@
3131
unused
3232
)]
3333
#![allow(clippy::needless_doctest_main)]
34-
#![cfg_attr(docsrs, feature(doc_cfg), deny(rustdoc::broken_intra_doc_links))]
34+
#![cfg_attr(
35+
docsrs,
36+
feature(doc_cfg, doc_auto_cfg),
37+
deny(rustdoc::broken_intra_doc_links)
38+
)]
3539
#![doc(
3640
html_logo_url = "https://raw.githubusercontent.com/open-telemetry/opentelemetry-rust/main/assets/logo.svg"
3741
)]

opentelemetry-api/src/trace/context.rs

Lines changed: 108 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,28 +45,42 @@ impl SpanRef<'_> {
4545
}
4646

4747
impl SpanRef<'_> {
48-
/// An API to record events in the context of a given `Span`.
48+
/// Record an event in the context this span.
49+
///
50+
/// Note that the OpenTelemetry project documents certain "[standard
51+
/// attributes]" that have prescribed semantic meanings and are available via
52+
/// the [opentelemetry_semantic_conventions] crate.
53+
///
54+
/// [standard attributes]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/trace/semantic_conventions/README.md
55+
/// [opentelemetry_semantic_conventions]: https://docs.rs/opentelemetry-semantic-conventions
4956
pub fn add_event<T>(&self, name: T, attributes: Vec<KeyValue>)
5057
where
5158
T: Into<Cow<'static, str>>,
5259
{
5360
self.with_inner_mut(|inner| inner.add_event(name, attributes))
5461
}
5562

56-
/// Convenience method to record an exception/error as an `Event`
63+
/// Record an exception event
5764
pub fn record_exception(&self, err: &dyn Error) {
5865
self.with_inner_mut(|inner| inner.record_exception(err))
5966
}
6067

61-
/// Convenience method to record a exception/error as an `Event` with custom stacktrace
68+
/// Record an exception event with stacktrace
6269
pub fn record_exception_with_stacktrace<T>(&self, err: &dyn Error, stacktrace: T)
6370
where
6471
T: Into<Cow<'static, str>>,
6572
{
6673
self.with_inner_mut(|inner| inner.record_exception_with_stacktrace(err, stacktrace))
6774
}
6875

69-
/// An API to record events at a specific time in the context of a given `Span`.
76+
/// Record an event with a timestamp in the context this span.
77+
///
78+
/// Note that the OpenTelemetry project documents certain "[standard
79+
/// attributes]" that have prescribed semantic meanings and are available via
80+
/// the [opentelemetry_semantic_conventions] crate.
81+
///
82+
/// [standard attributes]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/trace/semantic_conventions/README.md
83+
/// [opentelemetry_semantic_conventions]: https://docs.rs/opentelemetry-semantic-conventions
7084
pub fn add_event_with_timestamp<T>(
7185
&self,
7286
name: T,
@@ -80,13 +94,21 @@ impl SpanRef<'_> {
8094
})
8195
}
8296

83-
/// Returns the `SpanContext` for the given `Span`.
97+
/// A reference to the [`SpanContext`] for this span.
8498
pub fn span_context(&self) -> &SpanContext {
8599
&self.0.span_context
86100
}
87101

88-
/// Returns true if this `Span` is recording information like events with the `add_event`
89-
/// operation, attributes using `set_attributes`, status with `set_status`, etc.
102+
/// Returns `true` if this span is recording information.
103+
///
104+
/// Spans will not be recording information after they have ended.
105+
///
106+
/// This flag may be `true` despite the entire trace being sampled out. This
107+
/// allows recording and processing of information about the individual
108+
/// spans without sending it to the backend. An example of this scenario may
109+
/// be recording and processing of all incoming requests for the processing
110+
/// and building of SLA/SLO latency charts while sending only a subset -
111+
/// sampled spans - to the backend.
90112
pub fn is_recording(&self) -> bool {
91113
self.0
92114
.inner
@@ -95,61 +117,125 @@ impl SpanRef<'_> {
95117
.unwrap_or(false)
96118
}
97119

98-
/// An API to set a single `Attribute` where the attribute properties are passed
99-
/// as arguments. To avoid extra allocations some implementations may offer a separate API for
100-
/// each of the possible value types.
120+
/// Set an attribute of this span.
121+
///
122+
/// Setting an attribute with the same key as an existing attribute
123+
/// generally overwrites the existing attribute's value.
124+
///
125+
/// Note that the OpenTelemetry project documents certain "[standard
126+
/// attributes]" that have prescribed semantic meanings and are available via
127+
/// the [opentelemetry_semantic_conventions] crate.
128+
///
129+
/// [standard attributes]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/trace/semantic_conventions/README.md
130+
/// [opentelemetry_semantic_conventions]: https://docs.rs/opentelemetry-semantic-conventions
101131
pub fn set_attribute(&self, attribute: crate::KeyValue) {
102132
self.with_inner_mut(move |inner| inner.set_attribute(attribute))
103133
}
104134

105-
/// Sets the status of the `Span`. If used, this will override the default `Span`
106-
/// status, which is `Unset`. `message` MUST be ignored when the status is `OK` or `Unset`
135+
/// Sets the status of this `Span`.
136+
///
137+
/// If used, this will override the default span status, which is [`StatusCode::Unset`].
138+
///
139+
/// [`StatusCode::Unset`]: super::StatusCode::Unset
107140
pub fn set_status<T>(&self, code: super::StatusCode, message: T)
108141
where
109142
T: Into<Cow<'static, str>>,
110143
{
111144
self.with_inner_mut(move |inner| inner.set_status(code, message))
112145
}
113146

114-
/// Updates the `Span`'s name. After this update, any sampling behavior based on the
115-
/// name will depend on the implementation.
147+
/// Updates the span's name.
148+
///
149+
/// After this update, any sampling behavior based on the name will depend on
150+
/// the implementation.
116151
pub fn update_name<T>(&self, new_name: T)
117152
where
118153
T: Into<Cow<'static, str>>,
119154
{
120155
self.with_inner_mut(move |inner| inner.update_name(new_name))
121156
}
122157

123-
/// Finishes the `Span`.
158+
/// Signals that the operation described by this span has now ended.
124159
pub fn end(&self) {
125160
self.end_with_timestamp(crate::time::now());
126161
}
127162

128-
/// Finishes the `Span` with given timestamp
163+
/// Signals that the operation described by this span ended at the given time.
129164
pub fn end_with_timestamp(&self, timestamp: std::time::SystemTime) {
130165
self.with_inner_mut(move |inner| inner.end_with_timestamp(timestamp))
131166
}
132167
}
133168

134-
/// Methods for storing and retrieving trace data in a context.
169+
/// Methods for storing and retrieving trace data in a [`Context`].
170+
///
171+
/// See [`Context`] for examples of setting and retrieving the current context.
135172
pub trait TraceContextExt {
136-
/// Returns a clone of the current context with the included span.
173+
/// Returns a clone of the current context with the included [`Span`].
174+
///
175+
/// # Examples
176+
///
177+
/// ```
178+
/// use opentelemetry_api::{global, trace::{TraceContextExt, Tracer}, Context};
137179
///
138-
/// This is useful for building tracers.
180+
/// let tracer = global::tracer("example");
181+
///
182+
/// // build a span
183+
/// let span = tracer.start("parent_span");
184+
///
185+
/// // create a new context from the currently active context that includes this span
186+
/// let cx = Context::current_with_span(span);
187+
///
188+
/// // create a child span by explicitly specifying the parent context
189+
/// let child = tracer.start_with_context("child_span", &cx);
190+
/// # drop(child)
191+
/// ```
139192
fn current_with_span<T: crate::trace::Span + Send + Sync + 'static>(span: T) -> Self;
140193

141194
/// Returns a clone of this context with the included span.
142195
///
143-
/// This is useful for building tracers.
196+
/// # Examples
197+
///
198+
/// ```
199+
/// use opentelemetry_api::{global, trace::{TraceContextExt, Tracer}, Context};
200+
///
201+
/// fn fn_with_passed_in_context(cx: &Context) {
202+
/// let tracer = global::tracer("example");
203+
///
204+
/// // build a span
205+
/// let span = tracer.start("parent_span");
206+
///
207+
/// // create a new context from the given context that includes the span
208+
/// let cx_with_parent = cx.with_span(span);
209+
///
210+
/// // create a child span by explicitly specifying the parent context
211+
/// let child = tracer.start_with_context("child_span", &cx_with_parent);
212+
/// # drop(child)
213+
/// }
214+
///
144215
fn with_span<T: crate::trace::Span + Send + Sync + 'static>(&self, span: T) -> Self;
145216

146217
/// Returns a reference to this context's span, or the default no-op span if
147218
/// none has been set.
219+
///
220+
/// # Examples
221+
///
222+
/// ```
223+
/// use opentelemetry_api::{trace::TraceContextExt, Context};
224+
///
225+
/// // Add an event to the currently active span
226+
/// Context::current().span().add_event("An event!", vec![]);
227+
/// ```
148228
fn span(&self) -> SpanRef<'_>;
149229

150-
/// Used to see if a span has been marked as active
230+
/// Returns whether or not an active span has been set.
231+
///
232+
/// # Examples
233+
///
234+
/// ```
235+
/// use opentelemetry_api::{trace::TraceContextExt, Context};
151236
///
152-
/// This is useful for building tracers.
237+
/// assert!(!Context::current().has_active_span());
238+
/// ```
153239
fn has_active_span(&self) -> bool;
154240

155241
/// Returns a copy of this context with the span context included.

opentelemetry-api/src/trace/mod.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
//! ## Getting Started
1313
//!
1414
//! ```
15-
//! # #[cfg(feature = "trace")]
16-
//! # {
1715
//! use opentelemetry_api::{global, trace::{Span, Tracer, TracerProvider}};
1816
//!
1917
//! fn my_library_function() {
@@ -36,7 +34,6 @@
3634
//! // End the span
3735
//! span.end();
3836
//! }
39-
//! # }
4037
//! ```
4138
//!
4239
//! ## Overview
@@ -71,8 +68,6 @@
7168
//! [`Context`]: crate::Context
7269
//!
7370
//! ```
74-
//! # #[cfg(feature = "trace")]
75-
//! # {
7671
//! use opentelemetry_api::{global, trace::{self, Span, StatusCode, Tracer, TracerProvider}};
7772
//!
7873
//! fn may_error(rand: f32) {
@@ -98,15 +93,12 @@
9893
//!
9994
//! // Drop the guard and the span will no longer be active
10095
//! drop(active)
101-
//! # }
10296
//! ```
10397
//!
10498
//! Additionally [`Tracer::with_span`] and [`Tracer::in_span`] can be used as shorthand to
10599
//! simplify managing the parent context.
106100
//!
107101
//! ```
108-
//! # #[cfg(feature = "trace")]
109-
//! # {
110102
//! use opentelemetry_api::{global, trace::Tracer};
111103
//!
112104
//! // Get a tracer
@@ -123,16 +115,13 @@
123115
//! tracer.with_span(span, |cx| {
124116
//! // spans created here will be children of `parent_span`
125117
//! });
126-
//! # }
127118
//! ```
128119
//!
129120
//! #### Async active spans
130121
//!
131122
//! Async spans can be propagated with [`TraceContextExt`] and [`FutureExt`].
132123
//!
133124
//! ```
134-
//! # #[cfg(feature = "trace")]
135-
//! # {
136125
//! use opentelemetry_api::{Context, global, trace::{FutureExt, TraceContextExt, Tracer}};
137126
//!
138127
//! async fn some_work() { }
@@ -145,7 +134,6 @@
145134
//!
146135
//! // Perform some async work with this span as the currently active parent.
147136
//! some_work().with_context(Context::current_with_span(span));
148-
//! # }
149137
//! ```
150138
151139
use futures_channel::{mpsc::TrySendError, oneshot::Canceled};

opentelemetry-api/src/trace/noop.rs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::trace::TraceResult;
77
use crate::{
88
propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator},
99
trace,
10-
trace::{SpanBuilder, TraceContextExt, TraceFlags, TraceState},
10+
trace::{TraceContextExt, TraceFlags, TraceState},
1111
Context, KeyValue,
1212
};
1313
use std::borrow::Cow;
@@ -146,24 +146,6 @@ impl NoopTracer {
146146
impl trace::Tracer for NoopTracer {
147147
type Span = NoopSpan;
148148

149-
/// Starts a new `NoopSpan` with a given context.
150-
///
151-
/// If the context contains a valid span, it's span context is propagated.
152-
fn start_with_context<T>(&self, name: T, parent_cx: &Context) -> Self::Span
153-
where
154-
T: Into<std::borrow::Cow<'static, str>>,
155-
{
156-
self.build_with_context(SpanBuilder::from_name(name), parent_cx)
157-
}
158-
159-
/// Starts a `SpanBuilder`.
160-
fn span_builder<T>(&self, name: T) -> trace::SpanBuilder
161-
where
162-
T: Into<std::borrow::Cow<'static, str>>,
163-
{
164-
trace::SpanBuilder::from_name(name)
165-
}
166-
167149
/// Builds a `NoopSpan` from a `SpanBuilder`.
168150
///
169151
/// If the span builder or the context's current span contains a valid span context, it is

0 commit comments

Comments
 (0)