• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.63+][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 //! _subscribers_. 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][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 //! ## Subscribers
95 //!
96 //! As `Span`s and `Event`s occur, they are recorded or aggregated by
97 //! implementations of the [`Subscriber`] trait. `Subscriber`s are notified
98 //! when an `Event` takes place and when a `Span` is entered or exited. These
99 //! notifications are represented by the following `Subscriber` trait methods:
100 //!
101 //! + [`event`][Subscriber::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, subscribers 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 `Subscriber::enabled` returns `false` for a given
108 //! set of metadata, that `Subscriber` will *not* be notified about the
109 //! corresponding `Span` or `Event`. For performance reasons, if no currently
110 //! active subscribers 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 as well as the `#[instrument]` attribute
212 //! use fairly similar syntax, with some 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 subscriber), 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 the
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).entered();
520 //!
521 //!     info!("shaving yaks");
522 //!
523 //!     let mut yaks_shaved = 0;
524 //!     for yak in 1..=yaks {
525 //!         let res = shave(yak);
526 //!         debug!(yak, shaved = res.is_ok());
527 //!
528 //!         if let Err(ref error) = res {
529 //!             // Like spans, events can also use the field initialization shorthand.
530 //!             // In this instance, `yak` is the field being initalized.
531 //!             error!(yak, error = error.as_ref(), "failed to shave yak!");
532 //!         } else {
533 //!             yaks_shaved += 1;
534 //!         }
535 //!         debug!(yaks_shaved);
536 //!     }
537 //!
538 //!     yaks_shaved
539 //! }
540 //! ```
541 //!
542 //! ## In libraries
543 //!
544 //! Libraries should link only to the `tracing` crate, and use the provided
545 //! macros to record whatever information will be useful to downstream
546 //! consumers.
547 //!
548 //! ## In executables
549 //!
550 //! In order to record trace events, executables have to use a `Subscriber`
551 //! implementation compatible with `tracing`. A `Subscriber` implements a
552 //! way of collecting trace data, such as by logging it to standard output.
553 //!
554 //! This library does not contain any `Subscriber` implementations; these are
555 //! provided by [other crates](#related-crates).
556 //!
557 //! The simplest way to use a subscriber is to call the [`set_global_default`]
558 //! function:
559 //!
560 //! ```
561 //! extern crate tracing;
562 //! # pub struct FooSubscriber;
563 //! # use tracing::{span::{Id, Attributes, Record}, Metadata};
564 //! # impl tracing::Subscriber for FooSubscriber {
565 //! #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
566 //! #   fn record(&self, _: &Id, _: &Record) {}
567 //! #   fn event(&self, _: &tracing::Event) {}
568 //! #   fn record_follows_from(&self, _: &Id, _: &Id) {}
569 //! #   fn enabled(&self, _: &Metadata) -> bool { false }
570 //! #   fn enter(&self, _: &Id) {}
571 //! #   fn exit(&self, _: &Id) {}
572 //! # }
573 //! # impl FooSubscriber {
574 //! #   fn new() -> Self { FooSubscriber }
575 //! # }
576 //! # fn main() {
577 //!
578 //! let my_subscriber = FooSubscriber::new();
579 //! tracing::subscriber::set_global_default(my_subscriber)
580 //!     .expect("setting tracing default failed");
581 //! # }
582 //! ```
583 //!
584 //! <pre class="compile_fail" style="white-space:normal;font:inherit;">
585 //!     <strong>Warning</strong>: In general, libraries should <em>not</em> call
586 //!     <code>set_global_default()</code>! Doing so will cause conflicts when
587 //!     executables that depend on the library try to set the default later.
588 //! </pre>
589 //!
590 //! This subscriber will be used as the default in all threads for the
591 //! remainder of the duration of the program, similar to setting the logger
592 //! in the `log` crate.
593 //!
594 //! In addition, the default subscriber can be set through using the
595 //! [`with_default`] function. This follows the `tokio` pattern of using
596 //! closures to represent executing code in a context that is exited at the end
597 //! of the closure. For example:
598 //!
599 //! ```rust
600 //! # pub struct FooSubscriber;
601 //! # use tracing::{span::{Id, Attributes, Record}, Metadata};
602 //! # impl tracing::Subscriber for FooSubscriber {
603 //! #   fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
604 //! #   fn record(&self, _: &Id, _: &Record) {}
605 //! #   fn event(&self, _: &tracing::Event) {}
606 //! #   fn record_follows_from(&self, _: &Id, _: &Id) {}
607 //! #   fn enabled(&self, _: &Metadata) -> bool { false }
608 //! #   fn enter(&self, _: &Id) {}
609 //! #   fn exit(&self, _: &Id) {}
610 //! # }
611 //! # impl FooSubscriber {
612 //! #   fn new() -> Self { FooSubscriber }
613 //! # }
614 //! # fn main() {
615 //!
616 //! let my_subscriber = FooSubscriber::new();
617 //! # #[cfg(feature = "std")]
618 //! tracing::subscriber::with_default(my_subscriber, || {
619 //!     // Any trace events generated in this closure or by functions it calls
620 //!     // will be collected by `my_subscriber`.
621 //! })
622 //! # }
623 //! ```
624 //!
625 //! This approach allows trace data to be collected by multiple subscribers
626 //! within different contexts in the program. Note that the override only applies to the
627 //! currently executing thread; other threads will not see the change from with_default.
628 //!
629 //! Any trace events generated outside the context of a subscriber will not be collected.
630 //!
631 //! Once a subscriber has been set, instrumentation points may be added to the
632 //! executable using the `tracing` crate's macros.
633 //!
634 //! ## `log` Compatibility
635 //!
636 //! The [`log`] crate provides a simple, lightweight logging facade for Rust.
637 //! While `tracing` builds upon `log`'s foundation with richer structured
638 //! diagnostic data, `log`'s simplicity and ubiquity make it the "lowest common
639 //! denominator" for text-based logging in Rust — a vast majority of Rust
640 //! libraries and applications either emit or consume `log` records. Therefore,
641 //! `tracing` provides multiple forms of interoperability with `log`: `tracing`
642 //! instrumentation can emit `log` records, and a compatibility layer enables
643 //! `tracing` [`Subscriber`]s to consume `log` records as `tracing` [`Event`]s.
644 //!
645 //! ### Emitting `log` Records
646 //!
647 //! This crate provides two feature flags, "log" and "log-always", which will
648 //! cause [spans] and [events] to emit `log` records. When the "log" feature is
649 //! enabled, if no `tracing` `Subscriber` is active, invoking an event macro or
650 //! creating a span with fields will emit a `log` record. This is intended
651 //! primarily for use in libraries which wish to emit diagnostics that can be
652 //! consumed by applications using `tracing` *or* `log`, without paying the
653 //! additional overhead of emitting both forms of diagnostics when `tracing` is
654 //! in use.
655 //!
656 //! Enabling the "log-always" feature will cause `log` records to be emitted
657 //! even if a `tracing` `Subscriber` _is_ set. This is intended to be used in
658 //! applications where a `log` `Logger` is being used to record a textual log,
659 //! and `tracing` is used only to record other forms of diagnostics (such as
660 //! metrics, profiling, or distributed tracing data). Unlike the "log" feature,
661 //! libraries generally should **not** enable the "log-always" feature, as doing
662 //! so will prevent applications from being able to opt out of the `log` records.
663 //!
664 //! See [here][flags] for more details on this crate's feature flags.
665 //!
666 //! The generated `log` records' messages will be a string representation of the
667 //! span or event's fields, and all additional information recorded by `log`
668 //! (target, verbosity level, module path, file, and line number) will also be
669 //! populated. Additionally, `log` records are also generated when spans are
670 //! entered, exited, and closed. Since these additional span lifecycle logs have
671 //! the potential to be very verbose, and don't include additional fields, they
672 //! will always be emitted at the `Trace` level, rather than inheriting the
673 //! level of the span that generated them. Furthermore, they are are categorized
674 //! under a separate `log` target, "tracing::span" (and its sub-target,
675 //! "tracing::span::active", for the logs on entering and exiting a span), which
676 //! may be enabled or disabled separately from other `log` records emitted by
677 //! `tracing`.
678 //!
679 //! ### Consuming `log` Records
680 //!
681 //! The [`tracing-log`] crate provides a compatibility layer which
682 //! allows a `tracing` [`Subscriber`] to consume `log` records as though they
683 //! were `tracing` [events]. This allows applications using `tracing` to record
684 //! the logs emitted by dependencies using `log` as events within the context of
685 //! the application's trace tree. See [that crate's documentation][log-tracer]
686 //! for details.
687 //!
688 //! [log-tracer]: https://docs.rs/tracing-log/latest/tracing_log/#convert-log-records-to-tracing-events
689 //!
690 //! ## Related Crates
691 //!
692 //! In addition to `tracing` and `tracing-core`, the [`tokio-rs/tracing`] repository
693 //! contains several additional crates designed to be used with the `tracing` ecosystem.
694 //! This includes a collection of `Subscriber` implementations, as well as utility
695 //! and adapter crates to assist in writing `Subscriber`s and instrumenting
696 //! applications.
697 //!
698 //! In particular, the following crates are likely to be of interest:
699 //!
700 //!  - [`tracing-futures`] provides a compatibility layer with the `futures`
701 //!    crate, allowing spans to be attached to `Future`s, `Stream`s, and `Executor`s.
702 //!  - [`tracing-subscriber`] provides `Subscriber` implementations and
703 //!    utilities for working with `Subscriber`s. This includes a [`FmtSubscriber`]
704 //!    `FmtSubscriber` for logging formatted trace data to stdout, with similar
705 //!    filtering and formatting to the [`env_logger`] crate.
706 //!  - [`tracing-log`] provides a compatibility layer with the [`log`] crate,
707 //!    allowing log messages to be recorded as `tracing` `Event`s within the
708 //!    trace tree. This is useful when a project using `tracing` have
709 //!    dependencies which use `log`. Note that if you're using
710 //!    `tracing-subscriber`'s `FmtSubscriber`, you don't need to depend on
711 //!    `tracing-log` directly.
712 //!  - [`tracing-appender`] provides utilities for outputting tracing data,
713 //!     including a file appender and non blocking writer.
714 //!
715 //! Additionally, there are also several third-party crates which are not
716 //! maintained by the `tokio` project. These include:
717 //!
718 //!  - [`tracing-timing`] implements inter-event timing metrics on top of `tracing`.
719 //!    It provides a subscriber that records the time elapsed between pairs of
720 //!    `tracing` events and generates histograms.
721 //!  - [`tracing-opentelemetry`] provides a subscriber for emitting traces to
722 //!    [OpenTelemetry]-compatible distributed tracing systems.
723 //!  - [`tracing-honeycomb`] Provides a layer that reports traces spanning multiple machines to [honeycomb.io]. Backed by [`tracing-distributed`].
724 //!  - [`tracing-distributed`] Provides a generic implementation of a layer that reports traces spanning multiple machines to some backend.
725 //!  - [`tracing-actix-web`] provides `tracing` integration for the `actix-web` web framework.
726 //!  - [`tracing-actix`] provides `tracing` integration for the `actix` actor
727 //!    framework.
728 //!  - [`axum-insights`] provides `tracing` integration and Application insights export for the `axum` web framework.
729 //!  - [`tracing-gelf`] implements a subscriber for exporting traces in Greylog
730 //!    GELF format.
731 //!  - [`tracing-coz`] provides integration with the [coz] causal profiler
732 //!    (Linux-only).
733 //!  - [`tracing-bunyan-formatter`] provides a layer implementation that reports events and spans
734 //!    in [bunyan] format, enriched with timing information.
735 //!  - [`tracing-wasm`] provides a `Subscriber`/`Layer` implementation that reports
736 //!    events and spans via browser `console.log` and [User Timing API (`window.performance`)].
737 //!  - [`tracing-web`] provides a layer implementation of level-aware logging of events
738 //!    to web browsers' `console.*` and span events to the [User Timing API (`window.performance`)].
739 //!  - [`tide-tracing`] provides a [tide] middleware to trace all incoming requests and responses.
740 //!  - [`test-log`] takes care of initializing `tracing` for tests, based on
741 //!    environment variables with an `env_logger` compatible syntax.
742 //!  - [`tracing-unwrap`] provides convenience methods to report failed unwraps
743 //!    on `Result` or `Option` types to a `Subscriber`.
744 //!  - [`diesel-tracing`] provides integration with [`diesel`] database connections.
745 //!  - [`tracing-tracy`] provides a way to collect [Tracy] profiles in instrumented
746 //!    applications.
747 //!  - [`tracing-elastic-apm`] provides a layer for reporting traces to [Elastic APM].
748 //!  - [`tracing-etw`] provides a layer for emitting Windows [ETW] events.
749 //!  - [`tracing-fluent-assertions`] provides a fluent assertions-style testing
750 //!    framework for validating the behavior of `tracing` spans.
751 //!  - [`sentry-tracing`] provides a layer for reporting events and traces to [Sentry].
752 //!  - [`tracing-forest`] provides a subscriber that preserves contextual coherence by
753 //!    grouping together logs from the same spans during writing.
754 //!  - [`tracing-loki`] provides a layer for shipping logs to [Grafana Loki].
755 //!  - [`tracing-logfmt`] provides a layer that formats events and spans into the logfmt format.
756 //!  - [`reqwest-tracing`] provides a middleware to trace [`reqwest`] HTTP requests.
757 //!  - [`tracing-cloudwatch`] provides a layer that sends events to AWS CloudWatch Logs.
758 //!  - [`clippy-tracing`] provides a tool to add, remove and check for `tracing::instrument`.
759 //!  - [`json-subscriber`] provides a subscriber for emitting JSON logs. The output can be customized much more than with [`tracing-subscriber`]'s JSON output.
760 //!
761 //! If you're the maintainer of a `tracing` ecosystem crate not listed above,
762 //! please let us know! We'd love to add your project to the list!
763 //!
764 //! [`tracing-opentelemetry`]: https://crates.io/crates/tracing-opentelemetry
765 //! [OpenTelemetry]: https://opentelemetry.io/
766 //! [`tracing-honeycomb`]: https://crates.io/crates/tracing-honeycomb
767 //! [`tracing-distributed`]: https://crates.io/crates/tracing-distributed
768 //! [honeycomb.io]: https://www.honeycomb.io/
769 //! [`tracing-actix-web`]: https://crates.io/crates/tracing-actix-web
770 //! [`tracing-actix`]: https://crates.io/crates/tracing-actix
771 //! [`axum-insights`]: https://crates.io/crates/axum-insights
772 //! [`tracing-gelf`]: https://crates.io/crates/tracing-gelf
773 //! [`tracing-coz`]: https://crates.io/crates/tracing-coz
774 //! [coz]: https://github.com/plasma-umass/coz
775 //! [`tracing-bunyan-formatter`]: https://crates.io/crates/tracing-bunyan-formatter
776 //! [bunyan]: https://github.com/trentm/node-bunyan
777 //! [`tracing-wasm`]: https://docs.rs/tracing-wasm
778 //! [`tracing-web`]: https://docs.rs/tracing-web
779 //! [User Timing API (`window.performance`)]: https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API
780 //! [`tide-tracing`]: https://crates.io/crates/tide-tracing
781 //! [tide]: https://crates.io/crates/tide
782 //! [`test-log`]: https://crates.io/crates/test-log
783 //! [`tracing-unwrap`]: https://docs.rs/tracing-unwrap
784 //! [`diesel`]: https://crates.io/crates/diesel
785 //! [`diesel-tracing`]: https://crates.io/crates/diesel-tracing
786 //! [`tracing-tracy`]: https://crates.io/crates/tracing-tracy
787 //! [Tracy]: https://github.com/wolfpld/tracy
788 //! [`tracing-elastic-apm`]: https://crates.io/crates/tracing-elastic-apm
789 //! [Elastic APM]: https://www.elastic.co/apm
790 //! [`tracing-etw`]: https://github.com/microsoft/rust_win_etw/tree/main/win_etw_tracing
791 //! [ETW]: https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing
792 //! [`tracing-fluent-assertions`]: https://crates.io/crates/tracing-fluent-assertions
793 //! [`sentry-tracing`]: https://crates.io/crates/sentry-tracing
794 //! [Sentry]: https://sentry.io/welcome/
795 //! [`tracing-forest`]: https://crates.io/crates/tracing-forest
796 //! [`tracing-loki`]: https://crates.io/crates/tracing-loki
797 //! [Grafana Loki]: https://grafana.com/oss/loki/
798 //! [`tracing-logfmt`]: https://crates.io/crates/tracing-logfmt
799 //! [`reqwest-tracing`]: https://crates.io/crates/reqwest-tracing
800 //! [`reqwest`]: https://crates.io/crates/reqwest
801 //! [`tracing-cloudwatch`]: https://crates.io/crates/tracing-cloudwatch
802 //! [`clippy-tracing`]: https://crates.io/crates/clippy-tracing
803 //! [`json-subscriber`]: https://crates.io/crates/json-subscriber
804 //!
805 //! <pre class="ignore" style="white-space:normal;font:inherit;">
806 //!     <strong>Note</strong>: Some of these ecosystem crates are currently
807 //!     unreleased and/or in earlier stages of development. They may be less stable
808 //!     than <code>tracing</code> and <code>tracing-core</code>.
809 //! </pre>
810 //!
811 //! ## Crate Feature Flags
812 //!
813 //! The following crate [feature flags] are available:
814 //!
815 //! * A set of features controlling the [static verbosity level].
816 //! * `log`: causes trace instrumentation points to emit [`log`] records as well
817 //!   as trace events, if a default `tracing` subscriber has not been set. This
818 //!   is intended for use in libraries whose users may be using either `tracing`
819 //!   or `log`.
820 //! * `log-always`: Emit `log` records from all `tracing` spans and events, even
821 //!   if a `tracing` subscriber has been set. This should be set only by
822 //!   applications which intend to collect traces and logs separately; if an
823 //!   adapter is used to convert `log` records into `tracing` events, this will
824 //!   cause duplicate events to occur.
825 //! * `attributes`: Includes support for the `#[instrument]` attribute.
826 //!   This is on by default, but does bring in the `syn` crate as a dependency,
827 //!   which may add to the compile time of crates that do not already use it.
828 //! * `std`: Depend on the Rust standard library (enabled by default).
829 //!
830 //!   `no_std` users may disable this feature with `default-features = false`:
831 //!
832 //!   ```toml
833 //!   [dependencies]
834 //!   tracing = { version = "0.1.38", default-features = false }
835 //!   ```
836 //!
837 //! <pre class="ignore" style="white-space:normal;font:inherit;">
838 //!     <strong>Note</strong>: <code>tracing</code>'s <code>no_std</code> support
839 //!     requires <code>liballoc</code>.
840 //! </pre>
841 //!
842 //! ### Unstable Features
843 //!
844 //! These feature flags enable **unstable** features. The public API may break in 0.1.x
845 //! releases. To enable these features, the `--cfg tracing_unstable` must be passed to
846 //! `rustc` when compiling.
847 //!
848 //! The following unstable feature flags are currently available:
849 //!
850 //! * `valuable`: Enables support for recording [field values] using the
851 //!   [`valuable`] crate.
852 //!
853 //! #### Enabling Unstable Features
854 //!
855 //! The easiest way to set the `tracing_unstable` cfg is to use the `RUSTFLAGS`
856 //! env variable when running `cargo` commands:
857 //!
858 //! ```shell
859 //! RUSTFLAGS="--cfg tracing_unstable" cargo build
860 //! ```
861 //! Alternatively, the following can be added to the `.cargo/config` file in a
862 //! project to automatically enable the cfg flag for that project:
863 //!
864 //! ```toml
865 //! [build]
866 //! rustflags = ["--cfg", "tracing_unstable"]
867 //! ```
868 //!
869 //! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
870 //! [field values]: crate::field
871 //! [`valuable`]: https://crates.io/crates/valuable
872 //!
873 //! ## Supported Rust Versions
874 //!
875 //! Tracing is built against the latest stable release. The minimum supported
876 //! version is 1.63. The current Tracing version is not guaranteed to build on
877 //! Rust versions earlier than the minimum supported version.
878 //!
879 //! Tracing follows the same compiler support policies as the rest of the Tokio
880 //! project. The current stable Rust compiler and the three most recent minor
881 //! versions before it will always be supported. For example, if the current
882 //! stable compiler version is 1.69, the minimum supported version will not be
883 //! increased past 1.66, three minor versions prior. Increasing the minimum
884 //! supported compiler version is not considered a semver breaking change as
885 //! long as doing so complies with this policy.
886 //!
887 //! [`log`]: https://docs.rs/log/0.4.6/log/
888 //! [span]: mod@span
889 //! [spans]: mod@span
890 //! [`Span`]: span::Span
891 //! [`in_scope`]: span::Span::in_scope
892 //! [event]: Event
893 //! [events]: Event
894 //! [`Subscriber`]: subscriber::Subscriber
895 //! [Subscriber::event]: subscriber::Subscriber::event
896 //! [`enter`]: subscriber::Subscriber::enter
897 //! [`exit`]: subscriber::Subscriber::exit
898 //! [`enabled`]: subscriber::Subscriber::enabled
899 //! [metadata]: Metadata
900 //! [`field::display`]: field::display
901 //! [`field::debug`]: field::debug
902 //! [`set_global_default`]: subscriber::set_global_default
903 //! [`with_default`]: subscriber::with_default
904 //! [`tokio-rs/tracing`]: https://github.com/tokio-rs/tracing
905 //! [`tracing-futures`]: https://crates.io/crates/tracing-futures
906 //! [`tracing-subscriber`]: https://crates.io/crates/tracing-subscriber
907 //! [`tracing-log`]: https://crates.io/crates/tracing-log
908 //! [`tracing-timing`]: https://crates.io/crates/tracing-timing
909 //! [`tracing-appender`]: https://crates.io/crates/tracing-appender
910 //! [`env_logger`]: https://crates.io/crates/env_logger
911 //! [`FmtSubscriber`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/struct.Subscriber.html
912 //! [static verbosity level]: level_filters#compile-time-filters
913 //! [instrument]: https://docs.rs/tracing-attributes/latest/tracing_attributes/attr.instrument.html
914 //! [flags]: #crate-feature-flags
915 #![cfg_attr(not(feature = "std"), no_std)]
916 #![cfg_attr(docsrs, feature(doc_cfg), deny(rustdoc::broken_intra_doc_links))]
917 #![doc(
918     html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
919     issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
920 )]
921 #![warn(
922     missing_debug_implementations,
923     missing_docs,
924     rust_2018_idioms,
925     unreachable_pub,
926     bad_style,
927     dead_code,
928     improper_ctypes,
929     non_shorthand_field_patterns,
930     no_mangle_generic_items,
931     overflowing_literals,
932     path_statements,
933     patterns_in_fns_without_body,
934     private_interfaces,
935     private_bounds,
936     unconditional_recursion,
937     unused,
938     unused_allocation,
939     unused_comparisons,
940     unused_parens,
941     while_true
942 )]
943 
944 #[cfg(not(feature = "std"))]
945 extern crate alloc;
946 
947 // Somehow this `use` statement is necessary for us to re-export the `core`
948 // macros on Rust 1.26.0. I'm not sure how this makes it work, but it does.
949 #[allow(unused_imports)]
950 #[doc(hidden)]
951 use tracing_core::*;
952 
953 #[doc(inline)]
954 pub use self::instrument::Instrument;
955 pub use self::{dispatcher::Dispatch, event::Event, field::Value, subscriber::Subscriber};
956 
957 #[doc(hidden)]
958 pub use self::span::Id;
959 
960 #[doc(hidden)]
961 pub use tracing_core::{
962     callsite::{self, Callsite},
963     metadata,
964 };
965 pub use tracing_core::{event, Level, Metadata};
966 
967 #[doc(inline)]
968 pub use self::span::Span;
969 #[cfg(feature = "attributes")]
970 #[cfg_attr(docsrs, doc(cfg(feature = "attributes")))]
971 #[doc(inline)]
972 pub use tracing_attributes::instrument;
973 
974 #[macro_use]
975 mod macros;
976 
977 pub mod dispatcher;
978 pub mod field;
979 /// Attach a span to a `std::future::Future`.
980 pub mod instrument;
981 pub mod level_filters;
982 pub mod span;
983 pub(crate) mod stdlib;
984 pub mod subscriber;
985 
986 #[doc(hidden)]
987 pub mod __macro_support {
988     pub use crate::callsite::Callsite;
989     use crate::{subscriber::Interest, Metadata};
990     // Re-export the `core` functions that are used in macros. This allows
991     // a crate to be named `core` and avoid name clashes.
992     // See here: https://github.com/tokio-rs/tracing/issues/2761
993     pub use core::{concat, file, format_args, iter::Iterator, line, option::Option};
994 
995     /// Callsite implementation used by macro-generated code.
996     ///
997     /// /!\ WARNING: This is *not* a stable API! /!\
998     /// This type, and all code contained in the `__macro_support` module, is
999     /// a *private* API of `tracing`. It is exposed publicly because it is used
1000     /// by the `tracing` macros, but it is not part of the stable versioned API.
1001     /// Breaking changes to this module may occur in small-numbered versions
1002     /// without warning.
1003     pub use tracing_core::callsite::DefaultCallsite as MacroCallsite;
1004 
1005     /// /!\ WARNING: This is *not* a stable API! /!\
1006     /// This function, and all code contained in the `__macro_support` module, is
1007     /// a *private* API of `tracing`. It is exposed publicly because it is used
1008     /// by the `tracing` macros, but it is not part of the stable versioned API.
1009     /// Breaking changes to this module may occur in small-numbered versions
1010     /// without warning.
__is_enabled(meta: &Metadata<'static>, interest: Interest) -> bool1011     pub fn __is_enabled(meta: &Metadata<'static>, interest: Interest) -> bool {
1012         interest.is_always() || crate::dispatcher::get_default(|default| default.enabled(meta))
1013     }
1014 
1015     /// /!\ WARNING: This is *not* a stable API! /!\
1016     /// This function, and all code contained in the `__macro_support` module, is
1017     /// a *private* API of `tracing`. It is exposed publicly because it is used
1018     /// by the `tracing` macros, but it is not part of the stable versioned API.
1019     /// Breaking changes to this module may occur in small-numbered versions
1020     /// without warning.
1021     #[inline]
1022     #[cfg(feature = "log")]
__disabled_span(meta: &'static Metadata<'static>) -> crate::Span1023     pub fn __disabled_span(meta: &'static Metadata<'static>) -> crate::Span {
1024         crate::Span::new_disabled(meta)
1025     }
1026 
1027     /// /!\ WARNING: This is *not* a stable API! /!\
1028     /// This function, and all code contained in the `__macro_support` module, is
1029     /// a *private* API of `tracing`. It is exposed publicly because it is used
1030     /// by the `tracing` macros, but it is not part of the stable versioned API.
1031     /// Breaking changes to this module may occur in small-numbered versions
1032     /// without warning.
1033     #[inline]
1034     #[cfg(not(feature = "log"))]
__disabled_span(_: &'static Metadata<'static>) -> crate::Span1035     pub fn __disabled_span(_: &'static Metadata<'static>) -> crate::Span {
1036         crate::Span::none()
1037     }
1038 
1039     /// /!\ WARNING: This is *not* a stable API! /!\
1040     /// This function, and all code contained in the `__macro_support` module, is
1041     /// a *private* API of `tracing`. It is exposed publicly because it is used
1042     /// by the `tracing` macros, but it is not part of the stable versioned API.
1043     /// Breaking changes to this module may occur in small-numbered versions
1044     /// without warning.
1045     #[cfg(feature = "log")]
__tracing_log( meta: &Metadata<'static>, logger: &'static dyn log::Log, log_meta: log::Metadata<'_>, values: &tracing_core::field::ValueSet<'_>, )1046     pub fn __tracing_log(
1047         meta: &Metadata<'static>,
1048         logger: &'static dyn log::Log,
1049         log_meta: log::Metadata<'_>,
1050         values: &tracing_core::field::ValueSet<'_>,
1051     ) {
1052         logger.log(
1053             &crate::log::Record::builder()
1054                 .file(meta.file())
1055                 .module_path(meta.module_path())
1056                 .line(meta.line())
1057                 .metadata(log_meta)
1058                 .args(format_args!(
1059                     "{}",
1060                     crate::log::LogValueSet {
1061                         values,
1062                         is_first: true
1063                     }
1064                 ))
1065                 .build(),
1066         );
1067     }
1068 }
1069 
1070 #[cfg(feature = "log")]
1071 #[doc(hidden)]
1072 pub mod log {
1073     use core::fmt;
1074     pub use log::*;
1075     use tracing_core::field::{Field, ValueSet, Visit};
1076 
1077     /// Utility to format [`ValueSet`]s for logging.
1078     pub(crate) struct LogValueSet<'a> {
1079         pub(crate) values: &'a ValueSet<'a>,
1080         pub(crate) is_first: bool,
1081     }
1082 
1083     impl<'a> fmt::Display for LogValueSet<'a> {
1084         #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1085         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1086             struct LogVisitor<'a, 'b> {
1087                 f: &'a mut fmt::Formatter<'b>,
1088                 is_first: bool,
1089                 result: fmt::Result,
1090             }
1091 
1092             impl Visit for LogVisitor<'_, '_> {
1093                 fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
1094                     let res = if self.is_first {
1095                         self.is_first = false;
1096                         if field.name() == "message" {
1097                             write!(self.f, "{:?}", value)
1098                         } else {
1099                             write!(self.f, "{}={:?}", field.name(), value)
1100                         }
1101                     } else {
1102                         write!(self.f, " {}={:?}", field.name(), value)
1103                     };
1104                     if let Err(err) = res {
1105                         self.result = self.result.and(Err(err));
1106                     }
1107                 }
1108 
1109                 fn record_str(&mut self, field: &Field, value: &str) {
1110                     if field.name() == "message" {
1111                         self.record_debug(field, &format_args!("{}", value))
1112                     } else {
1113                         self.record_debug(field, &value)
1114                     }
1115                 }
1116             }
1117 
1118             let mut visit = LogVisitor {
1119                 f,
1120                 is_first: self.is_first,
1121                 result: Ok(()),
1122             };
1123             self.values.record(&mut visit);
1124             visit.result
1125         }
1126     }
1127 }
1128 
1129 mod sealed {
1130     pub trait Sealed {}
1131 }
1132