tokio_trace_core/span.rs
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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
//! Spans represent periods of time in the execution of a program.
use {field, Metadata};
/// Identifies a span within the context of a subscriber.
///
/// They are generated by [`Subscriber`]s for each span as it is created, by
/// the [`new_span`] trait method. See the documentation for that method for
/// more information on span ID generation.
///
/// [`Subscriber`]: ../subscriber/trait.Subscriber.html
/// [`new_span`]: ../subscriber/trait.Subscriber.html#method.new_span
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
// TODO(eliza): when Tokio's minimum Rust version is >= 1.28, change the
// internal representation to a `NonZeroU64`.
pub struct Id(u64);
/// Attributes provided to a `Subscriber` describing a new span when it is
/// created.
#[derive(Debug)]
pub struct Attributes<'a> {
metadata: &'a Metadata<'a>,
values: &'a field::ValueSet<'a>,
parent: Parent,
}
/// A set of fields recorded by a span.
#[derive(Debug)]
pub struct Record<'a> {
values: &'a field::ValueSet<'a>,
}
#[derive(Debug)]
enum Parent {
/// The new span will be a root span.
Root,
/// The new span will be rooted in the current span.
Current,
/// The new span has an explicitly-specified parent.
Explicit(Id),
}
// ===== impl Span =====
impl Id {
/// Constructs a new span ID from the given `u64`.
///
/// **Note**: Span IDs must be greater than zero.
///
/// # Panics
/// - If the provided `u64` is 0
pub fn from_u64(u: u64) -> Self {
assert!(u > 0);
Id(u)
}
/// Returns the span's ID as a `u64`.
pub fn into_u64(&self) -> u64 {
self.0
}
}
// ===== impl Attributes =====
impl<'a> Attributes<'a> {
/// Returns `Attributes` describing a new child span of the current span,
/// with the provided metadata and values.
pub fn new(metadata: &'a Metadata<'a>, values: &'a field::ValueSet<'a>) -> Self {
Attributes {
metadata,
values,
parent: Parent::Current,
}
}
/// Returns `Attributes` describing a new span at the root of its own trace
/// tree, with the provided metadata and values.
pub fn new_root(metadata: &'a Metadata<'a>, values: &'a field::ValueSet<'a>) -> Self {
Attributes {
metadata,
values,
parent: Parent::Root,
}
}
/// Returns `Attributes` describing a new child span of the specified
/// parent span, with the provided metadata and values.
pub fn child_of(
parent: Id,
metadata: &'a Metadata<'a>,
values: &'a field::ValueSet<'a>,
) -> Self {
Attributes {
metadata,
values,
parent: Parent::Explicit(parent),
}
}
/// Returns a reference to the new span's metadata.
pub fn metadata(&self) -> &Metadata<'a> {
self.metadata
}
/// Returns a reference to a `ValueSet` containing any values the new span
/// was created with.
pub fn values(&self) -> &field::ValueSet<'a> {
self.values
}
/// Returns true if the new span shoold be a root.
pub fn is_root(&self) -> bool {
match self.parent {
Parent::Root => true,
_ => false,
}
}
/// Returns true if the new span'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 span's parent. Otherwise, if the current
/// thread is _not_ inside a span, then the new span 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 span's explicitly-specified parent, if there is one.
///
/// Otherwise (if the new span 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,
}
}
/// Records all the fields in this set of `Attributes` with the provided
/// [Visitor].
///
/// [visitor]: ../field/trait.Visit.html
pub fn record(&self, visitor: &mut field::Visit) {
self.values.record(visitor)
}
/// Returns `true` if this set of `Attributes` contains a value for the
/// given `Field`.
pub fn contains(&self, field: &field::Field) -> bool {
self.values.contains(field)
}
/// Returns true if this set of `Attributes` contains _no_ values.
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
}
// ===== impl Record =====
impl<'a> Record<'a> {
/// Constructs a new `Record` from a `ValueSet`.
pub fn new(values: &'a field::ValueSet<'a>) -> Self {
Self { values }
}
/// Records all the fields in this `Record` with the provided [Visitor].
///
/// [visitor]: ../field/trait.Visit.html
pub fn record(&self, visitor: &mut field::Visit) {
self.values.record(visitor)
}
/// Returns `true` if this `Record` contains a value for the given `Field`.
pub fn contains(&self, field: &field::Field) -> bool {
self.values.contains(field)
}
/// Returns true if this `Record` contains _no_ values.
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
}