πŸ›ˆ Note: This is pre-release documentation for the upcoming tracing 0.2.0 ecosystem.

For the release documentation, please see docs.rs, instead.

tracing/
lib.rs

1//! A scoped, structured logging and diagnostics system.
2//!
3//! # Overview
4//!
5//! `tracing` is a framework for instrumenting Rust programs to collect
6//! structured, event-based diagnostic information.
7//!
8//! In asynchronous systems like Tokio, interpreting traditional log messages can
9//! often be quite challenging. Since individual tasks are multiplexed on the same
10//! thread, associated events and log lines are intermixed making it difficult to
11//! trace the logic flow. `tracing` expands upon logging-style diagnostics by
12//! allowing libraries and applications to record structured events with additional
13//! information about *temporality* and *causality* β€” unlike a log message, a span
14//! in `tracing` has a beginning and end time, may be entered and exited by the
15//! flow of execution, and may exist within a nested tree of similar spans. In
16//! addition, `tracing` spans are *structured*, with the ability to record typed
17//! data as well as textual messages.
18//!
19//! The `tracing` crate provides the APIs necessary for instrumenting libraries
20//! and applications to emit trace data.
21//!
22//! *Compiler support: [requires `rustc` 1.65+][msrv]*
23//!
24//! [msrv]: #supported-rust-versions
25//! # Core Concepts
26//!
27//! The core of `tracing`'s API is composed of _spans_, _events_ and
28//! _collectors_. We'll cover these in turn.
29//!
30//! ## Spans
31//!
32//! To record the flow of execution through a program, `tracing` introduces the
33//! concept of [spans]. Unlike a log line that represents a _moment in
34//! time_, a span represents a _period of time_ with a beginning and an end. When a
35//! program begins executing in a context or performing a unit of work, it
36//! _enters_ that context's span, and when it stops executing in that context,
37//! it _exits_ the span. The span in which a thread is currently executing is
38//! referred to as that thread's _current_ span.
39//!
40//! For example:
41//! ```
42//! use tracing::{span, Level};
43//! # fn main() {
44//! let span = span!(Level::TRACE, "my_span");
45//! // `enter` returns a RAII guard which, when dropped, exits the span. this
46//! // indicates that we are in the span for the current lexical scope.
47//! let _enter = span.enter();
48//! // perform some work in the context of `my_span`...
49//! # }
50//!```
51//!
52//! The [`span` module][mod@span]'s documentation provides further details on how to
53//! use spans.
54//!
55//! <div class="example-wrap" style="display:inline-block"><pre class="compile_fail" style="white-space:normal;font:inherit;">
56//!
57//!  **Warning**: In asynchronous code that uses async/await syntax,
58//!  `Span::enter` may produce incorrect traces if the returned drop
59//!  guard is held across an await point. See
60//!  [the method documentation][Span#in-asynchronous-code] for details.
61//!
62//! </pre></div>
63//!
64//! ## Events
65//!
66//! An [`Event`] represents a _moment_ in time. It signifies something that
67//! happened while a trace was being recorded. `Event`s are comparable to the log
68//! records emitted by unstructured logging code, but unlike a typical log line,
69//! an `Event` may occur within the context of a span.
70//!
71//! For example:
72//! ```
73//! use tracing::{event, span, Level};
74//!
75//! # fn main() {
76//! // records an event outside of any span context:
77//! event!(Level::INFO, "something happened");
78//!
79//! let span = span!(Level::INFO, "my_span");
80//! let _guard = span.enter();
81//!
82//! // records an event within "my_span".
83//! event!(Level::DEBUG, "something happened inside my_span");
84//! # }
85//!```
86//!
87//! In general, events should be used to represent points in time _within_ a
88//! span β€” a request returned with a given status code, _n_ new items were
89//! taken from a queue, and so on.
90//!
91//! The [`Event` struct][`Event`] documentation provides further details on using
92//! events.
93//!
94//! ## Collectors
95//!
96//! As `Span`s and `Event`s occur, they are recorded or aggregated by
97//! implementations of the [`Collect`] trait. Collectors are notified
98//! when an `Event` takes place and when a `Span` is entered or exited. These
99//! notifications are represented by the following `Collect` trait methods:
100//!
101//! + [`event`][Collect::event], called when an `Event` takes place,
102//! + [`enter`], called when execution enters a `Span`,
103//! + [`exit`], called when execution exits a `Span`
104//!
105//! In addition, collectors may implement the [`enabled`] function to _filter_
106//! the notifications they receive based on [metadata] describing each `Span`
107//! or `Event`. If a call to `Collect::enabled` returns `false` for a given
108//! set of metadata, that collector will *not* be notified about the
109//! corresponding `Span` or `Event`. For performance reasons, if no currently
110//! active collectors express interest in a given set of metadata by returning
111//! `true`, then the corresponding `Span` or `Event` will never be constructed.
112//!
113//! # Usage
114//!
115//! First, add this to your `Cargo.toml`:
116//!
117//! ```toml
118//! [dependencies]
119//! tracing = "0.1"
120//! ```
121//!
122//! ## Recording Spans and Events
123//!
124//! Spans and events are recorded using macros.
125//!
126//! ### Spans
127//!
128//! The [`span!`] macro expands to a [`Span` struct][`Span`] which is used to
129//! record a span. The [`Span::enter`] method on that struct records that the
130//! span has been entered, and returns a [RAII] guard object, which will exit
131//! the span when dropped.
132//!
133//! For example:
134//!
135//! ```rust
136//! use tracing::{span, Level};
137//! # fn main() {
138//! // Construct a new span named "my span" with trace log level.
139//! let span = span!(Level::TRACE, "my span");
140//!
141//! // Enter the span, returning a guard object.
142//! let _enter = span.enter();
143//!
144//! // Any trace events that occur before the guard is dropped will occur
145//! // within the span.
146//!
147//! // Dropping the guard will exit the span.
148//! # }
149//! ```
150//!
151//! The [`#[instrument]`][instrument] attribute provides an easy way to
152//! add `tracing` spans to functions. A function annotated with `#[instrument]`
153//! will create and enter a span with that function's name every time the
154//! function is called, with arguments to that function will be recorded as
155//! fields using `fmt::Debug`.
156//!
157//! For example:
158//! ```ignore
159//! # // this doctest is ignored because we don't have a way to say
160//! # // that it should only be run with cfg(feature = "attributes")
161//! use tracing::{Level, event, instrument};
162//!
163//! #[instrument]
164//! pub fn my_function(my_arg: usize) {
165//!     // This event will be recorded inside a span named `my_function` with the
166//!     // field `my_arg`.
167//!     event!(Level::INFO, "inside my_function!");
168//!     // ...
169//! }
170//! # fn main() {}
171//! ```
172//!
173//! For functions which don't have built-in tracing support and can't have
174//! the `#[instrument]` attribute applied (such as from an external crate),
175//! the [`Span` struct][`Span`] has a [`in_scope()` method][`in_scope`]
176//! which can be used to easily wrap synchronous code in a span.
177//!
178//! For example:
179//! ```rust
180//! use tracing::info_span;
181//!
182//! # fn doc() -> Result<(), ()> {
183//! # mod serde_json {
184//! #    pub(crate) fn from_slice(buf: &[u8]) -> Result<(), ()> { Ok(()) }
185//! # }
186//! # let buf: [u8; 0] = [];
187//! let json = info_span!("json.parse").in_scope(|| serde_json::from_slice(&buf))?;
188//! # let _ = json; // suppress unused variable warning
189//! # Ok(())
190//! # }
191//! ```
192//!
193//! You can find more examples showing how to use this crate [here][examples].
194//!
195//! [RAII]: https://github.com/rust-unofficial/patterns/blob/main/src/patterns/behavioural/RAII.md
196//! [examples]: https://github.com/tokio-rs/tracing/tree/master/examples
197//!
198//! ### Events
199//!
200//! [`Event`]s are recorded using the [`event!`] macro:
201//!
202//! ```rust
203//! # fn main() {
204//! use tracing::{event, Level};
205//! event!(Level::INFO, "something has happened!");
206//! # }
207//! ```
208//!
209//! ## Using the Macros
210//!
211//! The [`span!`] and [`event!`] macros use fairly similar syntax, with some
212//! exceptions.
213//!
214//! ### Configuring Attributes
215//!
216//! Both macros require a [`Level`] specifying the verbosity of the span or
217//! event. Optionally, the, [target] and [parent span] may be overridden. If the
218//! target and parent span are not overridden, they will default to the
219//! module path where the macro was invoked and the current span (as determined
220//! by the collector), respectively.
221//!
222//! For example:
223//!
224//! ```
225//! # use tracing::{span, event, Level};
226//! # fn main() {
227//! span!(target: "app_spans", Level::TRACE, "my span");
228//! event!(target: "app_events", Level::INFO, "something has happened!");
229//! # }
230//! ```
231//! ```
232//! # use tracing::{span, event, Level};
233//! # fn main() {
234//! let span = span!(Level::TRACE, "my span");
235//! event!(parent: &span, Level::INFO, "something has happened!");
236//! # }
237//! ```
238//!
239//! The span macros also take a string literal after the level, to set the name
240//! of the span (as above).  In the case of the event macros, the name of the event can
241//! be overridden (the default is `event file:line`) using the `name:` specifier.
242//!
243//! ```
244//! # use tracing::{span, event, Level};
245//! # fn main() {
246//! span!(Level::TRACE, "my span");
247//! event!(name: "some_info", Level::INFO, "something has happened!");
248//! # }
249//! ```
250//!
251//! ### Recording Fields
252//!
253//! Structured fields on spans and events are specified using the syntax
254//! `field_name = field_value`. Fields are separated by commas.
255//!
256//! ```
257//! # use tracing::{event, Level};
258//! # fn main() {
259//! // records an event with two fields:
260//! //  - "answer", with the value 42
261//! //  - "question", with the value "life, the universe and everything"
262//! event!(Level::INFO, answer = 42, question = "life, the universe, and everything");
263//! # }
264//! ```
265//!
266//! As shorthand, local variables may be used as field values without an
267//! assignment, similar to [struct initializers]. For example:
268//!
269//! ```
270//! # use tracing::{span, Level};
271//! # fn main() {
272//! let user = "ferris";
273//!
274//! span!(Level::TRACE, "login", user);
275//! // is equivalent to:
276//! span!(Level::TRACE, "login", user = user);
277//! # }
278//!```
279//!
280//! Field names can include dots, but should not be terminated by them:
281//! ```
282//! # use tracing::{span, Level};
283//! # fn main() {
284//! let user = "ferris";
285//! let email = "ferris@rust-lang.org";
286//! span!(Level::TRACE, "login", user, user.email = email);
287//! # }
288//!```
289//!
290//! Since field names can include dots, fields on local structs can be used
291//! using the local variable shorthand:
292//! ```
293//! # use tracing::{span, Level};
294//! # fn main() {
295//! # struct User {
296//! #    name: &'static str,
297//! #    email: &'static str,
298//! # }
299//! let user = User {
300//!     name: "ferris",
301//!     email: "ferris@rust-lang.org",
302//! };
303//! // the span will have the fields `user.name = "ferris"` and
304//! // `user.email = "ferris@rust-lang.org"`.
305//! span!(Level::TRACE, "login", user.name, user.email);
306//! # }
307//!```
308//!
309//! Fields with names that are not Rust identifiers, or with names that are Rust reserved words,
310//! may be created using quoted string literals. However, this may not be used with the local
311//! variable shorthand.
312//! ```
313//! # use tracing::{span, Level};
314//! # fn main() {
315//! // records an event with fields whose names are not Rust identifiers
316//! //  - "guid:x-request-id", containing a `:`, with the value "abcdef"
317//! //  - "type", which is a reserved word, with the value "request"
318//! span!(Level::TRACE, "api", "guid:x-request-id" = "abcdef", "type" = "request");
319//! # }
320//!```
321//!
322//! Constant expressions can also be used as field names. Constants
323//! must be enclosed in curly braces (`{}`) to indicate that the *value*
324//! of the constant is to be used as the field name, rather than the
325//! constant's name. For example:
326//! ```
327//! # use tracing::{span, Level};
328//! # fn main() {
329//! const RESOURCE_NAME: &str = "foo";
330//! // this span will have the field `foo = "some_id"`
331//! span!(Level::TRACE, "get", { RESOURCE_NAME } = "some_id");
332//! # }
333//!```
334//!
335//! The `?` sigil is shorthand that specifies a field should be recorded using
336//! its [`fmt::Debug`] implementation:
337//! ```
338//! # use tracing::{event, Level};
339//! # fn main() {
340//! #[derive(Debug)]
341//! struct MyStruct {
342//!     field: &'static str,
343//! }
344//!
345//! let my_struct = MyStruct {
346//!     field: "Hello world!"
347//! };
348//!
349//! // `my_struct` will be recorded using its `fmt::Debug` implementation.
350//! event!(Level::TRACE, greeting = ?my_struct);
351//! // is equivalent to:
352//! event!(Level::TRACE, greeting = tracing::field::debug(&my_struct));
353//! # }
354//! ```
355//!
356//! The `%` sigil operates similarly, but indicates that the value should be
357//! recorded using its [`fmt::Display`] implementation:
358//! ```
359//! # use tracing::{event, Level};
360//! # fn main() {
361//! # #[derive(Debug)]
362//! # struct MyStruct {
363//! #     field: &'static str,
364//! # }
365//! #
366//! # let my_struct = MyStruct {
367//! #     field: "Hello world!"
368//! # };
369//! // `my_struct.field` will be recorded using its `fmt::Display` implementation.
370//! event!(Level::TRACE, greeting = %my_struct.field);
371//! // is equivalent to:
372//! event!(Level::TRACE, greeting = tracing::field::display(&my_struct.field));
373//! # }
374//! ```
375//!
376//! The `%` and `?` sigils may also be used with local variable shorthand:
377//!
378//! ```
379//! # use tracing::{event, Level};
380//! # fn main() {
381//! # #[derive(Debug)]
382//! # struct MyStruct {
383//! #     field: &'static str,
384//! # }
385//! #
386//! # let my_struct = MyStruct {
387//! #     field: "Hello world!"
388//! # };
389//! // `my_struct.field` will be recorded using its `fmt::Display` implementation.
390//! event!(Level::TRACE, %my_struct.field);
391//! # }
392//! ```
393//!
394//! Additionally, a span may declare fields with the special value [`Empty`],
395//! which indicates that that the value for that field does not currently exist
396//! but may be recorded later. For example:
397//!
398//! ```
399//! use tracing::{trace_span, field};
400//!
401//! // Create a span with two fields: `greeting`, with the value "hello world", and
402//! // `parting`, without a value.
403//! let span = trace_span!("my_span", greeting = "hello world", parting = field::Empty);
404//!
405//! // ...
406//!
407//! // Now, record a value for parting as well.
408//! span.record("parting", &"goodbye world!");
409//! ```
410//!
411//! Finally, events may also include human-readable messages, in the form of a
412//! [format string][fmt] and (optional) arguments, **after** the event's
413//! key-value fields. If a format string and arguments are provided,
414//! they will implicitly create a new field named `message` whose value is the
415//! provided set of format arguments.
416//!
417//! For example:
418//!
419//! ```
420//! # use tracing::{event, Level};
421//! # fn main() {
422//! let question = "the ultimate question of life, the universe, and everything";
423//! let answer = 42;
424//! // records an event with the following fields:
425//! // - `question.answer` with the value 42,
426//! // - `question.tricky` with the value `true`,
427//! // - "message", with the value "the answer to the ultimate question of life, the
428//! //    universe, and everything is 42."
429//! event!(
430//!     Level::DEBUG,
431//!     question.answer = answer,
432//!     question.tricky = true,
433//!     "the answer to {} is {}.", question, answer
434//! );
435//! # }
436//! ```
437//!
438//! Specifying a formatted message in this manner does not allocate by default.
439//!
440//! [struct initializers]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html#using-the-field-init-shorthand-when-variables-and-fields-have-the-same-name
441//! [target]: Metadata::target()
442//! [parent span]: span::Attributes::parent()
443//! [determined contextually]: span::Attributes::is_contextual()
444//! [`fmt::Debug`]: std::fmt::Debug
445//! [`fmt::Display`]: std::fmt::Display
446//! [fmt]: std::fmt#usage
447//! [`Empty`]: field::Empty
448//!
449//! ### Shorthand Macros
450//!
451//! `tracing` also offers a number of macros with preset verbosity levels.
452//! The [`trace!`], [`debug!`], [`info!`], [`warn!`], and [`error!`] behave
453//! similarly to the [`event!`] macro, but with the [`Level`] argument already
454//! specified, while the corresponding [`trace_span!`], [`debug_span!`],
455//! [`info_span!`], [`warn_span!`], and [`error_span!`] macros are the same,
456//! but for the [`span!`] macro.
457//!
458//! These are intended both as a shorthand, and for compatibility with the [`log`]
459//! crate (see the next section).
460//!
461//! [`span!`]: span!
462//! [`event!`]: event!
463//! [`trace!`]: trace!
464//! [`debug!`]: debug!
465//! [`info!`]: info!
466//! [`warn!`]: warn!
467//! [`error!`]: error!
468//! [`trace_span!`]: trace_span!
469//! [`debug_span!`]: debug_span!
470//! [`info_span!`]: info_span!
471//! [`warn_span!`]: warn_span!
472//! [`error_span!`]: error_span!
473//!
474//! ### For `log` Users
475//!
476//! Users of the [`log`] crate should note that `tracing` exposes a set of
477//! macros for creating `Event`s (`trace!`, `debug!`, `info!`, `warn!`, and
478//! `error!`) which may be invoked with the same syntax as the similarly-named
479//! macros from the `log` crate. Often, the process of converting a project to
480//! use `tracing` can begin with a simple drop-in replacement.
481//!
482//! Let's consider the `log` crate's yak-shaving example:
483//!
484//! ```rust,ignore
485//! use std::{error::Error, io};
486//! use tracing::{debug, error, info, span, warn, Level};
487//!
488//! // the `#[tracing::instrument]` attribute creates and enters a span
489//! // every time the instrumented function is called. The span is named after
490//! // the function or method. Parameters passed to the function are recorded as fields.
491//! #[tracing::instrument]
492//! pub fn shave(yak: usize) -> Result<(), Box<dyn Error + 'static>> {
493//!     // this creates an event at the DEBUG level with two fields:
494//!     // - `excitement`, with the key "excitement" and the value "yay!"
495//!     // - `message`, with the key "message" and the value "hello! I'm gonna shave a yak."
496//!     //
497//!     // unlike other fields, `message`'s shorthand initialization is just the string itself.
498//!     debug!(excitement = "yay!", "hello! I'm gonna shave a yak.");
499//!     if yak == 3 {
500//!         warn!("could not locate yak!");
501//!         // note that this is intended to demonstrate `tracing`'s features, not idiomatic
502//!         // error handling! in a library or application, you should consider returning
503//!         // a dedicated `YakError`. libraries like snafu or thiserror make this easy.
504//!         return Err(io::Error::new(io::ErrorKind::Other, "shaving yak failed!").into());
505//!     } else {
506//!         debug!("yak shaved successfully");
507//!     }
508//!     Ok(())
509//! }
510//!
511//! pub fn shave_all(yaks: usize) -> usize {
512//!     // Constructs a new span named "shaving_yaks" at the TRACE level,
513//!     // and a field whose key is "yaks". This is equivalent to writing:
514//!     //
515//!     // let span = span!(Level::TRACE, "shaving_yaks", yaks = yaks);
516//!     //
517//!     // local variables (`yaks`) can be used as field values
518//!     // without an assignment, similar to struct initializers.
519//!     let span = span!(Level::TRACE, "shaving_yaks", yaks);
520//!     let _enter = span.enter();
521//!
522//!     info!("shaving yaks");
523//!
524//!     let mut yaks_shaved = 0;
525//!     for yak in 1..=yaks {
526//!         let res = shave(yak);
527//!         debug!(yak, shaved = res.is_ok());
528//!
529//!         if let Err(ref error) = res {
530//!             // Like spans, events can also use the field initialization shorthand.
531//!             // In this instance, `yak` is the field being initialized.
532//!             error!(yak, error = error.as_ref(), "failed to shave yak!");
533//!         } else {
534//!             yaks_shaved += 1;
535//!         }
536//!         debug!(yaks_shaved);
537//!     }
538//!
539//!     yaks_shaved
540//! }
541//! ```
542//!
543//! ## In libraries
544//!
545//! Libraries should link only to the `tracing` crate, and use the provided
546//! macros to record whatever information will be useful to downstream
547//! consumers.
548//!
549//! ## In executables
550//!
551//! In order to record trace events, executables have to use a collector
552//! implementation compatible with `tracing`. A collector implements a
553//! way of collecting trace data, such as by logging it to standard output.
554//!
555//! This library does not contain any `Collect` implementations; these are
556//! provided by [other crates](#related-crates).
557//!
558//! The simplest way to use a collector is to call the [`set_global_default`]
559//! function:
560//!
561//! ```
562//! # pub struct FooCollector;
563//! # use tracing::{span::{Id, Attributes, Record}, Metadata};
564//! # use tracing_core::span::Current;
565//! # impl tracing::Collect for FooCollector {
566//! #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
567//! #   fn record(&self, _: &Id, _: &Record) {}
568//! #   fn event(&self, _: &tracing::Event) {}
569//! #   fn record_follows_from(&self, _: &Id, _: &Id) {}
570//! #   fn enabled(&self, _: &Metadata) -> bool { false }
571//! #   fn enter(&self, _: &Id) {}
572//! #   fn exit(&self, _: &Id) {}
573//! #   fn current_span(&self) -> Current { Current::unknown() }
574//! # }
575//! # impl FooCollector {
576//! #   fn new() -> Self { FooCollector }
577//! # }
578//! # fn main() {
579//!
580//! # #[cfg(feature = "alloc")]
581//! let my_collector = FooCollector::new();
582//! # #[cfg(feature = "alloc")]
583//! tracing::collect::set_global_default(my_collector)
584//!     .expect("setting tracing default failed");
585//! # }
586//! ```
587//!
588//! <div class="information">
589//! </div><div class="example-wrap" style="display:inline-block"><pre class="compile_fail" style="white-space:normal;font:inherit;">
590//! <strong>Warning</strong>: In general, libraries should <em>not</em> call
591//! <code>set_global_default()</code>! Doing so will cause conflicts when
592//! executables that depend on the library try to set the default later.
593//! </pre></div>
594//!
595//! This collector will be used as the default in all threads for the
596//! remainder of the duration of the program, similar to setting the logger
597//! in the `log` crate.
598//!
599//! In addition, the default collector can be set through using the
600//! [`with_default`] function. This follows the `tokio` pattern of using
601//! closures to represent executing code in a context that is exited at the end
602//! of the closure. For example:
603//!
604//! ```rust
605//! # pub struct FooCollector;
606//! # use tracing::{span::{Id, Attributes, Record}, Metadata};
607//! # use tracing_core::span::Current;
608//! # impl tracing::Collect for FooCollector {
609//! #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
610//! #   fn record(&self, _: &Id, _: &Record) {}
611//! #   fn event(&self, _: &tracing::Event) {}
612//! #   fn record_follows_from(&self, _: &Id, _: &Id) {}
613//! #   fn enabled(&self, _: &Metadata) -> bool { false }
614//! #   fn enter(&self, _: &Id) {}
615//! #   fn exit(&self, _: &Id) {}
616//! #   fn current_span(&self) -> Current { Current::unknown() }
617//! # }
618//! # impl FooCollector {
619//! #   fn new() -> Self { FooCollector }
620//! # }
621//! # fn main() {
622//!
623//! let my_collector = FooCollector::new();
624//! # #[cfg(feature = "std")]
625//! tracing::collect::with_default(my_collector, || {
626//!     // Any trace events generated in this closure or by functions it calls
627//!     // will be collected by `my_collector`.
628//! })
629//! # }
630//! ```
631//!
632//! This approach allows trace data to be collected by multiple collectors
633//! within different contexts in the program. Note that the override only applies to the
634//! currently executing thread; other threads will not see the change from with_default.
635//!
636//! Any trace events generated outside the context of a collector will not be collected.
637//!
638//! Once a collector has been set, instrumentation points may be added to the
639//! executable using the `tracing` crate's macros.
640//!
641//! ## `log` Compatibility
642//!
643//! The [`log`] crate provides a simple, lightweight logging facade for Rust.
644//! While `tracing` builds upon `log`'s foundation with richer structured
645//! diagnostic data, `log`'s simplicity and ubiquity make it the "lowest common
646//! denominator" for text-based logging in Rust β€” a vast majority of Rust
647//! libraries and applications either emit or consume `log` records. Therefore,
648//! `tracing` provides multiple forms of interoperability with `log`: `tracing`
649//! instrumentation can emit `log` records, and a compatibility layer enables
650//! `tracing` [`Collect`]s to consume `log` records as `tracing` [`Event`]s.
651//!
652//! ### Emitting `log` Records
653//!
654//! This crate provides two feature flags, "log" and "log-always", which will
655//! cause [spans] and [events] to emit `log` records. When the "log" feature is
656//! enabled, if no `tracing` collector is active, invoking an event macro or
657//! creating a span with fields will emit a `log` record. This is intended
658//! primarily for use in libraries which wish to emit diagnostics that can be
659//! consumed by applications using `tracing` *or* `log`, without paying the
660//! additional overhead of emitting both forms of diagnostics when `tracing` is
661//! in use.
662//!
663//! Enabling the "log-always" feature will cause `log` records to be emitted
664//! even if a `tracing` collector _is_ set. This is intended to be used in
665//! applications where a `log` `Logger` is being used to record a textual log,
666//! and `tracing` is used only to record other forms of diagnostics (such as
667//! metrics, profiling, or distributed tracing data). Unlike the "log" feature,
668//! libraries generally should **not** enable the "log-always" feature, as doing
669//! so will prevent applications from being able to opt out of the `log` records.
670//!
671//! See [here][flags] for more details on this crate's feature flags.
672//!
673//! The generated `log` records' messages will be a string representation of the
674//! span or event's fields, and all additional information recorded by `log`
675//! (target, verbosity level, module path, file, and line number) will also be
676//! populated. Additionally, `log` records are also generated when spans are
677//! entered, exited, and closed. Since these additional span lifecycle logs have
678//! the potential to be very verbose, and don't include additional fields, they
679//! will always be emitted at the `Trace` level, rather than inheriting the
680//! level of the span that generated them. Furthermore, they are categorized
681//! under a separate `log` target, "tracing::span" (and its sub-target,
682//! "tracing::span::active", for the logs on entering and exiting a span), which
683//! may be enabled or disabled separately from other `log` records emitted by
684//! `tracing`.
685//!
686//! ### Consuming `log` Records
687//!
688//! The [`tracing-log`] crate provides a compatibility layer which
689//! allows a `tracing` collector to consume `log` records as though they
690//! were `tracing` [events]. This allows applications using `tracing` to record
691//! the logs emitted by dependencies using `log` as events within the context of
692//! the application's trace tree. See [that crate's documentation][log-tracer]
693//! for details.
694//!
695//! [log-tracer]: https://docs.rs/tracing-log/latest/tracing_log/#convert-log-records-to-tracing-events
696//!
697//! ### `no_std` Support
698//!
699//! In embedded systems and other bare-metal applications, `tracing` can be
700//! used without requiring the Rust standard library, although some features are
701//! disabled.
702//!
703//! The dependency on the standard library is controlled by two crate feature
704//! flags, "std", which enables the dependency on [`libstd`], and "alloc", which
705//! enables the dependency on [`liballoc`] (and is enabled by the "std"
706//! feature). These features are enabled by default, but `no_std` users can
707//! disable them using:
708//!
709//! ```toml
710//! # Cargo.toml
711//! tracing = { version = "0.2", default-features = false }
712//! ```
713//!
714//! To enable `liballoc` but not `std`, use:
715//!
716//! ```toml
717//! # Cargo.toml
718//! tracing = { version = "0.2", default-features = false, features = ["alloc"] }
719//! ```
720//!
721//! When both the "std" and "alloc" feature flags are disabled, `tracing-core`
722//! will not make any dynamic memory allocations at runtime, and does not
723//! require a global memory allocator.
724//!
725//! The "alloc" feature is required to enable the [`Dispatch::new`] function,
726//! which requires dynamic memory allocation to construct a collect trait
727//! object at runtime. When liballoc is disabled, new `Dispatch`s may still be
728//! created from `&'static dyn Collector` references, using
729//! [`Dispatch::from_static`].
730//!
731//! The "std" feature is required to enable the following features:
732//!
733//! * Per-thread scoped trace dispatchers ([`Dispatch::set_default`] and
734//!   [`with_default`]. Since setting a thread-local dispatcher inherently
735//!   requires a concept of threads to be available, this API is not possible
736//!   without the standard library.
737//! * Support for [constructing `Value`s from types implementing
738//!   `std::error::Error`][err]. Since the `Error` trait is defined in `std`,
739//!   it's not possible to provide this feature without `std`.
740//!
741//! All other features of `tracing` should behave identically with and
742//! without `std` and `alloc`.
743//!
744//! [`libstd`]: std
745//! [`Dispatch::new`]: crate::dispatch::Dispatch::new
746//! [`Dispatch::from_static`]: crate::dispatch::Dispatch::from_static
747//! [`Dispatch::set_default`]: crate::dispatch::set_default
748//! [`with_default`]: crate::dispatch::with_default
749//! [err]: crate::field::Visit::record_error
750//!
751//! ## Related Crates
752//!
753//! In addition to `tracing` and `tracing-core`, the [`tokio-rs/tracing`] repository
754//! contains several additional crates designed to be used with the `tracing` ecosystem.
755//! This includes a collection of `Collect` implementations, as well as utility
756//! and adapter crates to assist in writing collectors and instrumenting
757//! applications.
758//!
759//! In particular, the following crates are likely to be of interest:
760//!
761//!  - [`tracing-futures`] provides a compatibility layer with the `futures`
762//!    crate, allowing spans to be attached to `Future`s, `Stream`s, and `Executor`s.
763//!  - [`tracing-subscriber`] provides `tracing_subscriber::Subscribe` implementations and
764//!    utilities for working with collectors. This includes a [`FmtSubscriber`]
765//!    for logging formatted trace data to stdout, with similar
766//!    filtering and formatting to the [`env_logger`] crate.
767//!  - [`tracing-log`] provides a compatibility layer with the [`log`] crate,
768//!    allowing log messages to be recorded as `tracing` `Event`s within the
769//!    trace tree. This is useful when a project using `tracing` have
770//!    dependencies which use `log`. Note that if you're using
771//!    `tracing-subscriber`'s `FmtSubscriber`, you don't need to depend on
772//!    `tracing-log` directly.
773//!  - [`tracing-appender`] provides utilities for outputting tracing data,
774//!    including a file appender and non blocking writer.
775//!
776//! Additionally, there are also several third-party crates which are not
777//! maintained by the `tokio` project. These include:
778//!
779//!  - [`tracing-timing`] implements inter-event timing metrics on top of `tracing`.
780//!    It provides a subscriber that records the time elapsed between pairs of
781//!    `tracing` events and generates histograms.
782//!  - [`tracing-opentelemetry`] provides a subscriber for emitting traces to
783//!    [OpenTelemetry]-compatible distributed tracing systems.
784//!  - [`tracing-honeycomb`] Provides a layer that reports traces spanning multiple machines to [honeycomb.io]. Backed by [`tracing-distributed`].
785//!  - [`tracing-distributed`] Provides a generic implementation of a layer that reports traces spanning multiple machines to some backend.
786//!  - [`tracing-actix-web`] provides `tracing` integration for the `actix-web` web framework.
787//!  - [`tracing-actix`] provides `tracing` integration for the `actix` actor
788//!    framework.
789//!  - [`axum-insights`] provides `tracing` integration and Application insights export for the `axum` web framework.
790//!  - [`tracing-gelf`] implements a subscriber for exporting traces in Greylog
791//!    GELF format.
792//!  - [`tracing-coz`] provides integration with the [coz] causal profiler
793//!    (Linux-only).
794//!  - [`tracing-bunyan-formatter`] provides a layer implementation that reports events and spans
795//!    in [bunyan] format, enriched with timing information.
796//!  - [`tracing-wasm`] provides a `Collect`/`Subscribe` implementation that reports
797//!    events and spans via browser `console.log` and [User Timing API (`window.performance`)].
798//!  - [`tracing-web`] provides a layer implementation of level-aware logging of events
799//!    to web browsers' `console.*` and span events to the [User Timing API (`window.performance`)].
800//!  - [`tide-tracing`] provides a [tide] middleware to trace all incoming requests and responses.
801//!  - [`test-log`] takes care of initializing `tracing` for tests, based on
802//!    environment variables with an `env_logger` compatible syntax.
803//!  - [`tracing-unwrap`] provides convenience methods to report failed unwraps
804//!    on `Result` or `Option` types to a [`collect`].
805//!  - [`diesel-tracing`] provides integration with [`diesel`] database connections.
806//!  - [`tracing-tracy`] provides a way to collect [Tracy] profiles in instrumented
807//!    applications.
808//!  - [`tracing-elastic-apm`] provides a layer for reporting traces to [Elastic APM].
809//!  - [`tracing-etw`] provides a layer for emitting Windows [ETW] events.
810//!  - [`tracing-fluent-assertions`] provides a fluent assertions-style testing
811//!    framework for validating the behavior of `tracing` spans.
812//!  - [`sentry-tracing`] provides a layer for reporting events and traces to [Sentry].
813//!  - [`tracing-forest`] provides a subscriber that preserves contextual coherence by
814//!    grouping together logs from the same spans during writing.
815//!  - [`tracing-loki`] provides a layer for shipping logs to [Grafana Loki].
816//!  - [`tracing-logfmt`] provides a layer that formats events and spans into the logfmt format.
817//!  - [`reqwest-tracing`] provides a middleware to trace [`reqwest`] HTTP requests.
818//!  - [`tracing-cloudwatch`] provides a layer that sends events to AWS CloudWatch Logs.
819//!  - [`clippy-tracing`] provides a tool to add, remove and check for `tracing::instrument`.
820//!  - [`json-subscriber`] provides a subscriber for emitting JSON logs. The output can be customized much more than with [`tracing-subscriber`]'s JSON output.
821//!
822//! If you're the maintainer of a `tracing` ecosystem crate not listed above,
823//! please let us know! We'd love to add your project to the list!
824//!
825//! [`tracing-opentelemetry`]: https://crates.io/crates/tracing-opentelemetry
826//! [OpenTelemetry]: https://opentelemetry.io/
827//! [`tracing-honeycomb`]: https://crates.io/crates/tracing-honeycomb
828//! [`tracing-distributed`]: https://crates.io/crates/tracing-distributed
829//! [honeycomb.io]: https://www.honeycomb.io/
830//! [`tracing-actix-web`]: https://crates.io/crates/tracing-actix-web
831//! [`tracing-actix`]: https://crates.io/crates/tracing-actix
832//! [`axum-insights`]: https://crates.io/crates/axum-insights
833//! [`tracing-gelf`]: https://crates.io/crates/tracing-gelf
834//! [`tracing-coz`]: https://crates.io/crates/tracing-coz
835//! [coz]: https://github.com/plasma-umass/coz
836//! [`tracing-bunyan-formatter`]: https://crates.io/crates/tracing-bunyan-formatter
837//! [bunyan]: https://github.com/trentm/node-bunyan
838//! [`tracing-wasm`]: https://docs.rs/tracing-wasm
839//! [`tracing-web`]: https://docs.rs/tracing-web
840//! [User Timing API (`window.performance`)]: https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API
841//! [`tide-tracing`]: https://crates.io/crates/tide-tracing
842//! [tide]: https://crates.io/crates/tide
843//! [`test-log`]: https://crates.io/crates/test-log
844//! [`tracing-unwrap`]: https://docs.rs/tracing-unwrap
845//! [`diesel`]: https://crates.io/crates/diesel
846//! [`diesel-tracing`]: https://crates.io/crates/diesel-tracing
847//! [`tracing-tracy`]: https://crates.io/crates/tracing-tracy
848//! [Tracy]: https://github.com/wolfpld/tracy
849//! [`tracing-elastic-apm`]: https://crates.io/crates/tracing-elastic-apm
850//! [Elastic APM]: https://www.elastic.co/apm
851//! [`tracing-etw`]: https://github.com/microsoft/rust_win_etw/tree/main/win_etw_tracing
852//! [ETW]: https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing
853//! [`tracing-fluent-assertions`]: https://crates.io/crates/tracing-fluent-assertions
854//! [`sentry-tracing`]: https://crates.io/crates/sentry-tracing
855//! [Sentry]: https://sentry.io/welcome/
856//! [`tracing-forest`]: https://crates.io/crates/tracing-forest
857//! [`tracing-loki`]: https://crates.io/crates/tracing-loki
858//! [Grafana Loki]: https://grafana.com/oss/loki/
859//! [`tracing-logfmt`]: https://crates.io/crates/tracing-logfmt
860//! [`reqwest-tracing`]: https://crates.io/crates/reqwest-tracing
861//! [`reqwest`]: https://crates.io/crates/reqwest
862//! [`tracing-cloudwatch`]: https://crates.io/crates/tracing-cloudwatch
863//! [`clippy-tracing`]: https://crates.io/crates/clippy-tracing
864//! [`json-subscriber`]: https://crates.io/crates/json-subscriber
865//!
866//! <div class="example-wrap" style="display:inline-block">
867//! <pre class="ignore" style="white-space:normal;font:inherit;">
868//! <strong>Note</strong>: Some of these ecosystem crates are currently
869//! unreleased and/or in earlier stages of development. They may be less stable
870//! than <code>tracing</code> and <code>tracing-core</code>.
871//! </pre></div>
872//!
873//! ## Crate Feature Flags
874//!
875//! The following crate feature flags are available:
876//!
877//! * A set of features controlling the [static verbosity level].
878//! * `log`: causes trace instrumentation points to emit [`log`] records as well
879//!   as trace events, if a default `tracing` collector has not been set. This
880//!   is intended for use in libraries whose users may be using either `tracing`
881//!   or `log`.
882//! * `log-always`: Emit `log` records from all `tracing` spans and events, even
883//!   if a `tracing` collector has been set. This should be set only by
884//!   applications which intend to collect traces and logs separately; if an
885//!   adapter is used to convert `log` records into `tracing` events, this will
886//!   cause duplicate events to occur.
887//! * `attributes`: Includes support for the `#[instrument]` attribute.
888//!   This is on by default, but does bring in the `syn` crate as a dependency,
889//!   which may add to the compile time of crates that do not already use it.
890//! * `std`: Depend on the Rust standard library (enabled by default).
891//! * `alloc`: Depend on [`liballoc`] (enabled by "std").
892//!
893//! [`liballoc`]: https://doc.rust-lang.org/alloc/index.html
894//! ## Supported Rust Versions
895//!
896//! Tracing is built against the latest stable release. The minimum supported
897//! version is 1.65. The current Tracing version is not guaranteed to build on
898//! Rust versions earlier than the minimum supported version.
899//!
900//! Tracing follows the same compiler support policies as the rest of the Tokio
901//! project. The current stable Rust compiler and the three most recent minor
902//! versions before it will always be supported. For example, if the current
903//! stable compiler version is 1.69, the minimum supported version will not be
904//! increased past 1.66, three minor versions prior. Increasing the minimum
905//! supported compiler version is not considered a semver breaking change as
906//! long as doing so complies with this policy.
907//!
908//! [`log`]: https://docs.rs/log/0.4.6/log/
909//! [spans]: mod@span
910//! [`Span`]: span::Span
911//! [`in_scope`]: span::Span::in_scope
912//! [event]: Event
913//! [events]: Event
914//! [`collect`]: collect::Collect
915//! [Collect::event]: fn@collect::Collect::event
916//! [`enter`]: collect::Collect::enter
917//! [`exit`]: collect::Collect::exit
918//! [`enabled`]: collect::Collect::enabled
919//! [metadata]: Metadata
920//! [`set_global_default`]: collect::set_global_default
921//! [`with_default`]: collect::with_default
922//! [`tokio-rs/tracing`]: https://github.com/tokio-rs/tracing
923//! [`tracing-futures`]: https://crates.io/crates/tracing-futures
924//! [`tracing-subscriber`]: https://crates.io/crates/tracing-subscriber
925//! [`tracing-log`]: https://crates.io/crates/tracing-log
926//! [`tracing-timing`]: https://crates.io/crates/tracing-timing
927//! [`tracing-appender`]: https://crates.io/crates/tracing-appender
928//! [`env_logger`]: https://crates.io/crates/env_logger
929//! [`FmtSubscriber`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/struct.Subscriber.html
930//! [static verbosity level]: level_filters#compile-time-filters
931//! [instrument]: tracing_attributes::instrument
932//! [flags]: #crate-feature-flags
933#![cfg_attr(not(feature = "std"), no_std)]
934#![cfg_attr(docsrs, feature(doc_cfg))]
935#![doc(
936    html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
937    html_favicon_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/favicon.ico",
938    issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
939)]
940#![warn(
941    missing_debug_implementations,
942    missing_docs,
943    rust_2018_idioms,
944    unreachable_pub,
945    bad_style,
946    dead_code,
947    improper_ctypes,
948    non_shorthand_field_patterns,
949    no_mangle_generic_items,
950    overflowing_literals,
951    path_statements,
952    patterns_in_fns_without_body,
953    private_interfaces,
954    private_bounds,
955    unconditional_recursion,
956    unused,
957    unused_allocation,
958    unused_comparisons,
959    unused_parens,
960    while_true
961)]
962
963// Somehow this `use` statement is necessary for us to re-export the `core`
964// macros on Rust 1.26.0. I'm not sure how this makes it work, but it does.
965#[allow(unused_imports)]
966#[doc(hidden)]
967use tracing_core::*;
968
969#[doc(inline)]
970pub use self::instrument::Instrument;
971pub use self::{collect::Collect, dispatch::Dispatch, event::Event, field::Value};
972
973#[doc(hidden)]
974pub use self::span::Id;
975
976#[doc(hidden)]
977pub use tracing_core::{
978    callsite::{self, Callsite},
979    metadata,
980};
981pub use tracing_core::{event, Level, Metadata};
982
983#[doc(inline)]
984pub use self::span::Span;
985#[cfg(feature = "attributes")]
986#[cfg_attr(docsrs, doc(cfg(feature = "attributes")))]
987#[doc(inline)]
988pub use tracing_attributes::instrument;
989
990#[macro_use]
991mod macros;
992
993pub mod collect;
994pub mod dispatch;
995pub mod field;
996/// Attach a span to a `std::future::Future`.
997pub mod instrument;
998pub mod level_filters;
999pub mod span;
1000
1001#[doc(hidden)]
1002pub mod __macro_support {
1003    pub use crate::callsite::{Callsite, Registration};
1004    use crate::{collect::Interest, Metadata};
1005    use core::sync::atomic::Ordering;
1006    use core::{fmt, str};
1007
1008    #[cfg(feature = "portable-atomic")]
1009    use portable_atomic::AtomicU8;
1010
1011    #[cfg(not(feature = "portable-atomic"))]
1012    use core::sync::atomic::AtomicU8;
1013
1014    // Re-export the `core` functions that are used in macros. This allows
1015    // a crate to be named `core` and avoid name clashes.
1016    // See here: https://github.com/tokio-rs/tracing/issues/2761
1017    pub use core::{concat, file, format_args, iter::Iterator, line, option::Option, stringify};
1018
1019    /// Callsite implementation used by macro-generated code.
1020    ///
1021    /// /!\ WARNING: This is *not* a stable API! /!\
1022    /// This type, and all code contained in the `__macro_support` module, is
1023    /// a *private* API of `tracing`. It is exposed publicly because it is used
1024    /// by the `tracing` macros, but it is not part of the stable versioned API.
1025    /// Breaking changes to this module may occur in small-numbered versions
1026    /// without warning.
1027    pub struct MacroCallsite<T = &'static dyn Callsite>
1028    where
1029        T: 'static,
1030    {
1031        interest: AtomicU8,
1032        register: AtomicU8,
1033        meta: &'static Metadata<'static>,
1034        registration: &'static Registration<T>,
1035    }
1036
1037    impl<T: 'static> MacroCallsite<T> {
1038        /// Returns a new `MacroCallsite` with the specified `Metadata`.
1039        ///
1040        /// /!\ WARNING: This is *not* a stable API! /!\
1041        /// This method, and all code contained in the `__macro_support` module, is
1042        /// a *private* API of `tracing`. It is exposed publicly because it is used
1043        /// by the `tracing` macros, but it is not part of the stable versioned API.
1044        /// Breaking changes to this module may occur in small-numbered versions
1045        /// without warning.
1046        pub const fn new(
1047            meta: &'static Metadata<'static>,
1048            registration: &'static Registration<T>,
1049        ) -> Self {
1050            Self {
1051                interest: AtomicU8::new(Self::INTEREST_EMPTY),
1052                register: AtomicU8::new(Self::UNREGISTERED),
1053                meta,
1054                registration,
1055            }
1056        }
1057
1058        const UNREGISTERED: u8 = 0;
1059        const REGISTERING: u8 = 1;
1060        const REGISTERED: u8 = 2;
1061
1062        const INTEREST_NEVER: u8 = 0;
1063        const INTEREST_SOMETIMES: u8 = 1;
1064        const INTEREST_ALWAYS: u8 = 2;
1065        const INTEREST_EMPTY: u8 = 0xFF;
1066    }
1067
1068    impl MacroCallsite<&'static dyn Callsite> {
1069        /// Registers this callsite with the global callsite registry.
1070        ///
1071        /// If the callsite is already registered, this does nothing.
1072        ///
1073        /// /!\ WARNING: This is *not* a stable API! /!\
1074        /// This method, and all code contained in the `__macro_support` module, is
1075        /// a *private* API of `tracing`. It is exposed publicly because it is used
1076        /// by the `tracing` macros, but it is not part of the stable versioned API.
1077        /// Breaking changes to this module may occur in small-numbered versions
1078        /// without warning.
1079        #[inline(never)]
1080        // This only happens once (or if the cached interest value was corrupted).
1081        #[cold]
1082        pub fn register(&'static self) -> Interest {
1083            // Attempt to advance the registration state to `REGISTERING`...
1084            match self.register.compare_exchange(
1085                Self::UNREGISTERED,
1086                Self::REGISTERING,
1087                Ordering::AcqRel,
1088                Ordering::Acquire,
1089            ) {
1090                Ok(_) => {
1091                    // Okay, we advanced the state, try to register the callsite.
1092                    crate::callsite::register(self.registration);
1093                    self.register.store(Self::REGISTERED, Ordering::Release);
1094                }
1095                // Great, the callsite is already registered! Just load its
1096                // previous cached interest.
1097                Err(Self::REGISTERED) => {}
1098                // Someone else is registering...
1099                Err(_state) => {
1100                    debug_assert_eq!(
1101                        _state,
1102                        Self::REGISTERING,
1103                        "weird callsite registration state"
1104                    );
1105                    // Just hit `enabled` this time.
1106                    return Interest::sometimes();
1107                }
1108            }
1109
1110            match self.interest.load(Ordering::Relaxed) {
1111                Self::INTEREST_NEVER => Interest::never(),
1112                Self::INTEREST_ALWAYS => Interest::always(),
1113                _ => Interest::sometimes(),
1114            }
1115        }
1116
1117        /// Returns the callsite's cached Interest, or registers it for the
1118        /// first time if it has not yet been registered.
1119        ///
1120        /// /!\ WARNING: This is *not* a stable API! /!\
1121        /// This method, and all code contained in the `__macro_support` module, is
1122        /// a *private* API of `tracing`. It is exposed publicly because it is used
1123        /// by the `tracing` macros, but it is not part of the stable versioned API.
1124        /// Breaking changes to this module may occur in small-numbered versions
1125        /// without warning.
1126        #[inline]
1127        pub fn interest(&'static self) -> Interest {
1128            match self.interest.load(Ordering::Relaxed) {
1129                Self::INTEREST_NEVER => Interest::never(),
1130                Self::INTEREST_SOMETIMES => Interest::sometimes(),
1131                Self::INTEREST_ALWAYS => Interest::always(),
1132                _ => self.register(),
1133            }
1134        }
1135
1136        pub fn is_enabled(&self, interest: Interest) -> bool {
1137            interest.is_always()
1138                || crate::dispatch::get_default(|default| default.enabled(self.meta))
1139        }
1140
1141        #[inline]
1142        #[cfg(feature = "log")]
1143        pub fn disabled_span(&self) -> crate::Span {
1144            crate::Span::new_disabled(self.meta)
1145        }
1146
1147        #[inline]
1148        #[cfg(not(feature = "log"))]
1149        pub fn disabled_span(&self) -> crate::Span {
1150            crate::Span::none()
1151        }
1152
1153        #[cfg(feature = "log")]
1154        pub fn log(
1155            &self,
1156            logger: &'static dyn log::Log,
1157            log_meta: log::Metadata<'_>,
1158            values: &tracing_core::field::ValueSet<'_>,
1159        ) {
1160            let meta = self.metadata();
1161            logger.log(
1162                &crate::log::Record::builder()
1163                    .file(meta.file())
1164                    .module_path(meta.module_path())
1165                    .line(meta.line())
1166                    .metadata(log_meta)
1167                    .args(format_args!(
1168                        "{}",
1169                        crate::log::LogValueSet {
1170                            values,
1171                            is_first: true
1172                        }
1173                    ))
1174                    .build(),
1175            );
1176        }
1177    }
1178
1179    impl Callsite for MacroCallsite {
1180        fn set_interest(&self, interest: Interest) {
1181            let interest = match () {
1182                _ if interest.is_never() => 0,
1183                _ if interest.is_always() => 2,
1184                _ => 1,
1185            };
1186            self.interest.store(interest, Ordering::SeqCst);
1187        }
1188
1189        #[inline(always)]
1190        fn metadata(&self) -> &Metadata<'static> {
1191            self.meta
1192        }
1193    }
1194
1195    impl fmt::Debug for MacroCallsite {
1196        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1197            f.debug_struct("MacroCallsite")
1198                .field("interest", &self.interest)
1199                .field("meta", &self.meta)
1200                .field("register", &self.register)
1201                .field("registration", &self.registration)
1202                .finish()
1203        }
1204    }
1205
1206    /// Implementation detail used for constructing FieldSet names from raw
1207    /// identifiers. In `info!(..., r#type = "...")` the macro would end up
1208    /// constructing a name equivalent to `FieldName(*b"type")`.
1209    pub struct FieldName<const N: usize>([u8; N]);
1210
1211    impl<const N: usize> FieldName<N> {
1212        /// Convert `"prefix.r#keyword.suffix"` to `b"prefix.keyword.suffix"`.
1213        pub const fn new(input: &str) -> Self {
1214            let input = input.as_bytes();
1215            let mut output = [0u8; N];
1216            let mut read = 0;
1217            let mut write = 0;
1218            while read < input.len() {
1219                if read + 1 < input.len() && input[read] == b'r' && input[read + 1] == b'#' {
1220                    read += 2;
1221                }
1222                output[write] = input[read];
1223                read += 1;
1224                write += 1;
1225            }
1226            assert!(write == N);
1227            Self(output)
1228        }
1229
1230        pub const fn as_str(&self) -> &str {
1231            // SAFETY: Because of the private visibility of self.0, it must have
1232            // been computed by Self::new. So these bytes are all of the bytes
1233            // of some original valid UTF-8 string, but with "r#" substrings
1234            // removed, which cannot have produced invalid UTF-8.
1235            unsafe { str::from_utf8_unchecked(self.0.as_slice()) }
1236        }
1237    }
1238
1239    impl FieldName<0> {
1240        /// For `"prefix.r#keyword.suffix"` compute `"prefix.keyword.suffix".len()`.
1241        pub const fn len(input: &str) -> usize {
1242            // Count occurrences of "r#"
1243            let mut raw = 0;
1244
1245            let mut i = 0;
1246            while i < input.len() {
1247                if input.as_bytes()[i] == b'#' {
1248                    raw += 1;
1249                }
1250                i += 1;
1251            }
1252
1253            input.len() - 2 * raw
1254        }
1255    }
1256
1257    impl<const N: usize> fmt::Debug for FieldName<N> {
1258        fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1259            formatter
1260                .debug_tuple("FieldName")
1261                .field(&self.as_str())
1262                .finish()
1263        }
1264    }
1265}
1266
1267#[cfg(feature = "log")]
1268#[doc(hidden)]
1269pub mod log {
1270    use core::fmt;
1271    pub use log::*;
1272    use tracing_core::field::{Field, ValueSet, Visit};
1273
1274    /// Utility to format [`ValueSet`]s for logging.
1275    pub(crate) struct LogValueSet<'a> {
1276        pub(crate) values: &'a ValueSet<'a>,
1277        pub(crate) is_first: bool,
1278    }
1279
1280    impl<'a> fmt::Display for LogValueSet<'a> {
1281        #[inline]
1282        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1283            struct LogVisitor<'a, 'b> {
1284                f: &'a mut fmt::Formatter<'b>,
1285                is_first: bool,
1286                result: fmt::Result,
1287            }
1288
1289            impl Visit for LogVisitor<'_, '_> {
1290                fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
1291                    let res = if self.is_first {
1292                        self.is_first = false;
1293                        if field.name() == "message" {
1294                            write!(self.f, "{:?}", value)
1295                        } else {
1296                            write!(self.f, "{}={:?}", field.name(), value)
1297                        }
1298                    } else {
1299                        write!(self.f, " {}={:?}", field.name(), value)
1300                    };
1301                    if let Err(err) = res {
1302                        self.result = self.result.and(Err(err));
1303                    }
1304                }
1305
1306                fn record_str(&mut self, field: &Field, value: &str) {
1307                    if field.name() == "message" {
1308                        self.record_debug(field, &format_args!("{}", value))
1309                    } else {
1310                        self.record_debug(field, &value)
1311                    }
1312                }
1313            }
1314
1315            let mut visit = LogVisitor {
1316                f,
1317                is_first: self.is_first,
1318                result: Ok(()),
1319            };
1320            self.values.record(&mut visit);
1321            visit.result
1322        }
1323    }
1324}
1325
1326mod sealed {
1327    pub trait Sealed {}
1328}