pub struct Context { /* private fields */ }
Expand description
An execution-scoped collection of values.
A Context
is a propagation mechanism which carries execution-scoped
values across API boundaries and between logically associated execution
units. Cross-cutting concerns access their data in-process using the same
shared context object.
Context
s are immutable, and their write operations result in the creation
of a new context containing the original values and the new specified values.
§Context state
Concerns can create and retrieve their local state in the current execution
state represented by a context through the get
and with_value
methods. It is recommended to use application-specific types when storing new
context values to avoid unintentionally overwriting existing state.
§Managing the current context
Contexts can be associated with the caller’s current execution unit on a
given thread via the attach
method, and previous contexts can be restored
by dropping the returned ContextGuard
. Context can be nested, and will
restore their parent outer context when detached on drop. To access the
values of the context, a snapshot can be created via the Context::current
method.
§Examples
use opentelemetry::Context;
// Application-specific `a` and `b` values
#[derive(Debug, PartialEq)]
struct ValueA(&'static str);
#[derive(Debug, PartialEq)]
struct ValueB(u64);
let _outer_guard = Context::new().with_value(ValueA("a")).attach();
// Only value a has been set
let current = Context::current();
assert_eq!(current.get::<ValueA>(), Some(&ValueA("a")));
assert_eq!(current.get::<ValueB>(), None);
{
let _inner_guard = Context::current_with_value(ValueB(42)).attach();
// Both values are set in inner context
let current = Context::current();
assert_eq!(current.get::<ValueA>(), Some(&ValueA("a")));
assert_eq!(current.get::<ValueB>(), Some(&ValueB(42)));
}
// Resets to only the `a` value when inner guard is dropped
let current = Context::current();
assert_eq!(current.get::<ValueA>(), Some(&ValueA("a")));
assert_eq!(current.get::<ValueB>(), None);
Implementations§
source§impl Context
impl Context
sourcepub fn new() -> Self
pub fn new() -> Self
Creates an empty Context
.
The context is initially created with a capacity of 0, so it will not
allocate. Use with_value
to create a new context that has entries.
sourcepub fn current() -> Self
pub fn current() -> Self
Returns an immutable snapshot of the current thread’s context.
§Examples
use opentelemetry::Context;
#[derive(Debug, PartialEq)]
struct ValueA(&'static str);
fn do_work() {
assert_eq!(Context::current().get(), Some(&ValueA("a")));
}
let _guard = Context::new().with_value(ValueA("a")).attach();
do_work()
sourcepub fn map_current<T>(f: impl FnOnce(&Context) -> T) -> T
pub fn map_current<T>(f: impl FnOnce(&Context) -> T) -> T
Applies a function to the current context returning its value.
This can be used to build higher performing algebraic expressions for optionally creating a new context without the overhead of cloning the current one and dropping it.
Note: This function will panic if you attempt to attach another context while the current one is still borrowed.
sourcepub fn current_with_value<T: 'static + Send + Sync>(value: T) -> Self
pub fn current_with_value<T: 'static + Send + Sync>(value: T) -> Self
Returns a clone of the current thread’s context with the given value.
This is a more efficient form of Context::current().with_value(value)
as it avoids the intermediate context clone.
§Examples
use opentelemetry::Context;
// Given some value types defined in your application
#[derive(Debug, PartialEq)]
struct ValueA(&'static str);
#[derive(Debug, PartialEq)]
struct ValueB(u64);
// You can create and attach context with the first value set to "a"
let _guard = Context::new().with_value(ValueA("a")).attach();
// And create another context based on the fist with a new value
let all_current_and_b = Context::current_with_value(ValueB(42));
// The second context now contains all the current values and the addition
assert_eq!(all_current_and_b.get::<ValueA>(), Some(&ValueA("a")));
assert_eq!(all_current_and_b.get::<ValueB>(), Some(&ValueB(42)));
sourcepub fn get<T: 'static>(&self) -> Option<&T>
pub fn get<T: 'static>(&self) -> Option<&T>
Returns a reference to the entry for the corresponding value type.
§Examples
use opentelemetry::Context;
// Given some value types defined in your application
#[derive(Debug, PartialEq)]
struct ValueA(&'static str);
#[derive(Debug, PartialEq)]
struct MyUser();
let cx = Context::new().with_value(ValueA("a"));
// Values can be queried by type
assert_eq!(cx.get::<ValueA>(), Some(&ValueA("a")));
// And return none if not yet set
assert_eq!(cx.get::<MyUser>(), None);
sourcepub fn with_value<T: 'static + Send + Sync>(&self, value: T) -> Self
pub fn with_value<T: 'static + Send + Sync>(&self, value: T) -> Self
Returns a copy of the context with the new value included.
§Examples
use opentelemetry::Context;
// Given some value types defined in your application
#[derive(Debug, PartialEq)]
struct ValueA(&'static str);
#[derive(Debug, PartialEq)]
struct ValueB(u64);
// You can create a context with the first value set to "a"
let cx_with_a = Context::new().with_value(ValueA("a"));
// And create another context based on the fist with a new value
let cx_with_a_and_b = cx_with_a.with_value(ValueB(42));
// The first context is still available and unmodified
assert_eq!(cx_with_a.get::<ValueA>(), Some(&ValueA("a")));
assert_eq!(cx_with_a.get::<ValueB>(), None);
// The second context now contains both values
assert_eq!(cx_with_a_and_b.get::<ValueA>(), Some(&ValueA("a")));
assert_eq!(cx_with_a_and_b.get::<ValueB>(), Some(&ValueB(42)));
sourcepub fn attach(self) -> ContextGuard
pub fn attach(self) -> ContextGuard
Replaces the current context on this thread with this context.
Dropping the returned ContextGuard
will reset the current context to the
previous value.
§Examples
use opentelemetry::Context;
#[derive(Debug, PartialEq)]
struct ValueA(&'static str);
let my_cx = Context::new().with_value(ValueA("a"));
// Set the current thread context
let cx_guard = my_cx.attach();
assert_eq!(Context::current().get::<ValueA>(), Some(&ValueA("a")));
// Drop the guard to restore the previous context
drop(cx_guard);
assert_eq!(Context::current().get::<ValueA>(), None);
Guards do not need to be explicitly dropped:
use opentelemetry::Context;
#[derive(Debug, PartialEq)]
struct ValueA(&'static str);
fn my_function() -> String {
// attach a context the duration of this function.
let my_cx = Context::new().with_value(ValueA("a"));
// NOTE: a variable name after the underscore is **required** or rust
// will drop the guard, restoring the previous context _immediately_.
let _guard = my_cx.attach();
// anything happening in functions we call can still access my_cx...
my_other_function();
// returning from the function drops the guard, exiting the span.
return "Hello world".to_owned();
}
fn my_other_function() {
// ...
}
Sub-scopes may be created to limit the duration for which the span is entered:
use opentelemetry::Context;
#[derive(Debug, PartialEq)]
struct ValueA(&'static str);
let my_cx = Context::new().with_value(ValueA("a"));
{
let _guard = my_cx.attach();
// the current context can access variables in
assert_eq!(Context::current().get::<ValueA>(), Some(&ValueA("a")));
// exiting the scope drops the guard, detaching the context.
}
// this is back in the default empty context
assert_eq!(Context::current().get::<ValueA>(), None);
Trait Implementations§
source§impl BaggageExt for Context
impl BaggageExt for Context
source§fn with_baggage<T: IntoIterator<Item = I>, I: Into<KeyValueMetadata>>(
&self,
baggage: T,
) -> Self
fn with_baggage<T: IntoIterator<Item = I>, I: Into<KeyValueMetadata>>( &self, baggage: T, ) -> Self
source§fn current_with_baggage<T: IntoIterator<Item = I>, I: Into<KeyValueMetadata>>(
kvs: T,
) -> Self
fn current_with_baggage<T: IntoIterator<Item = I>, I: Into<KeyValueMetadata>>( kvs: T, ) -> Self
source§fn with_cleared_baggage(&self) -> Self
fn with_cleared_baggage(&self) -> Self
source§impl TraceContextExt for Context
impl TraceContextExt for Context
source§fn with_span<T: Span + Send + Sync + 'static>(&self, span: T) -> Self
fn with_span<T: Span + Send + Sync + 'static>(&self, span: T) -> Self
source§fn span(&self) -> SpanRef<'_>
fn span(&self) -> SpanRef<'_>
source§fn has_active_span(&self) -> bool
fn has_active_span(&self) -> bool
source§fn with_remote_span_context(&self, span_context: SpanContext) -> Self
fn with_remote_span_context(&self, span_context: SpanContext) -> Self
Auto Trait Implementations§
impl Freeze for Context
impl !RefUnwindSafe for Context
impl Send for Context
impl Sync for Context
impl Unpin for Context
impl !UnwindSafe for Context
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)