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