]>
git.proxmox.com Git - rustc.git/blob - vendor/tracing-core/src/span.rs
1 //! Spans represent periods of time in the execution of a program.
2 use crate::field
::FieldSet
;
3 use crate::parent
::Parent
;
4 use crate::stdlib
::num
::NonZeroU64
;
5 use crate::{field, Metadata}
;
7 /// Identifies a span within the context of a subscriber.
9 /// They are generated by [`Subscriber`]s for each span as it is created, by
10 /// the [`new_span`] trait method. See the documentation for that method for
11 /// more information on span ID generation.
13 /// [`Subscriber`]: super::subscriber::Subscriber
14 /// [`new_span`]: super::subscriber::Subscriber::new_span
15 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
16 pub struct Id(NonZeroU64
);
18 /// Attributes provided to a `Subscriber` describing a new span when it is
21 pub struct Attributes
<'a
> {
22 metadata
: &'
static Metadata
<'
static>,
23 values
: &'a field
::ValueSet
<'a
>,
27 /// A set of fields recorded by a span.
29 pub struct Record
<'a
> {
30 values
: &'a field
::ValueSet
<'a
>,
33 /// Indicates what [the `Subscriber` considers] the "current" span.
35 /// As subscribers may not track a notion of a current span, this has three
37 /// - "unknown", indicating that the subscriber does not track a current span,
38 /// - "none", indicating that the current context is known to not be in a span,
39 /// - "some", with the current span's [`Id`] and [`Metadata`].
41 /// [the `Subscriber` considers]: super::subscriber::Subscriber::current_span
42 /// [`Metadata`]: super::metadata::Metadata
52 metadata
: &'
static Metadata
<'
static>,
58 // ===== impl Span =====
61 /// Constructs a new span ID from the given `u64`.
63 /// <pre class="ignore" style="white-space:normal;font:inherit;">
64 /// <strong>Note</strong>: Span IDs must be greater than zero.
68 /// - If the provided `u64` is 0.
69 pub fn from_u64(u
: u64) -> Self {
70 Id(NonZeroU64
::new(u
).expect("span IDs must be > 0"))
73 /// Constructs a new span ID from the given `NonZeroU64`.
75 /// Unlike [`Id::from_u64`](Id::from_u64()), this will never panic.
77 pub const fn from_non_zero_u64(id
: NonZeroU64
) -> Self {
81 // Allow `into` by-ref since we don't want to impl Copy for Id
82 #[allow(clippy::wrong_self_convention)]
83 /// Returns the span's ID as a `u64`.
84 pub fn into_u64(&self) -> u64 {
88 // Allow `into` by-ref since we don't want to impl Copy for Id
89 #[allow(clippy::wrong_self_convention)]
90 /// Returns the span's ID as a `NonZeroU64`.
92 pub const fn into_non_zero_u64(&self) -> NonZeroU64
{
97 impl<'a
> From
<&'a Id
> for Option
<Id
> {
98 fn from(id
: &'a Id
) -> Self {
103 // ===== impl Attributes =====
105 impl<'a
> Attributes
<'a
> {
106 /// Returns `Attributes` describing a new child span of the current span,
107 /// with the provided metadata and values.
108 pub fn new(metadata
: &'
static Metadata
<'
static>, values
: &'a field
::ValueSet
<'a
>) -> Self {
112 parent
: Parent
::Current
,
116 /// Returns `Attributes` describing a new span at the root of its own trace
117 /// tree, with the provided metadata and values.
118 pub fn new_root(metadata
: &'
static Metadata
<'
static>, values
: &'a field
::ValueSet
<'a
>) -> Self {
122 parent
: Parent
::Root
,
126 /// Returns `Attributes` describing a new child span of the specified
127 /// parent span, with the provided metadata and values.
130 metadata
: &'
static Metadata
<'
static>,
131 values
: &'a field
::ValueSet
<'a
>,
136 parent
: Parent
::Explicit(parent
),
140 /// Returns a reference to the new span's metadata.
141 pub fn metadata(&self) -> &'
static Metadata
<'
static> {
145 /// Returns a reference to a `ValueSet` containing any values the new span
146 /// was created with.
147 pub fn values(&self) -> &field
::ValueSet
<'a
> {
151 /// Returns true if the new span should be a root.
152 pub fn is_root(&self) -> bool
{
153 matches
!(self.parent
, Parent
::Root
)
156 /// Returns true if the new span's parent should be determined based on the
159 /// If this is true and the current thread is currently inside a span, then
160 /// that span should be the new span's parent. Otherwise, if the current
161 /// thread is _not_ inside a span, then the new span will be the root of its
163 pub fn is_contextual(&self) -> bool
{
164 matches
!(self.parent
, Parent
::Current
)
167 /// Returns the new span's explicitly-specified parent, if there is one.
169 /// Otherwise (if the new span is a root or is a child of the current span),
171 pub fn parent(&self) -> Option
<&Id
> {
173 Parent
::Explicit(ref p
) => Some(p
),
178 /// Records all the fields in this set of `Attributes` with the provided
181 /// [visitor]: super::field::Visit
182 pub fn record(&self, visitor
: &mut dyn field
::Visit
) {
183 self.values
.record(visitor
)
186 /// Returns `true` if this set of `Attributes` contains a value for the
188 pub fn contains(&self, field
: &field
::Field
) -> bool
{
189 self.values
.contains(field
)
192 /// Returns true if this set of `Attributes` contains _no_ values.
193 pub fn is_empty(&self) -> bool
{
194 self.values
.is_empty()
197 /// Returns the set of all [fields] defined by this span's [`Metadata`].
199 /// Note that the [`FieldSet`] returned by this method includes *all* the
200 /// fields declared by this span, not just those with values that are recorded
201 /// as part of this set of `Attributes`. Other fields with values not present in
202 /// this `Attributes`' value set may [record] values later.
204 /// [fields]: crate::field
205 /// [record]: Attributes::record()
206 /// [`Metadata`]: crate::metadata::Metadata
207 /// [`FieldSet`]: crate::field::FieldSet
208 pub fn fields(&self) -> &FieldSet
{
209 self.values
.field_set()
213 // ===== impl Record =====
215 impl<'a
> Record
<'a
> {
216 /// Constructs a new `Record` from a `ValueSet`.
217 pub fn new(values
: &'a field
::ValueSet
<'a
>) -> Self {
221 /// Records all the fields in this `Record` with the provided [Visitor].
223 /// [visitor]: super::field::Visit
224 pub fn record(&self, visitor
: &mut dyn field
::Visit
) {
225 self.values
.record(visitor
)
228 /// Returns the number of fields that would be visited from this `Record`
229 /// when [`Record::record()`] is called
231 /// [`Record::record()`]: Record::record()
232 pub fn len(&self) -> usize {
236 /// Returns `true` if this `Record` contains a value for the given `Field`.
237 pub fn contains(&self, field
: &field
::Field
) -> bool
{
238 self.values
.contains(field
)
241 /// Returns true if this `Record` contains _no_ values.
242 pub fn is_empty(&self) -> bool
{
243 self.values
.is_empty()
247 // ===== impl Current =====
250 /// Constructs a new `Current` that indicates the current context is a span
251 /// with the given `metadata` and `metadata`.
252 pub fn new(id
: Id
, metadata
: &'
static Metadata
<'
static>) -> Self {
254 inner
: CurrentInner
::Current { id, metadata }
,
258 /// Constructs a new `Current` that indicates the current context is *not*
260 pub fn none() -> Self {
262 inner
: CurrentInner
::None
,
266 /// Constructs a new `Current` that indicates the `Subscriber` does not
267 /// track a current span.
268 pub(crate) fn unknown() -> Self {
270 inner
: CurrentInner
::Unknown
,
274 /// Returns `true` if the `Subscriber` that constructed this `Current` tracks a
277 /// If this returns `true` and [`id`], [`metadata`], or [`into_inner`]
278 /// return `None`, that indicates that we are currently known to *not* be
279 /// inside a span. If this returns `false`, those methods will also return
280 /// `None`, but in this case, that is because the subscriber does not keep
281 /// track of the currently-entered span.
283 /// [`id`]: Current::id()
284 /// [`metadata`]: Current::metadata()
285 /// [`into_inner`]: Current::into_inner()
286 pub fn is_known(&self) -> bool
{
287 !matches
!(self.inner
, CurrentInner
::Unknown
)
290 /// Consumes `self` and returns the span `Id` and `Metadata` of the current
291 /// span, if one exists and is known.
292 pub fn into_inner(self) -> Option
<(Id
, &'
static Metadata
<'
static>)> {
294 CurrentInner
::Current { id, metadata }
=> Some((id
, metadata
)),
299 /// Borrows the `Id` of the current span, if one exists and is known.
300 pub fn id(&self) -> Option
<&Id
> {
302 CurrentInner
::Current { ref id, .. }
=> Some(id
),
307 /// Borrows the `Metadata` of the current span, if one exists and is known.
308 pub fn metadata(&self) -> Option
<&'
static Metadata
<'
static>> {
310 CurrentInner
::Current { metadata, .. }
=> Some(metadata
),
316 impl<'a
> From
<&'a Current
> for Option
<&'a Id
> {
317 fn from(cur
: &'a Current
) -> Self {
322 impl<'a
> From
<&'a Current
> for Option
<Id
> {
323 fn from(cur
: &'a Current
) -> Self {
328 impl From
<Current
> for Option
<Id
> {
329 fn from(cur
: Current
) -> Self {
331 CurrentInner
::Current { id, .. }
=> Some(id
),
337 impl<'a
> From
<&'a Current
> for Option
<&'
static Metadata
<'
static>> {
338 fn from(cur
: &'a Current
) -> Self {