pub struct EnteredSpan { /* private fields */ }Expand description
An owned version of Entered, a guard representing a span which has been
entered and is currently executing.
When the guard is dropped, the span will be exited.
This is returned by the Span::entered function.
Implementations§
Methods from Deref<Target = Span>§
Sourcepub fn enter(&self) -> Entered<'_>
pub fn enter(&self) -> Entered<'_>
Enters this span, returning a guard that will exit the span when dropped.
If this span is enabled by the current collector, then this function will
call Collect::enter with the span’s Id, and dropping the guard
will call Collect::exit. If the span is disabled, this does
nothing.
Note: The returned
Enteredguard does not implementSend. Dropping the guard will exit this span, and if the guard is sent to another thread and dropped there, that thread may never have entered this span. Thus,Enteredshould not be sent between threads.
Warning: in asynchronous code that uses async/await syntax,
Span::enter should be used very carefully or avoided entirely. Holding
the drop guard returned by Span::enter across .await points will
result in incorrect traces. For example,
async fn my_async_function() {
let span = info_span!("my_async_function");
// WARNING: This span will remain entered until this
// guard is dropped...
let _enter = span.enter();
// ...but the `await` keyword may yield, causing the
// runtime to switch to another task, while remaining in
// this span!
some_other_async_function().await
// ...
}The drop guard returned by Span::enter exits the span when it is
dropped. When an async function or async block yields at an .await
point, the current scope is exited, but values in that scope are
not dropped (because the async block will eventually resume
execution from that await point). This means that another task will
begin executing while remaining in the entered span. This results in
an incorrect trace.
Instead of using Span::enter in asynchronous code, prefer the
following:
-
To enter a span for a synchronous section of code within an async block or function, prefer
Span::in_scope. Sincein_scopetakes a synchronous closure and exits the span when the closure returns, the span will always be exited before the next await point. For example:async fn my_async_function() { let span = info_span!("my_async_function"); let some_value = span.in_scope(|| { // run some synchronous code inside the span... }); // This is okay! The span has already been exited before we reach // the await point. some_other_async_function(some_value).await; // ... } -
For instrumenting asynchronous code,
tracingprovides theFuture::instrumentcombinator for attaching a span to a future (async function or block). This will enter the span every time the future is polled, and exit it whenever the future yields.Instrumentcan be used with an async block inside an async function:ⓘuse tracing::Instrument; async fn my_async_function() { let span = info_span!("my_async_function"); async move { // This is correct! If we yield here, the span will be exited, // and re-entered when we resume. some_other_async_function().await; //more asynchronous code inside the span... } // instrument the async block with the span... .instrument(span) // ...and await it. .await }It can also be used to instrument calls to async functions at the callsite:
ⓘuse tracing::Instrument; async fn my_async_function() { let some_value = some_other_async_function() .instrument(debug_span!("some_other_async_function")) .await; // ... } -
The
#[instrument]attribute macro can automatically generate correct code when used on an async function:ⓘ#[tracing::instrument(level = "info")] async fn my_async_function() { // This is correct! If we yield here, the span will be exited, // and re-entered when we resume. some_other_async_function().await; // ... }
§Examples
let span = span!(Level::INFO, "my_span");
let guard = span.enter();
// code here is within the span
drop(guard);
// code here is no longer within the span
Guards need not be explicitly dropped:
fn my_function() -> String {
// enter a span for the duration of this function.
let span = trace_span!("my_function");
let _enter = span.enter();
// anything happening in functions we call is still inside the span...
my_other_function();