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