1 //! Events represent single points in time during the execution of a program.
2 use crate::parent::Parent;
3 use crate::span::Id;
4 use 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]: ../span
21 /// [fields]: ../field
22 #[derive(Debug)]
23 pub struct Event<'a> {
24     fields: &'a field::ValueSet<'a>,
25     metadata: &'static Metadata<'static>,
26     parent: Parent,
27 }
28 
29 impl<'a> Event<'a> {
30     /// Constructs a new `Event` with the specified metadata and set of values,
31     /// and observes it with the current subscriber.
dispatch(metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'_>)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]
new(metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'a>) -> Self42     pub fn new(metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'a>) -> Self {
43         Event {
44             metadata,
45             fields,
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]
new_child_of( parent: impl Into<Option<Id>>, metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'a>, ) -> Self53     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             metadata,
64             fields,
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.
child_of( parent: impl Into<Option<Id>>, metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'_>, )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]: ../field/trait.Visit.html
85     #[inline]
record(&self, visitor: &mut dyn field::Visit)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`.
fields(&self) -> field::Iter91     pub fn fields(&self) -> field::Iter {
92         self.fields.field_set().iter()
93     }
94 
95     /// Returns [metadata] describing this `Event`.
96     ///
97     /// [metadata]: ../struct.Metadata.html
metadata(&self) -> &'static Metadata<'static>98     pub fn metadata(&self) -> &'static Metadata<'static> {
99         self.metadata
100     }
101 
102     /// Returns true if the new event should be a root.
is_root(&self) -> bool103     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.
is_contextual(&self) -> bool114     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 false.
parent(&self) -> Option<&Id>122     pub fn parent(&self) -> Option<&Id> {
123         match self.parent {
124             Parent::Explicit(ref p) => Some(p),
125             _ => None,
126         }
127     }
128 }
129