      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
    129
    130
    131
    132
    133
    134

    //! 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 {
            match self.parent {
                Parent::Root => true,
                _ => false,
            }
        }

        /// 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 {
            match self.parent {
                Parent::Current => true,
                _ => false,
            }
        }

        /// 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,
            }
        }
    }