Coverage Report

Created: 2025-11-16 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-0.1.41/src/lib.rs
Line
Count
Source
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.
1011
0
    pub fn __is_enabled(meta: &Metadata<'static>, interest: Interest) -> bool {
1012
0
        interest.is_always() || crate::dispatcher::get_default(|default| default.enabled(meta))
1013
0
    }
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")]
1023
    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"))]
1035
0
    pub fn __disabled_span(_: &'static Metadata<'static>) -> crate::Span {
1036
0
        crate::Span::none()
1037
0
    }
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")]
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]
1085
        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
}