Expand description
Spans represent periods of time in the execution of a program.
§Entering a Span
A thread of execution is said to enter a span when it begins executing,
and exit the span when it switches to another context. Spans may be
entered through the enter
method, which enters the target span,
performs a given function (either a closure or a function pointer), exits
the span, and then returns the result.
Calling enter
on a span handle enters the span that handle corresponds to,
if the span exists:
let my_var: u64 = 5;
let my_span = span!(Level::TRACE, "my_span", my_var = &my_var);
my_span.enter(|| {
// perform some work in the context of `my_span`...
});
// Perform some work outside of the context of `my_span`...
my_span.enter(|| {
// Perform some more work in the context of `my_span`.
});
§The Span Lifecycle
Execution may enter and exit a span multiple times before that span is closed. Consider, for example, a future which has an associated span and enters that span every time it is polled:
struct MyFuture {
// data
span: tokio_trace::Span,
}
impl Future for MyFuture {
type Item = ();
type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
self.span.enter(|| {
// Do actual future work
})
}
}
If this future was spawned on an executor, it might yield one or more times
before poll
returns Ok(Async::Ready)
. If the future were to yield, then
the executor would move on to poll the next future, which may also enter
an associated span or series of spans. Therefore, it is valid for a span to
be entered repeatedly before it completes. Only the time when that span or
one of its children was the current span is considered to be time spent in
that span. A span which is not executing and has not yet been closed is said
to be idle.
Because spans may be entered and exited multiple times before they close,
Subscriber
s have separate trait methods which are called to notify them
of span exits and when span handles are dropped. When execution exits a
span, exit
will always be called with that span’s ID to notify the
subscriber that the span has been exited. When span handles are dropped, the
drop_span
method is called with that span’s ID. The subscriber may use
this to determine whether or not the span will be entered again.
If there is only a single handle with the capacity to exit a span, dropping that handle “close” the span, since the capacity to enter it no longer exists. For example:
{
span!(Level::TRACE, "my_span").enter(|| {
// perform some work in the context of `my_span`...
}); // --> Subscriber::exit(my_span)
// The handle to `my_span` only lives inside of this block; when it is
// dropped, the subscriber will be informed via `drop_span`.
} // --> Subscriber::drop_span(my_span)
However, if multiple handles exist, the span can still be re-entered even if
one or more is dropped. For determining when all handles to a span have
been dropped, Subscriber
s have a clone_span
method, which is called
every time a span handle is cloned. Combined with drop_span
, this may be
used to track the number of handles to a given span — if drop_span
has
been called one more time than the number of calls to clone_span
for a
given ID, then no more handles to the span with that ID exist. The
subscriber may then treat it as closed.
§Accessing a Span’s Attributes
The Attributes
type represents a non-entering reference to a Span
’s data
— a set of key-value pairs (known as fields), a creation timestamp,
a reference to the span’s parent in the trace tree, and metadata describing
the source code location where the span was created. This data is provided
to the Subscriber
when the span is created; it may then choose to cache
the data for future use, record it in some manner, or discard it completely.
Structs§
- Attributes provided to a
Subscriber
describing a new span when it is created. - Identifies a span within the context of a subscriber.
- A set of fields recorded by a span.
- A handle representing a span, with the capability to enter the span if it exists.
Traits§
- Trait implemented by types which have a span
Id
.