tokio_trace_core/metadata.rs
1//! Metadata describing trace data.
2use super::{
3 callsite::{self, Callsite},
4 field,
5};
6use std::fmt;
7
8/// Metadata describing a [span] or [event].
9///
10/// This includes the source code location where the span occurred, the names of
11/// its fields, et cetera.
12///
13/// Metadata is used by [`Subscriber`]s when filtering spans and events, and it
14/// may also be used as part of their data payload.
15///
16/// When created by the `event!` or `span!` macro, the metadata describing a
17/// particular event or span is constructed statically and exists as a single
18/// static instance. Thus, the overhead of creating the metadata is
19/// _significantly_ lower than that of creating the actual span. Therefore,
20/// filtering is based on metadata, rather than on the constructed span.
21///
22/// **Note**: Although instances of `Metadata` cannot be compared directly, they
23/// provide a method [`Metadata::id()`] which returns an an opaque [callsite
24/// identifier] which uniquely identifies the callsite where the metadata
25/// originated. This can be used for determining if two Metadata correspond to
26/// the same callsite.
27///
28/// [span]: ../span
29/// [`Subscriber`]: ../subscriber/trait.Subscriber.html
30/// [`Metadata::id()`]: struct.Metadata.html#method.id
31/// [callsite identifier]: ../callsite/struct.Identifier.html
32// TODO: When `const fn` is stable, make this type's fields private.
33pub struct Metadata<'a> {
34 /// The name of the span described by this metadata.
35 ///
36 /// **Warning**: The fields on this type are currently `pub` because it must
37 /// be able to be constructed statically by macros. However, when `const
38 /// fn`s are available on stable Rust, this will no longer be necessary.
39 /// Thus, these fields are *not* considered stable public API, and they may
40 /// change warning. Do not rely on any fields on `Metadata`. When
41 /// constructing new `Metadata`, use the `metadata!` macro or the
42 /// `Metadata::new` constructor instead!
43 #[doc(hidden)]
44 pub name: &'static str,
45
46 /// The part of the system that the span that this metadata describes
47 /// occurred in.
48 ///
49 /// Typically, this is the module path, but alternate targets may be set
50 /// when spans or events are constructed.
51 ///
52 /// **Warning**: The fields on this type are currently `pub` because it must
53 /// be able to be constructed statically by macros. However, when `const
54 /// fn`s are available on stable Rust, this will no longer be necessary.
55 /// Thus, these fields are *not* considered stable public API, and they may
56 /// change warning. Do not rely on any fields on `Metadata`. When
57 /// constructing new `Metadata`, use the `metadata!` macro or the
58 /// `Metadata::new` constructor instead!
59 #[doc(hidden)]
60 pub target: &'a str,
61
62 /// The level of verbosity of the described span.
63 ///
64 /// **Warning**: The fields on this type are currently `pub` because it must
65 /// be able to be constructed statically by macros. However, when `const
66 /// fn`s are available on stable Rust, this will no longer be necessary.
67 /// Thus, these fields are *not* considered stable public API, and they may
68 /// change warning. Do not rely on any fields on `Metadata`. When
69 /// constructing new `Metadata`, use the `metadata!` macro or the
70 /// `Metadata::new` constructor instead!
71 #[doc(hidden)]
72 pub level: Level,
73
74 /// The name of the Rust module where the span occurred, or `None` if this
75 /// could not be determined.
76 ///
77 /// **Warning**: The fields on this type are currently `pub` because it must
78 /// be able to be constructed statically by macros. However, when `const
79 /// fn`s are available on stable Rust, this will no longer be necessary.
80 /// Thus, these fields are *not* considered stable public API, and they may
81 /// change warning. Do not rely on any fields on `Metadata`. When
82 /// constructing new `Metadata`, use the `metadata!` macro or the
83 /// `Metadata::new` constructor instead!
84 #[doc(hidden)]
85 pub module_path: Option<&'a str>,
86
87 /// The name of the source code file where the span occurred, or `None` if
88 /// this could not be determined.
89 ///
90 /// **Warning**: The fields on this type are currently `pub` because it must
91 /// be able to be constructed statically by macros. However, when `const
92 /// fn`s are available on stable Rust, this will no longer be necessary.
93 /// Thus, these fields are *not* considered stable public API, and they may
94 /// change warning. Do not rely on any fields on `Metadata`. When
95 /// constructing new `Metadata`, use the `metadata!` macro or the
96 /// `Metadata::new` constructor instead!
97 #[doc(hidden)]
98 pub file: Option<&'a str>,
99
100 /// The line number in the source code file where the span occurred, or
101 /// `None` if this could not be determined.
102 ///
103 /// **Warning**: The fields on this type are currently `pub` because it must
104 /// be able to be constructed statically by macros. However, when `const
105 /// fn`s are available on stable Rust, this will no longer be necessary.
106 /// Thus, these fields are *not* considered stable public API, and they may
107 /// change warning. Do not rely on any fields on `Metadata`. When
108 /// constructing new `Metadata`, use the `metadata!` macro or the
109 /// `Metadata::new` constructor instead!
110 #[doc(hidden)]
111 pub line: Option<u32>,
112
113 /// The names of the key-value fields attached to the described span or
114 /// event.
115 ///
116 /// **Warning**: The fields on this type are currently `pub` because it must
117 /// be able to be constructed statically by macros. However, when `const
118 /// fn`s are available on stable Rust, this will no longer be necessary.
119 /// Thus, these fields are *not* considered stable public API, and they may
120 /// change warning. Do not rely on any fields on `Metadata`. When
121 /// constructing new `Metadata`, use the `metadata!` macro or the
122 /// `Metadata::new` constructor instead!
123 #[doc(hidden)]
124 pub fields: field::FieldSet,
125
126 /// The kind of the callsite.
127 ///
128 /// **Warning**: The fields on this type are currently `pub` because it must
129 /// be able to be constructed statically by macros. However, when `const
130 /// fn`s are available on stable Rust, this will no longer be necessary.
131 /// Thus, these fields are *not* considered stable public API, and they may
132 /// change warning. Do not rely on any fields on `Metadata`. When
133 /// constructing new `Metadata`, use the `metadata!` macro or the
134 /// `Metadata::new` constructor instead!
135 #[doc(hidden)]
136 pub kind: Kind,
137}
138
139/// Indicate whether the callsite is a span or event.
140#[derive(Clone, Debug, Eq, PartialEq)]
141pub struct Kind(KindInner);
142
143/// Describes the level of verbosity of a span or event.
144#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
145pub struct Level(LevelInner);
146
147// ===== impl Metadata =====
148
149impl<'a> Metadata<'a> {
150 /// Construct new metadata for a span, with a name, target, level, field
151 /// names, and optional source code location.
152 pub fn new(
153 name: &'static str,
154 target: &'a str,
155 level: Level,
156 module_path: Option<&'a str>,
157 file: Option<&'a str>,
158 line: Option<u32>,
159 field_names: &'static [&'static str],
160 callsite: &'static Callsite,
161 kind: Kind,
162 ) -> Self {
163 Metadata {
164 name,
165 target,
166 level,
167 module_path,
168 file,
169 line,
170 fields: field::FieldSet {
171 names: field_names,
172 callsite: callsite::Identifier(callsite),
173 },
174 kind,
175 }
176 }
177
178 /// Returns the set of fields on the described span.
179 pub fn fields(&self) -> &field::FieldSet {
180 &self.fields
181 }
182
183 /// Returns the level of verbosity of the described span.
184 pub fn level(&self) -> &Level {
185 &self.level
186 }
187
188 /// Returns the name of the span.
189 pub fn name(&self) -> &'static str {
190 self.name
191 }
192
193 /// Returns a string describing the part of the system where the span or
194 /// event that this metadata describes occurred.
195 ///
196 /// Typically, this is the module path, but alternate targets may be set
197 /// when spans or events are constructed.
198 pub fn target(&self) -> &'a str {
199 self.target
200 }
201
202 /// Returns the path to the Rust module where the span occurred, or
203 /// `None` if the module path is unknown.
204 pub fn module_path(&self) -> Option<&'a str> {
205 self.module_path
206 }
207
208 /// Returns the name of the source code file where the span
209 /// occurred, or `None` if the file is unknown
210 pub fn file(&self) -> Option<&'a str> {
211 self.file
212 }
213
214 /// Returns the line number in the source code file where the span
215 /// occurred, or `None` if the line number is unknown.
216 pub fn line(&self) -> Option<u32> {
217 self.line
218 }
219
220 /// Returns an opaque `Identifier` that uniquely identifies the callsite
221 /// this `Metadata` originated from.
222 #[inline]
223 pub fn callsite(&self) -> callsite::Identifier {
224 self.fields.callsite()
225 }
226
227 /// Returns true if the callsite kind is `Event`.
228 pub fn is_event(&self) -> bool {
229 self.kind.is_event()
230 }
231
232 /// Return true if the callsite kind is `Span`.
233 pub fn is_span(&self) -> bool {
234 self.kind.is_span()
235 }
236}
237
238impl<'a> fmt::Debug for Metadata<'a> {
239 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
240 let mut meta = f.debug_struct("Metadata");
241 meta.field("name", &self.name)
242 .field("target", &self.target)
243 .field("level", &self.level);
244
245 if let Some(path) = self.module_path() {
246 meta.field("module_path", &path);
247 }
248
249 match (self.file(), self.line()) {
250 (Some(file), Some(line)) => {
251 meta.field("location", &format_args!("{}:{}", file, line));
252 }
253 (Some(file), None) => {
254 meta.field("file", &format_args!("{}", file));
255 }
256
257 // Note: a line num with no file is a kind of weird case that _probably_ never occurs...
258 (None, Some(line)) => {
259 meta.field("line", &line);
260 }
261 (None, None) => {}
262 };
263
264 meta.field("fields", &format_args!("{}", self.fields))
265 .field("callsite", &self.callsite())
266 .field("kind", &self.kind)
267 .finish()
268 }
269}
270
271#[derive(Clone, Debug, Eq, PartialEq)]
272enum KindInner {
273 Event,
274 Span,
275}
276
277impl Kind {
278 /// `Event` callsite
279 pub const EVENT: Kind = Kind(KindInner::Event);
280
281 /// `Span` callsite
282 pub const SPAN: Kind = Kind(KindInner::Span);
283
284 /// Return true if the callsite kind is `Span`
285 pub fn is_span(&self) -> bool {
286 match self {
287 Kind(KindInner::Span) => true,
288 _ => false,
289 }
290 }
291
292 /// Return true if the callsite kind is `Event`
293 pub fn is_event(&self) -> bool {
294 match self {
295 Kind(KindInner::Event) => true,
296 _ => false,
297 }
298 }
299}
300
301// ===== impl Level =====
302
303impl Level {
304 /// The "error" level.
305 ///
306 /// Designates very serious errors.
307 pub const ERROR: Level = Level(LevelInner::Error);
308 /// The "warn" level.
309 ///
310 /// Designates hazardous situations.
311 pub const WARN: Level = Level(LevelInner::Warn);
312 /// The "info" level.
313 ///
314 /// Designates useful information.
315 pub const INFO: Level = Level(LevelInner::Info);
316 /// The "debug" level.
317 ///
318 /// Designates lower priority information.
319 pub const DEBUG: Level = Level(LevelInner::Debug);
320 /// The "trace" level.
321 ///
322 /// Designates very low priority, often extremely verbose, information.
323 pub const TRACE: Level = Level(LevelInner::Trace);
324}
325
326#[repr(usize)]
327#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
328enum LevelInner {
329 /// The "error" level.
330 ///
331 /// Designates very serious errors.
332 Error = 1,
333 /// The "warn" level.
334 ///
335 /// Designates hazardous situations.
336 Warn,
337 /// The "info" level.
338 ///
339 /// Designates useful information.
340 Info,
341 /// The "debug" level.
342 ///
343 /// Designates lower priority information.
344 Debug,
345 /// The "trace" level.
346 ///
347 /// Designates very low priority, often extremely verbose, information.
348 Trace,
349}