tracing_core/
event.rs

1//! Events represent single points in time during the execution of a program.
2use crate::parent::Parent;
3use crate::span::Id;
4use crate::{field, Metadata};
5
6/// `Event`s represent single points in time where something occurred during the
7/// execution of a program.
8///
9/// An `Event` can be compared to a log record in unstructured logging, but with
10/// two key differences:
11/// - `Event`s exist _within the context of a [span]_. Unlike log lines, they
12///   may be located within the trace tree, allowing visibility into the
13///   _temporal_ context in which the event occurred, as well as the source
14///   code location.
15/// - Like spans, `Event`s have structured key-value data known as _[fields]_,
16///   which may include textual message. In general, a majority of the data
17///   associated with an event should be in the event's fields rather than in
18///   the textual message, as the fields are more structured.
19///
20/// [span]: super::span
21/// [fields]: super::field
22#[derive(Debug)]
23pub struct Event<'a> {
24    fields: &'a field::ValueSet<'a>,
25    metadata: &'static Metadata<'static>,
26    parent: Parent,
27}
28
29impl<'a> Event<'a> {
30    /// Constructs a new `Event` with the specified metadata and set of values,
31    /// and observes it with the current subscriber.
32    pub fn dispatch(metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'_>) {
33        let event = Event::new(metadata, fields);
34        crate::dispatcher::get_default(|current| {
35            current.event(&event);
36        });
37    }
38
39    /// Returns a new `Event` in the current span, with the specified metadata
40    /// and set of values.
41    #[inline]
42    pub fn new(metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'a>) -> Self {
43        Event {
44            fields,
45            metadata,
46            parent: Parent::Current,
47        }
48    }
49
50    /// Returns a new `Event` as a child of the specified span, with the
51    /// provided metadata and set of values.
52    #[inline]
53    pub fn new_child_of(
54        parent: impl Into<Option<Id>>,
55        metadata: &'static Metadata<'static>,
56        fields: &'a field::ValueSet<'a>,
57    ) -> Self {
58        let parent = match parent.into() {
59            Some(p) => Parent::Explicit(p),
60            None => Parent::Root,
61        };
62        Event {
63            fields,
64            metadata,
65            parent,
66        }
67    }
68
69    /// Constructs a new `Event` with the specified metadata and set of values,
70    /// and observes it with the current subscriber and an explicit parent.
71    pub fn child_of(
72        parent: impl Into<Option<Id>>,
73        metadata: &'static Metadata<'static>,
74        fields: &'a field::ValueSet<'_>,
75    ) {
76        let event = Self::new_child_of(parent, metadata, fields);
77        crate::dispatcher::get_default(|current| {
78            current.event(&event);
79        });
80    }
81
82    /// Visits all the fields on this `Event` with the specified [visitor].
83    ///
84    /// [visitor]: super::field::Visit
85    #[inline]
86    pub fn record(&self, visitor: &mut dyn field::Visit) {
87        self.fields.record(visitor);
88    }
89
90    /// Returns an iterator over the set of values on this `Event`.
91    pub fn fields(&self) -> field::Iter {
92        self.fields.field_set().iter()
93    }
94
95    /// Returns [metadata] describing this `Event`.
96    ///
97    /// [metadata]: super::Metadata
98    pub fn metadata(&self) -> &'static Metadata<'static> {
99        self.metadata
100    }
101
102    /// Returns true if the new event should be a root.
103    pub fn is_root(&self) -> bool {
104        matches!(self.parent, Parent::Root)
105    }
106
107    /// Returns true if the new event's parent should be determined based on the
108    /// current context.
109    ///
110    /// If this is true and the current thread is currently inside a span, then
111    /// that span should be the new event's parent. Otherwise, if the current
112    /// thread is _not_ inside a span, then the new event will be the root of its
113    /// own trace tree.
114    pub fn is_contextual(&self) -> bool {
115        matches!(self.parent, Parent::Current)
116    }
117
118    /// Returns the new event's explicitly-specified parent, if there is one.
119    ///
120    /// Otherwise (if the new event is a root or is a child of the current span),
121    /// returns `None`.
122    pub fn parent(&self) -> Option<&Id> {
123        match self.parent {
124            Parent::Explicit(ref p) => Some(p),
125            _ => None,
126        }
127    }
128}