,
{
@@ -193,7 +193,7 @@ impl GlobalTracerProvider {
/// Create a new GlobalTracerProvider instance from a struct that implements `TracerProvider`.
fn new(provider: P) -> Self
where
- S: trace::Span + Send + Sync,
+ S: trace::Span + Send + Sync + 'static,
T: trace::Tracer + Send + Sync,
P: trace::TracerProvider + Send + Sync,
{
@@ -258,7 +258,7 @@ pub fn tracer_with_version(name: &'static str, version: &'static str) -> BoxedTr
/// [`TracerProvider`]: crate::trace::TracerProvider
pub fn set_tracer_provider(new_provider: P) -> GlobalTracerProvider
where
- S: trace::Span + Send + Sync,
+ S: trace::Span + Send + Sync + 'static,
T: trace::Tracer + Send + Sync,
P: trace::TracerProvider + Send + Sync,
{
diff --git a/opentelemetry/src/sdk/propagation/composite.rs b/opentelemetry/src/sdk/propagation/composite.rs
index 9c292191ed..e4fdce6aa2 100644
--- a/opentelemetry/src/sdk/propagation/composite.rs
+++ b/opentelemetry/src/sdk/propagation/composite.rs
@@ -138,14 +138,15 @@ mod tests {
impl TextMapPropagator for TestPropagator {
fn inject_context(&self, cx: &Context, injector: &mut dyn Injector) {
- let span = cx.span().span_context();
+ let span = cx.span();
+ let span_context = span.span_context();
injector.set(
"testheader",
format!(
"{}-{}-{}",
- span.trace_id().to_u128(),
- span.span_id().to_u64(),
- span.trace_flags()
+ span_context.trace_id().to_u128(),
+ span_context.span_id().to_u64(),
+ span_context.trace_flags()
),
)
}
diff --git a/opentelemetry/src/sdk/propagation/trace_context.rs b/opentelemetry/src/sdk/propagation/trace_context.rs
index 9904638c1e..c00c75c83c 100644
--- a/opentelemetry/src/sdk/propagation/trace_context.rs
+++ b/opentelemetry/src/sdk/propagation/trace_context.rs
@@ -117,7 +117,8 @@ impl TextMapPropagator for TraceContextPropagator {
/// Properly encodes the values of the `SpanContext` and injects them
/// into the `Injector`.
fn inject_context(&self, cx: &Context, injector: &mut dyn Injector) {
- let span_context = cx.span().span_context();
+ let span = cx.span();
+ let span_context = span.span_context();
if span_context.is_valid() {
let header_value = format!(
"{:02x}-{:032x}-{:016x}-{:02x}",
diff --git a/opentelemetry/src/sdk/trace/sampler.rs b/opentelemetry/src/sdk/trace/sampler.rs
index 5242dbf2cd..c05c79d320 100644
--- a/opentelemetry/src/sdk/trace/sampler.rs
+++ b/opentelemetry/src/sdk/trace/sampler.rs
@@ -119,7 +119,8 @@ impl ShouldSample for Sampler {
.should_sample(parent_context, trace_id, name, span_kind, attributes, links)
.decision,
|ctx| {
- let parent_span_context = ctx.span().span_context();
+ let span = ctx.span();
+ let parent_span_context = span.span_context();
if parent_span_context.is_sampled() {
SamplingDecision::RecordAndSample
} else {
diff --git a/opentelemetry/src/sdk/trace/span.rs b/opentelemetry/src/sdk/trace/span.rs
index f8eec586b1..866f1780e2 100644
--- a/opentelemetry/src/sdk/trace/span.rs
+++ b/opentelemetry/src/sdk/trace/span.rs
@@ -10,20 +10,14 @@
//! These cannot be changed after the `Span`'s end time has been set.
use crate::trace::{Event, SpanContext, SpanId, SpanKind, StatusCode};
use crate::{sdk, trace, KeyValue};
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
use std::time::SystemTime;
/// Single operation within a trace.
-#[derive(Clone, Debug)]
-pub struct Span {
- inner: Arc,
-}
-
-/// Inner data, processed and exported on end
#[derive(Debug)]
-struct SpanInner {
+pub struct Span {
span_context: SpanContext,
- data: Option>>,
+ data: Option,
tracer: sdk::trace::Tracer,
}
@@ -49,8 +43,6 @@ pub(crate) struct SpanData {
pub(crate) status_code: StatusCode,
/// Span status message
pub(crate) status_message: String,
- /// Resource contains attributes representing an entity that produced this span.
- pub(crate) resource: Arc,
}
impl Span {
@@ -60,25 +52,18 @@ impl Span {
tracer: sdk::trace::Tracer,
) -> Self {
Span {
- inner: Arc::new(SpanInner {
- span_context,
- data: data.map(|data| Mutex::new(Some(data))),
- tracer,
- }),
+ span_context,
+ data,
+ tracer,
}
}
/// Operate on a mutable reference to span data
- fn with_data(&self, f: F) -> Option
+ fn with_data(&mut self, f: F) -> Option
where
F: FnOnce(&mut SpanData) -> T,
{
- self.inner.data.as_ref().and_then(|inner| {
- inner
- .lock()
- .ok()
- .and_then(|mut span_data| span_data.as_mut().map(f))
- })
+ self.data.as_mut().map(f)
}
}
@@ -89,7 +74,7 @@ impl crate::trace::Span for Span {
/// keys"](https://github.com/open-telemetry/opentelemetry-specification/tree/v0.5.0/specification/trace/semantic_conventions/README.md)
/// which have prescribed semantic meanings.
fn add_event_with_timestamp(
- &self,
+ &mut self,
name: String,
timestamp: SystemTime,
attributes: Vec,
@@ -102,19 +87,14 @@ impl crate::trace::Span for Span {
/// Returns the `SpanContext` for the given `Span`.
fn span_context(&self) -> &SpanContext {
- &self.inner.span_context
+ &self.span_context
}
/// Returns true if this `Span` is recording information like events with the `add_event`
/// operation, attributes using `set_attributes`, status with `set_status`, etc.
/// Always returns false after span `end`.
fn is_recording(&self) -> bool {
- if let Some(data) = &self.inner.data {
- if let Ok(span_data) = data.lock() {
- return span_data.is_some();
- }
- }
- false
+ self.data.is_some()
}
/// Sets a single `Attribute` where the attribute properties are passed as arguments.
@@ -122,7 +102,7 @@ impl crate::trace::Span for Span {
/// Note that the OpenTelemetry project documents certain ["standard
/// attributes"](https://github.com/open-telemetry/opentelemetry-specification/tree/v0.5.0/specification/trace/semantic_conventions/README.md)
/// that have prescribed semantic meanings.
- fn set_attribute(&self, attribute: KeyValue) {
+ fn set_attribute(&mut self, attribute: KeyValue) {
self.with_data(|data| {
data.attributes.insert(attribute);
});
@@ -130,7 +110,7 @@ impl crate::trace::Span for Span {
/// Sets the status of the `Span`. If used, this will override the default `Span`
/// status, which is `Unset`. `message` MUST be ignored when the status is `OK` or `Unset`
- fn set_status(&self, code: StatusCode, message: String) {
+ fn set_status(&mut self, code: StatusCode, message: String) {
self.with_data(|data| {
if code == StatusCode::Error {
data.status_message = message;
@@ -140,50 +120,49 @@ impl crate::trace::Span for Span {
}
/// Updates the `Span`'s name.
- fn update_name(&self, new_name: String) {
+ fn update_name(&mut self, new_name: String) {
self.with_data(|data| {
data.name = new_name;
});
}
/// Finishes the span with given timestamp.
- fn end_with_timestamp(&self, timestamp: SystemTime) {
- self.inner.ensure_ended_and_exported(Some(timestamp));
+ fn end_with_timestamp(&mut self, timestamp: SystemTime) {
+ self.ensure_ended_and_exported(Some(timestamp));
}
}
-impl SpanInner {
- fn ensure_ended_and_exported(&self, timestamp: Option) {
- if let Some(data) = &self.data {
- if let Ok(mut span_data) = data.lock().map(|mut data| data.take()) {
- // Ensure end time is set via explicit end or implicitly on drop
- if let Some(span_data) = span_data.as_mut() {
- if let Some(timestamp) = timestamp {
- span_data.end_time = timestamp;
- } else if span_data.end_time == span_data.start_time {
- span_data.end_time = crate::time::now();
- }
- }
+impl Span {
+ fn ensure_ended_and_exported(&mut self, timestamp: Option) {
+ if let Some(mut data) = self.data.take() {
+ // Ensure end time is set via explicit end or implicitly on drop
+ if let Some(timestamp) = timestamp {
+ data.end_time = timestamp;
+ } else if data.end_time == data.start_time {
+ data.end_time = crate::time::now();
+ }
- // Notify each span processor that the span has ended
- if let Some(provider) = self.tracer.provider() {
- let mut processors = provider.span_processors().iter().peekable();
- while let Some(processor) = processors.next() {
- let span_data = if processors.peek().is_none() {
- // last loop or single processor/exporter, move data
- span_data.take()
- } else {
- // clone so each exporter gets owned data
- span_data.clone()
- };
-
- if let Some(span_data) = span_data {
- processor.on_end(build_export_data(
- span_data,
- self.span_context.clone(),
- &self.tracer,
- ));
- }
+ // Notify each span processor that the span has ended
+ if let Some(provider) = self.tracer.provider() {
+ let mut processors = provider.span_processors().iter().peekable();
+ let resource = provider.config().resource.clone();
+ let mut span_data = Some((data, resource));
+ while let Some(processor) = processors.next() {
+ let span_data = if processors.peek().is_none() {
+ // last loop or single processor/exporter, move data
+ span_data.take()
+ } else {
+ // clone so each exporter gets owned data
+ span_data.clone()
+ };
+
+ if let Some((span_data, resource)) = span_data {
+ processor.on_end(build_export_data(
+ span_data,
+ self.span_context.clone(),
+ resource,
+ &self.tracer,
+ ));
}
}
}
@@ -191,7 +170,7 @@ impl SpanInner {
}
}
-impl Drop for SpanInner {
+impl Drop for Span {
/// Report span on inner drop
fn drop(&mut self) {
self.ensure_ended_and_exported(None);
@@ -201,6 +180,7 @@ impl Drop for SpanInner {
fn build_export_data(
data: SpanData,
span_context: SpanContext,
+ resource: Arc,
tracer: &sdk::trace::Tracer,
) -> sdk::export::trace::SpanData {
sdk::export::trace::SpanData {
@@ -215,7 +195,7 @@ fn build_export_data(
links: data.links,
status_code: data.status_code,
status_message: data.status_message,
- resource: data.resource,
+ resource,
instrumentation_lib: *tracer.instrumentation_library(),
}
}
@@ -241,7 +221,6 @@ mod tests {
links: sdk::trace::EvictedQueue::new(config.max_links_per_span),
status_code: StatusCode::Unset,
status_message: "".to_string(),
- resource: config.resource.clone(),
};
(tracer, data)
}
@@ -254,20 +233,20 @@ mod tests {
#[test]
fn create_span_without_data() {
let (tracer, _) = init();
- let span = Span::new(SpanContext::empty_context(), None, tracer);
+ let mut span = Span::new(SpanContext::empty_context(), None, tracer);
span.with_data(|_data| panic!("there are data"));
}
#[test]
fn create_span_with_data_mut() {
let (tracer, data) = init();
- let span = Span::new(SpanContext::empty_context(), Some(data.clone()), tracer);
+ let mut span = Span::new(SpanContext::empty_context(), Some(data.clone()), tracer);
span.with_data(|d| assert_eq!(*d, data));
}
#[test]
fn add_event() {
- let span = create_span();
+ let mut span = create_span();
let name = "some_event".to_string();
let attributes = vec![KeyValue::new("k", "v")];
span.add_event(name.clone(), attributes.clone());
@@ -283,7 +262,7 @@ mod tests {
#[test]
fn add_event_with_timestamp() {
- let span = create_span();
+ let mut span = create_span();
let name = "some_event".to_string();
let attributes = vec![KeyValue::new("k", "v")];
let timestamp = crate::time::now();
@@ -301,7 +280,7 @@ mod tests {
#[test]
fn record_exception() {
- let span = create_span();
+ let mut span = create_span();
let err = std::io::Error::from(std::io::ErrorKind::Other);
span.record_exception(&err);
span.with_data(|data| {
@@ -319,7 +298,7 @@ mod tests {
#[test]
fn record_exception_with_stacktrace() {
- let span = create_span();
+ let mut span = create_span();
let err = std::io::Error::from(std::io::ErrorKind::Other);
let stacktrace = "stacktrace...".to_string();
span.record_exception_with_stacktrace(&err, stacktrace.clone());
@@ -341,7 +320,7 @@ mod tests {
#[test]
fn set_attribute() {
- let span = create_span();
+ let mut span = create_span();
let attributes = KeyValue::new("k", "v");
span.set_attribute(attributes.clone());
span.with_data(|data| {
@@ -356,7 +335,7 @@ mod tests {
#[test]
fn set_status() {
{
- let span = create_span();
+ let mut span = create_span();
let status = StatusCode::Ok;
let message = "OK".to_string();
span.set_status(status, message);
@@ -366,7 +345,7 @@ mod tests {
});
}
{
- let span = create_span();
+ let mut span = create_span();
let status = StatusCode::Unset;
let message = "OK".to_string();
span.set_status(status, message);
@@ -376,7 +355,7 @@ mod tests {
});
}
{
- let span = create_span();
+ let mut span = create_span();
let status = StatusCode::Error;
let message = "Error".to_string();
span.set_status(status, message);
@@ -389,7 +368,7 @@ mod tests {
#[test]
fn update_name() {
- let span = create_span();
+ let mut span = create_span();
let name = "new_name".to_string();
span.update_name(name.clone());
span.with_data(|data| {
@@ -399,13 +378,13 @@ mod tests {
#[test]
fn end() {
- let span = create_span();
+ let mut span = create_span();
span.end();
}
#[test]
fn end_with_timestamp() {
- let span = create_span();
+ let mut span = create_span();
let timestamp = crate::time::now();
span.end_with_timestamp(timestamp);
span.with_data(|data| assert_eq!(data.end_time, timestamp));
@@ -413,21 +392,14 @@ mod tests {
#[test]
fn allows_to_get_span_context_after_end() {
- let span = create_span();
+ let mut span = create_span();
span.end();
assert_eq!(span.span_context(), &SpanContext::empty_context());
}
- #[test]
- fn allows_to_get_span_context_after_clone_drop() {
- let span = create_span();
- drop(span.clone());
- assert_eq!(span.span_context(), &SpanContext::empty_context());
- }
-
#[test]
fn end_only_once() {
- let span = create_span();
+ let mut span = create_span();
let timestamp = crate::time::now();
span.end_with_timestamp(timestamp);
span.end_with_timestamp(timestamp.checked_add(Duration::from_secs(10)).unwrap());
@@ -436,7 +408,7 @@ mod tests {
#[test]
fn noop_after_end() {
- let span = create_span();
+ let mut span = create_span();
let initial = span.with_data(|data| data.clone()).unwrap();
span.end();
span.add_event("some_event".to_string(), vec![KeyValue::new("k", "v")]);
@@ -468,7 +440,7 @@ mod tests {
#[test]
fn is_recording_false_after_end() {
- let span = create_span();
+ let mut span = create_span();
span.end();
assert!(!span.is_recording());
}
diff --git a/opentelemetry/src/sdk/trace/tracer.rs b/opentelemetry/src/sdk/trace/tracer.rs
index 29d29fa4dc..f9369d5813 100644
--- a/opentelemetry/src/sdk/trace/tracer.rs
+++ b/opentelemetry/src/sdk/trace/tracer.rs
@@ -11,7 +11,7 @@ use crate::sdk::{
trace::{
provider::{TracerProvider, TracerProviderInner},
span::{Span, SpanData},
- EvictedHashMap, EvictedQueue, SamplingDecision, SamplingResult,
+ Config, EvictedHashMap, EvictedQueue, SamplingDecision, SamplingResult,
},
InstrumentationLibrary,
};
@@ -73,11 +73,9 @@ impl Tracer {
span_kind: &SpanKind,
attributes: &[KeyValue],
links: &[Link],
+ config: &Config,
) -> Option<(u8, Vec, TraceState)> {
- let provider = self.provider()?;
- let sampler = &provider.config().default_sampler;
-
- let sampling_result = sampler.should_sample(
+ let sampling_result = config.default_sampler.should_sample(
Some(parent_cx),
trace_id,
name,
@@ -192,11 +190,13 @@ impl crate::trace::Tracer for Tracer {
_ => cx,
}
};
+ let span = parent_cx.span();
let parent_span_context = if parent_cx.has_active_span() {
- Some(parent_cx.span().span_context())
+ Some(span.span_context())
} else {
None
};
+
// Build context for sampling decision
let (no_parent, trace_id, parent_span_id, remote_parent, parent_trace_flags) =
parent_span_context
@@ -235,6 +235,7 @@ impl crate::trace::Tracer for Tracer {
&span_kind,
&attribute_options,
link_options.as_deref().unwrap_or(&[]),
+ provider.config(),
)
} else {
// has parent that is local: use parent if sampled, or don't record.
@@ -270,8 +271,7 @@ impl crate::trace::Tracer for Tracer {
message_events.append_vec(&mut events);
}
let status_code = builder.status_code.unwrap_or(StatusCode::Unset);
- let status_message = builder.status_message.unwrap_or_else(String::new);
- let resource = config.resource.clone();
+ let status_message = builder.status_message.unwrap_or_default();
SpanData {
parent_span_id,
@@ -284,7 +284,6 @@ impl crate::trace::Tracer for Tracer {
links,
status_code,
status_message,
- resource,
}
});
diff --git a/opentelemetry/src/testing/trace.rs b/opentelemetry/src/testing/trace.rs
index b6f4caa83a..6f2f3ebd89 100644
--- a/opentelemetry/src/testing/trace.rs
+++ b/opentelemetry/src/testing/trace.rs
@@ -19,7 +19,7 @@ pub struct TestSpan(pub SpanContext);
impl Span for TestSpan {
fn add_event_with_timestamp(
- &self,
+ &mut self,
_name: String,
_timestamp: std::time::SystemTime,
_attributes: Vec,
@@ -31,10 +31,10 @@ impl Span for TestSpan {
fn is_recording(&self) -> bool {
false
}
- fn set_attribute(&self, _attribute: KeyValue) {}
- fn set_status(&self, _code: StatusCode, _message: String) {}
- fn update_name(&self, _new_name: String) {}
- fn end_with_timestamp(&self, _timestamp: std::time::SystemTime) {}
+ fn set_attribute(&mut self, _attribute: KeyValue) {}
+ fn set_status(&mut self, _code: StatusCode, _message: String) {}
+ fn update_name(&mut self, _new_name: String) {}
+ fn end_with_timestamp(&mut self, _timestamp: std::time::SystemTime) {}
}
pub fn new_test_export_span_data() -> SpanData {
diff --git a/opentelemetry/src/trace/context.rs b/opentelemetry/src/trace/context.rs
index 05932ca263..93bb2ade1a 100644
--- a/opentelemetry/src/trace/context.rs
+++ b/opentelemetry/src/trace/context.rs
@@ -1,10 +1,110 @@
//! Context extensions for tracing
-use crate::{Context, ContextGuard};
+use crate::{global, trace::SpanContext, Context, ContextGuard, KeyValue};
+use std::error::Error;
+use std::sync::Mutex;
+
lazy_static::lazy_static! {
- static ref NOOP_SPAN: crate::trace::NoopSpan = crate::trace::NoopSpan::new();
+ static ref NOOP_SPAN: SynchronizedSpan = SynchronizedSpan {
+ span_context: SpanContext::empty_context(),
+ inner: None,
+ };
+}
+
+/// A reference to the currently active span in this context.
+#[derive(Debug)]
+pub struct SpanRef<'a>(&'a SynchronizedSpan);
+
+#[derive(Debug)]
+struct SynchronizedSpan {
+ /// Immutable span context
+ span_context: SpanContext,
+ /// Mutable span inner that requires synchronization
+ inner: Option>>,
+}
+
+impl SpanRef<'_> {
+ fn with_inner_mut(&self, f: F) {
+ if let Some(ref inner) = self.0.inner {
+ match inner.lock() {
+ Ok(mut locked) => f(&mut *locked),
+ Err(err) => global::handle_error(err),
+ }
+ }
+ }
}
-struct Span(Box);
+impl SpanRef<'_> {
+ /// An API to record events in the context of a given `Span`.
+ pub fn add_event(&self, name: String, attributes: Vec) {
+ self.with_inner_mut(|inner| inner.add_event(name, attributes))
+ }
+
+ /// Convenience method to record an exception/error as an `Event`
+ pub fn record_exception(&self, err: &dyn Error) {
+ self.with_inner_mut(|inner| inner.record_exception(err))
+ }
+
+ /// Convenience method to record a exception/error as an `Event` with custom stacktrace
+ pub fn record_exception_with_stacktrace(&self, err: &dyn Error, stacktrace: String) {
+ self.with_inner_mut(|inner| inner.record_exception_with_stacktrace(err, stacktrace))
+ }
+
+ /// An API to record events at a specific time in the context of a given `Span`.
+ pub fn add_event_with_timestamp(
+ &self,
+ name: String,
+ timestamp: std::time::SystemTime,
+ attributes: Vec,
+ ) {
+ self.with_inner_mut(move |inner| {
+ inner.add_event_with_timestamp(name, timestamp, attributes)
+ })
+ }
+
+ /// Returns the `SpanContext` for the given `Span`.
+ pub fn span_context(&self) -> &SpanContext {
+ &self.0.span_context
+ }
+
+ /// Returns true if this `Span` is recording information like events with the `add_event`
+ /// operation, attributes using `set_attributes`, status with `set_status`, etc.
+ pub fn is_recording(&self) -> bool {
+ self.0
+ .inner
+ .as_ref()
+ .and_then(|inner| inner.lock().ok().map(|active| active.is_recording()))
+ .unwrap_or(false)
+ }
+
+ /// An API to set a single `Attribute` where the attribute properties are passed
+ /// as arguments. To avoid extra allocations some implementations may offer a separate API for
+ /// each of the possible value types.
+ pub fn set_attribute(&self, attribute: crate::KeyValue) {
+ self.with_inner_mut(move |inner| inner.set_attribute(attribute))
+ }
+
+ /// Sets the status of the `Span`. If used, this will override the default `Span`
+ /// status, which is `Unset`. `message` MUST be ignored when the status is `OK` or `Unset`
+ pub fn set_status(&self, code: super::StatusCode, message: String) {
+ self.with_inner_mut(move |inner| inner.set_status(code, message))
+ }
+
+ /// Updates the `Span`'s name. After this update, any sampling behavior based on the
+ /// name will depend on the implementation.
+ pub fn update_name(&self, new_name: String) {
+ self.with_inner_mut(move |inner| inner.update_name(new_name))
+ }
+
+ /// Finishes the `Span`.
+ pub fn end(&self) {
+ self.end_with_timestamp(crate::time::now());
+ }
+
+ /// Finishes the `Span` with given timestamp
+ pub fn end_with_timestamp(&self, timestamp: std::time::SystemTime) {
+ self.with_inner_mut(move |inner| inner.end_with_timestamp(timestamp))
+ }
+}
struct RemoteSpanContext(crate::trace::SpanContext);
@@ -13,12 +113,12 @@ pub trait TraceContextExt {
/// Returns a clone of the current context with the included span.
///
/// This is useful for building tracers.
- fn current_with_span(span: T) -> Self;
+ fn current_with_span(span: T) -> Self;
/// Returns a clone of this context with the included span.
///
/// This is useful for building tracers.
- fn with_span(&self, span: T) -> Self;
+ fn with_span(&self, span: T) -> Self;
/// Returns a reference to this context's span, or the default no-op span if
/// none has been set.
@@ -40,7 +140,7 @@ pub trait TraceContextExt {
/// assert_ne!(cx.span().span_context(), &SpanContext::empty_context());
/// });
/// ```
- fn span(&self) -> &dyn crate::trace::Span;
+ fn span(&self) -> SpanRef<'_>;
/// Used to see if a span has been marked as active
///
@@ -60,24 +160,30 @@ pub trait TraceContextExt {
}
impl TraceContextExt for Context {
- fn current_with_span(span: T) -> Self {
- Context::current_with_value(Span(Box::new(span)))
+ fn current_with_span(span: T) -> Self {
+ Context::current_with_value(SynchronizedSpan {
+ span_context: span.span_context().clone(),
+ inner: Some(Box::new(Mutex::new(span))),
+ })
}
- fn with_span(&self, span: T) -> Self {
- self.with_value(Span(Box::new(span)))
+ fn with_span(&self, span: T) -> Self {
+ self.with_value(SynchronizedSpan {
+ span_context: span.span_context().clone(),
+ inner: Some(Box::new(Mutex::new(span))),
+ })
}
- fn span(&self) -> &dyn crate::trace::Span {
- if let Some(span) = self.get::() {
- span.0.as_ref()
+ fn span(&self) -> SpanRef<'_> {
+ if let Some(span) = self.get::() {
+ SpanRef(span)
} else {
- &*NOOP_SPAN
+ SpanRef(&*NOOP_SPAN)
}
}
fn has_active_span(&self) -> bool {
- self.get::().is_some()
+ self.get::().is_some()
}
fn with_remote_span_context(&self, span_context: crate::trace::SpanContext) -> Self {
@@ -121,7 +227,7 @@ impl TraceContextExt for Context {
/// }
/// ```
#[must_use = "Dropping the guard detaches the context."]
-pub fn mark_span_as_active(span: T) -> ContextGuard {
+pub fn mark_span_as_active(span: T) -> ContextGuard {
let cx = Context::current_with_span(span);
cx.attach()
}
@@ -151,7 +257,7 @@ pub fn mark_span_as_active(span: T) -> Cont
/// ```
pub fn get_active_span(f: F) -> T
where
- F: FnOnce(&dyn crate::trace::Span) -> T,
+ F: FnOnce(SpanRef<'_>) -> T,
{
f(Context::current().span())
}
diff --git a/opentelemetry/src/trace/noop.rs b/opentelemetry/src/trace/noop.rs
index 7b2dad3540..e2ee5d0949 100644
--- a/opentelemetry/src/trace/noop.rs
+++ b/opentelemetry/src/trace/noop.rs
@@ -63,13 +63,13 @@ impl NoopSpan {
impl trace::Span for NoopSpan {
/// Ignores all events
- fn add_event(&self, _name: String, _attributes: Vec) {
+ fn add_event(&mut self, _name: String, _attributes: Vec) {
// Ignore
}
/// Ignores all events with timestamps
fn add_event_with_timestamp(
- &self,
+ &mut self,
_name: String,
_timestamp: SystemTime,
_attributes: Vec,
@@ -88,22 +88,22 @@ impl trace::Span for NoopSpan {
}
/// Ignores all attributes
- fn set_attribute(&self, _attribute: KeyValue) {
+ fn set_attribute(&mut self, _attribute: KeyValue) {
// Ignored
}
/// Ignores status
- fn set_status(&self, _code: trace::StatusCode, _message: String) {
+ fn set_status(&mut self, _code: trace::StatusCode, _message: String) {
// Ignored
}
/// Ignores name updates
- fn update_name(&self, _new_name: String) {
+ fn update_name(&mut self, _new_name: String) {
// Ignored
}
/// Ignores `Span` endings
- fn end_with_timestamp(&self, _timestamp: SystemTime) {
+ fn end_with_timestamp(&mut self, _timestamp: SystemTime) {
// Ignored
}
}
diff --git a/opentelemetry/src/trace/span.rs b/opentelemetry/src/trace/span.rs
index f7033edc29..2ba22e67e2 100644
--- a/opentelemetry/src/trace/span.rs
+++ b/opentelemetry/src/trace/span.rs
@@ -23,7 +23,7 @@ use std::fmt;
use std::time::SystemTime;
/// Interface for a single operation within a trace.
-pub trait Span: fmt::Debug + 'static + Send + Sync {
+pub trait Span: fmt::Debug {
/// An API to record events in the context of a given `Span`.
///
/// Events have a time associated with the moment when they are
@@ -35,7 +35,7 @@ pub trait Span: fmt::Debug + 'static + Send + Sync {
/// Note that the OpenTelemetry project documents certain ["standard event names and
/// keys"](https://github.com/open-telemetry/opentelemetry-specification/tree/v0.5.0/specification/trace/semantic_conventions/README.md)
/// which have prescribed semantic meanings.
- fn add_event(&self, name: String, attributes: Vec) {
+ fn add_event(&mut self, name: String, attributes: Vec) {
self.add_event_with_timestamp(name, crate::time::now(), attributes)
}
@@ -52,7 +52,7 @@ pub trait Span: fmt::Debug + 'static + Send + Sync {
///
/// Users can custom the exception message by overriding the `fmt::Display` trait's `fmt` method
/// for the error.
- fn record_exception(&self, err: &dyn Error) {
+ fn record_exception(&mut self, err: &dyn Error) {
let attributes = vec![KeyValue::new("exception.message", err.to_string())];
self.add_event("exception".to_string(), attributes);
@@ -61,7 +61,7 @@ pub trait Span: fmt::Debug + 'static + Send + Sync {
/// Convenience method to record a exception/error as an `Event` with custom stacktrace
///
/// See `Span:record_exception` method for more details.
- fn record_exception_with_stacktrace(&self, err: &dyn Error, stacktrace: String) {
+ fn record_exception_with_stacktrace(&mut self, err: &dyn Error, stacktrace: String) {
let attributes = vec![
KeyValue::new("exception.message", err.to_string()),
KeyValue::new("exception.stacktrace", stacktrace),
@@ -79,7 +79,7 @@ pub trait Span: fmt::Debug + 'static + Send + Sync {
/// keys"](https://github.com/open-telemetry/opentelemetry-specification/tree/v0.5.0/specification/trace/semantic_conventions/README.md)
/// which have prescribed semantic meanings.
fn add_event_with_timestamp(
- &self,
+ &mut self,
name: String,
timestamp: SystemTime,
attributes: Vec,
@@ -120,14 +120,14 @@ pub trait Span: fmt::Debug + 'static + Send + Sync {
/// Note that the OpenTelemetry project documents certain ["standard
/// attributes"](https://github.com/open-telemetry/opentelemetry-specification/tree/v0.5.0/specification/trace/semantic_conventions/README.md)
/// that have prescribed semantic meanings.
- fn set_attribute(&self, attribute: KeyValue);
+ fn set_attribute(&mut self, attribute: KeyValue);
/// Sets the status of the `Span`. If used, this will override the default `Span`
/// status, which is `Unset`. `message` MUST be ignored when the status is `OK` or `Unset`
///
/// Only the value of the last call will be recorded, and implementations are free
/// to ignore previous calls.
- fn set_status(&self, code: StatusCode, message: String);
+ fn set_status(&mut self, code: StatusCode, message: String);
/// Updates the `Span`'s name. After this update, any sampling behavior based on the
/// name will depend on the implementation.
@@ -141,7 +141,7 @@ pub trait Span: fmt::Debug + 'static + Send + Sync {
/// regular property. It emphasizes that this operation signifies a
/// major change for a `Span` and may lead to re-calculation of sampling or
/// filtering decisions made previously depending on the implementation.
- fn update_name(&self, new_name: String);
+ fn update_name(&mut self, new_name: String);
/// Finishes the `Span`.
///
@@ -153,7 +153,7 @@ pub trait Span: fmt::Debug + 'static + Send + Sync {
/// still be running and can be ended later.
///
/// This API MUST be non-blocking.
- fn end(&self) {
+ fn end(&mut self) {
self.end_with_timestamp(crate::time::now());
}
@@ -162,7 +162,7 @@ pub trait Span: fmt::Debug + 'static + Send + Sync {
/// For more details, refer to [`Span::end`]
///
/// [`Span::end`]: Span::end()
- fn end_with_timestamp(&self, timestamp: SystemTime);
+ fn end_with_timestamp(&mut self, timestamp: SystemTime);
}
/// `SpanKind` describes the relationship between the Span, its parents,
diff --git a/opentelemetry/src/trace/tracer.rs b/opentelemetry/src/trace/tracer.rs
index fb685c217e..065606f4d1 100644
--- a/opentelemetry/src/trace/tracer.rs
+++ b/opentelemetry/src/trace/tracer.rs
@@ -1,5 +1,5 @@
-use crate::sdk;
use crate::{
+ sdk,
trace::{Event, Link, Span, SpanId, SpanKind, StatusCode, TraceContextExt, TraceId},
Context, KeyValue,
};
@@ -40,7 +40,7 @@ use std::time::SystemTime;
///
/// let parent = tracer.start("foo");
/// let parent_cx = Context::current_with_span(parent);
-/// let child = tracer.span_builder("bar")
+/// let mut child = tracer.span_builder("bar")
/// .with_parent_context(parent_cx.clone())
/// .start(&tracer);
///
@@ -158,7 +158,7 @@ use std::time::SystemTime;
/// [`Context`]: crate::Context
pub trait Tracer: fmt::Debug + 'static {
/// The `Span` type used by this `Tracer`.
- type Span: Span;
+ type Span: Span + Send + Sync;
/// Returns a span with an invalid `SpanContext`. Used by functions that
/// need to return a default span like `get_active_span` if no span is present.