1 use crate::{ 2 field::RecordFields, 3 fmt::{format, FormatEvent, FormatFields, MakeWriter, TestWriter}, 4 layer::{self, Context}, 5 registry::{self, LookupSpan, SpanRef}, 6 }; 7 use format::{FmtSpan, TimingDisplay}; 8 use std::{ 9 any::TypeId, cell::RefCell, env, fmt, io, marker::PhantomData, ops::Deref, time::Instant, 10 }; 11 use tracing_core::{ 12 field, 13 span::{Attributes, Current, Id, Record}, 14 Event, Metadata, Subscriber, 15 }; 16 17 /// A [`Layer`] that logs formatted representations of `tracing` events. 18 /// 19 /// ## Examples 20 /// 21 /// Constructing a layer with the default configuration: 22 /// 23 /// ```rust 24 /// use tracing_subscriber::{fmt, Registry}; 25 /// use tracing_subscriber::prelude::*; 26 /// 27 /// let subscriber = Registry::default() 28 /// .with(fmt::Layer::default()); 29 /// 30 /// tracing::subscriber::set_global_default(subscriber).unwrap(); 31 /// ``` 32 /// 33 /// Overriding the layer's behavior: 34 /// 35 /// ```rust 36 /// use tracing_subscriber::{fmt, Registry}; 37 /// use tracing_subscriber::prelude::*; 38 /// 39 /// let fmt_layer = fmt::layer() 40 /// .with_target(false) // don't include event targets when logging 41 /// .with_level(false); // don't include event levels when logging 42 /// 43 /// let subscriber = Registry::default().with(fmt_layer); 44 /// # tracing::subscriber::set_global_default(subscriber).unwrap(); 45 /// ``` 46 /// 47 /// Setting a custom event formatter: 48 /// 49 /// ```rust 50 /// use tracing_subscriber::fmt::{self, format, time}; 51 /// use tracing_subscriber::prelude::*; 52 /// 53 /// let fmt = format().with_timer(time::Uptime::default()); 54 /// let fmt_layer = fmt::layer() 55 /// .event_format(fmt) 56 /// .with_target(false); 57 /// # let subscriber = fmt_layer.with_subscriber(tracing_subscriber::registry::Registry::default()); 58 /// # tracing::subscriber::set_global_default(subscriber).unwrap(); 59 /// ``` 60 /// 61 /// [`Layer`]: super::layer::Layer 62 #[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))] 63 #[derive(Debug)] 64 pub struct Layer< 65 S, 66 N = format::DefaultFields, 67 E = format::Format<format::Full>, 68 W = fn() -> io::Stdout, 69 > { 70 make_writer: W, 71 fmt_fields: N, 72 fmt_event: E, 73 fmt_span: format::FmtSpanConfig, 74 is_ansi: bool, 75 log_internal_errors: bool, 76 _inner: PhantomData<fn(S)>, 77 } 78 79 impl<S> Layer<S> { 80 /// Returns a new [`Layer`][self::Layer] with the default configuration. new() -> Self81 pub fn new() -> Self { 82 Self::default() 83 } 84 } 85 86 // This needs to be a seperate impl block because they place different bounds on the type parameters. 87 impl<S, N, E, W> Layer<S, N, E, W> 88 where 89 S: Subscriber + for<'a> LookupSpan<'a>, 90 N: for<'writer> FormatFields<'writer> + 'static, 91 W: for<'writer> MakeWriter<'writer> + 'static, 92 { 93 /// Sets the [event formatter][`FormatEvent`] that the layer being built will 94 /// use to format events. 95 /// 96 /// The event formatter may be any type implementing the [`FormatEvent`] 97 /// trait, which is implemented for all functions taking a [`FmtContext`], a 98 /// [`Writer`], and an [`Event`]. 99 /// 100 /// # Examples 101 /// 102 /// Setting a type implementing [`FormatEvent`] as the formatter: 103 /// ```rust 104 /// use tracing_subscriber::fmt::{self, format}; 105 /// 106 /// let layer = fmt::layer() 107 /// .event_format(format().compact()); 108 /// # // this is necessary for type inference. 109 /// # use tracing_subscriber::Layer as _; 110 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); 111 /// ``` 112 /// [`FormatEvent`]: format::FormatEvent 113 /// [`Event`]: tracing::Event 114 /// [`Writer`]: format::Writer event_format<E2>(self, e: E2) -> Layer<S, N, E2, W> where E2: FormatEvent<S, N> + 'static,115 pub fn event_format<E2>(self, e: E2) -> Layer<S, N, E2, W> 116 where 117 E2: FormatEvent<S, N> + 'static, 118 { 119 Layer { 120 fmt_fields: self.fmt_fields, 121 fmt_event: e, 122 fmt_span: self.fmt_span, 123 make_writer: self.make_writer, 124 is_ansi: self.is_ansi, 125 log_internal_errors: self.log_internal_errors, 126 _inner: self._inner, 127 } 128 } 129 130 /// Updates the event formatter by applying a function to the existing event formatter. 131 /// 132 /// This sets the event formatter that the layer being built will use to record fields. 133 /// 134 /// # Examples 135 /// 136 /// Updating an event formatter: 137 /// 138 /// ```rust 139 /// let layer = tracing_subscriber::fmt::layer() 140 /// .map_event_format(|e| e.compact()); 141 /// # // this is necessary for type inference. 142 /// # use tracing_subscriber::Layer as _; 143 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); 144 /// ``` map_event_format<E2>(self, f: impl FnOnce(E) -> E2) -> Layer<S, N, E2, W> where E2: FormatEvent<S, N> + 'static,145 pub fn map_event_format<E2>(self, f: impl FnOnce(E) -> E2) -> Layer<S, N, E2, W> 146 where 147 E2: FormatEvent<S, N> + 'static, 148 { 149 Layer { 150 fmt_fields: self.fmt_fields, 151 fmt_event: f(self.fmt_event), 152 fmt_span: self.fmt_span, 153 make_writer: self.make_writer, 154 is_ansi: self.is_ansi, 155 log_internal_errors: self.log_internal_errors, 156 _inner: self._inner, 157 } 158 } 159 } 160 161 // This needs to be a seperate impl block because they place different bounds on the type parameters. 162 impl<S, N, E, W> Layer<S, N, E, W> { 163 /// Sets the [`MakeWriter`] that the layer being built will use to write events. 164 /// 165 /// # Examples 166 /// 167 /// Using `stderr` rather than `stdout`: 168 /// 169 /// ```rust 170 /// use std::io; 171 /// use tracing_subscriber::fmt; 172 /// 173 /// let layer = fmt::layer() 174 /// .with_writer(io::stderr); 175 /// # // this is necessary for type inference. 176 /// # use tracing_subscriber::Layer as _; 177 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); 178 /// ``` with_writer<W2>(self, make_writer: W2) -> Layer<S, N, E, W2> where W2: for<'writer> MakeWriter<'writer> + 'static,179 pub fn with_writer<W2>(self, make_writer: W2) -> Layer<S, N, E, W2> 180 where 181 W2: for<'writer> MakeWriter<'writer> + 'static, 182 { 183 Layer { 184 fmt_fields: self.fmt_fields, 185 fmt_event: self.fmt_event, 186 fmt_span: self.fmt_span, 187 is_ansi: self.is_ansi, 188 log_internal_errors: self.log_internal_errors, 189 make_writer, 190 _inner: self._inner, 191 } 192 } 193 194 /// Borrows the [writer] for this [`Layer`]. 195 /// 196 /// [writer]: MakeWriter writer(&self) -> &W197 pub fn writer(&self) -> &W { 198 &self.make_writer 199 } 200 201 /// Mutably borrows the [writer] for this [`Layer`]. 202 /// 203 /// This method is primarily expected to be used with the 204 /// [`reload::Handle::modify`](crate::reload::Handle::modify) method. 205 /// 206 /// # Examples 207 /// 208 /// ``` 209 /// # use tracing::info; 210 /// # use tracing_subscriber::{fmt,reload,Registry,prelude::*}; 211 /// # fn non_blocking<T: std::io::Write>(writer: T) -> (fn() -> std::io::Stdout) { 212 /// # std::io::stdout 213 /// # } 214 /// # fn main() { 215 /// let layer = fmt::layer().with_writer(non_blocking(std::io::stderr())); 216 /// let (layer, reload_handle) = reload::Layer::new(layer); 217 /// # 218 /// # // specifying the Registry type is required 219 /// # let _: &reload::Handle<fmt::Layer<Registry, _, _, _>, Registry> = &reload_handle; 220 /// # 221 /// info!("This will be logged to stderr"); 222 /// reload_handle.modify(|layer| *layer.writer_mut() = non_blocking(std::io::stdout())); 223 /// info!("This will be logged to stdout"); 224 /// # } 225 /// ``` 226 /// 227 /// [writer]: MakeWriter writer_mut(&mut self) -> &mut W228 pub fn writer_mut(&mut self) -> &mut W { 229 &mut self.make_writer 230 } 231 232 /// Sets whether this layer should use ANSI terminal formatting 233 /// escape codes (such as colors). 234 /// 235 /// This method is primarily expected to be used with the 236 /// [`reload::Handle::modify`](crate::reload::Handle::modify) method when changing 237 /// the writer. 238 #[cfg(feature = "ansi")] 239 #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] set_ansi(&mut self, ansi: bool)240 pub fn set_ansi(&mut self, ansi: bool) { 241 self.is_ansi = ansi; 242 } 243 244 /// Configures the layer to support [`libtest`'s output capturing][capturing] when used in 245 /// unit tests. 246 /// 247 /// See [`TestWriter`] for additional details. 248 /// 249 /// # Examples 250 /// 251 /// Using [`TestWriter`] to let `cargo test` capture test output: 252 /// 253 /// ```rust 254 /// use std::io; 255 /// use tracing_subscriber::fmt; 256 /// 257 /// let layer = fmt::layer() 258 /// .with_test_writer(); 259 /// # // this is necessary for type inference. 260 /// # use tracing_subscriber::Layer as _; 261 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); 262 /// ``` 263 /// [capturing]: 264 /// https://doc.rust-lang.org/book/ch11-02-running-tests.html#showing-function-output 265 /// [`TestWriter`]: super::writer::TestWriter with_test_writer(self) -> Layer<S, N, E, TestWriter>266 pub fn with_test_writer(self) -> Layer<S, N, E, TestWriter> { 267 Layer { 268 fmt_fields: self.fmt_fields, 269 fmt_event: self.fmt_event, 270 fmt_span: self.fmt_span, 271 is_ansi: self.is_ansi, 272 log_internal_errors: self.log_internal_errors, 273 make_writer: TestWriter::default(), 274 _inner: self._inner, 275 } 276 } 277 278 /// Sets whether or not the formatter emits ANSI terminal escape codes 279 /// for colors and other text formatting. 280 /// 281 /// When the "ansi" crate feature flag is enabled, ANSI colors are enabled 282 /// by default unless the [`NO_COLOR`] environment variable is set to 283 /// a non-empty value. If the [`NO_COLOR`] environment variable is set to 284 /// any non-empty value, then ANSI colors will be suppressed by default. 285 /// The [`with_ansi`] and [`set_ansi`] methods can be used to forcibly 286 /// enable ANSI colors, overriding any [`NO_COLOR`] environment variable. 287 /// 288 /// [`NO_COLOR`]: https://no-color.org/ 289 /// 290 /// Enabling ANSI escapes (calling `with_ansi(true)`) requires the "ansi" 291 /// crate feature flag. Calling `with_ansi(true)` without the "ansi" 292 /// feature flag enabled will panic if debug assertions are enabled, or 293 /// print a warning otherwise. 294 /// 295 /// This method itself is still available without the feature flag. This 296 /// is to allow ANSI escape codes to be explicitly *disabled* without 297 /// having to opt-in to the dependencies required to emit ANSI formatting. 298 /// This way, code which constructs a formatter that should never emit 299 /// ANSI escape codes can ensure that they are not used, regardless of 300 /// whether or not other crates in the dependency graph enable the "ansi" 301 /// feature flag. 302 /// 303 /// [`with_ansi`]: Subscriber::with_ansi 304 /// [`set_ansi`]: Subscriber::set_ansi with_ansi(self, ansi: bool) -> Self305 pub fn with_ansi(self, ansi: bool) -> Self { 306 #[cfg(not(feature = "ansi"))] 307 if ansi { 308 const ERROR: &str = 309 "tracing-subscriber: the `ansi` crate feature is required to enable ANSI terminal colors"; 310 #[cfg(debug_assertions)] 311 panic!("{}", ERROR); 312 #[cfg(not(debug_assertions))] 313 eprintln!("{}", ERROR); 314 } 315 316 Self { 317 is_ansi: ansi, 318 ..self 319 } 320 } 321 322 /// Sets whether to write errors from [`FormatEvent`] to the writer. 323 /// Defaults to true. 324 /// 325 /// By default, `fmt::Layer` will write any `FormatEvent`-internal errors to 326 /// the writer. These errors are unlikely and will only occur if there is a 327 /// bug in the `FormatEvent` implementation or its dependencies. 328 /// 329 /// If writing to the writer fails, the error message is printed to stderr 330 /// as a fallback. 331 /// 332 /// [`FormatEvent`]: crate::fmt::FormatEvent log_internal_errors(self, log_internal_errors: bool) -> Self333 pub fn log_internal_errors(self, log_internal_errors: bool) -> Self { 334 Self { 335 log_internal_errors, 336 ..self 337 } 338 } 339 340 /// Updates the [`MakeWriter`] by applying a function to the existing [`MakeWriter`]. 341 /// 342 /// This sets the [`MakeWriter`] that the layer being built will use to write events. 343 /// 344 /// # Examples 345 /// 346 /// Redirect output to stderr if level is <= WARN: 347 /// 348 /// ```rust 349 /// use tracing::Level; 350 /// use tracing_subscriber::fmt::{self, writer::MakeWriterExt}; 351 /// 352 /// let stderr = std::io::stderr.with_max_level(Level::WARN); 353 /// let layer = fmt::layer() 354 /// .map_writer(move |w| stderr.or_else(w)); 355 /// # // this is necessary for type inference. 356 /// # use tracing_subscriber::Layer as _; 357 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); 358 /// ``` map_writer<W2>(self, f: impl FnOnce(W) -> W2) -> Layer<S, N, E, W2> where W2: for<'writer> MakeWriter<'writer> + 'static,359 pub fn map_writer<W2>(self, f: impl FnOnce(W) -> W2) -> Layer<S, N, E, W2> 360 where 361 W2: for<'writer> MakeWriter<'writer> + 'static, 362 { 363 Layer { 364 fmt_fields: self.fmt_fields, 365 fmt_event: self.fmt_event, 366 fmt_span: self.fmt_span, 367 is_ansi: self.is_ansi, 368 log_internal_errors: self.log_internal_errors, 369 make_writer: f(self.make_writer), 370 _inner: self._inner, 371 } 372 } 373 } 374 375 impl<S, N, L, T, W> Layer<S, N, format::Format<L, T>, W> 376 where 377 N: for<'writer> FormatFields<'writer> + 'static, 378 { 379 /// Use the given [`timer`] for span and event timestamps. 380 /// 381 /// See the [`time` module] for the provided timer implementations. 382 /// 383 /// Note that using the `"time`"" feature flag enables the 384 /// additional time formatters [`UtcTime`] and [`LocalTime`], which use the 385 /// [`time` crate] to provide more sophisticated timestamp formatting 386 /// options. 387 /// 388 /// [`timer`]: super::time::FormatTime 389 /// [`time` module]: mod@super::time 390 /// [`UtcTime`]: super::time::UtcTime 391 /// [`LocalTime`]: super::time::LocalTime 392 /// [`time` crate]: https://docs.rs/time/0.3 with_timer<T2>(self, timer: T2) -> Layer<S, N, format::Format<L, T2>, W>393 pub fn with_timer<T2>(self, timer: T2) -> Layer<S, N, format::Format<L, T2>, W> { 394 Layer { 395 fmt_event: self.fmt_event.with_timer(timer), 396 fmt_fields: self.fmt_fields, 397 fmt_span: self.fmt_span, 398 make_writer: self.make_writer, 399 is_ansi: self.is_ansi, 400 log_internal_errors: self.log_internal_errors, 401 _inner: self._inner, 402 } 403 } 404 405 /// Do not emit timestamps with spans and event. without_time(self) -> Layer<S, N, format::Format<L, ()>, W>406 pub fn without_time(self) -> Layer<S, N, format::Format<L, ()>, W> { 407 Layer { 408 fmt_event: self.fmt_event.without_time(), 409 fmt_fields: self.fmt_fields, 410 fmt_span: self.fmt_span.without_time(), 411 make_writer: self.make_writer, 412 is_ansi: self.is_ansi, 413 log_internal_errors: self.log_internal_errors, 414 _inner: self._inner, 415 } 416 } 417 418 /// Configures how synthesized events are emitted at points in the [span 419 /// lifecycle][lifecycle]. 420 /// 421 /// The following options are available: 422 /// 423 /// - `FmtSpan::NONE`: No events will be synthesized when spans are 424 /// created, entered, exited, or closed. Data from spans will still be 425 /// included as the context for formatted events. This is the default. 426 /// - `FmtSpan::NEW`: An event will be synthesized when spans are created. 427 /// - `FmtSpan::ENTER`: An event will be synthesized when spans are entered. 428 /// - `FmtSpan::EXIT`: An event will be synthesized when spans are exited. 429 /// - `FmtSpan::CLOSE`: An event will be synthesized when a span closes. If 430 /// [timestamps are enabled][time] for this formatter, the generated 431 /// event will contain fields with the span's _busy time_ (the total 432 /// time for which it was entered) and _idle time_ (the total time that 433 /// the span existed but was not entered). 434 /// - `FmtSpan::ACTIVE`: Events will be synthesized when spans are entered 435 /// or exited. 436 /// - `FmtSpan::FULL`: Events will be synthesized whenever a span is 437 /// created, entered, exited, or closed. If timestamps are enabled, the 438 /// close event will contain the span's busy and idle time, as 439 /// described above. 440 /// 441 /// The options can be enabled in any combination. For instance, the following 442 /// will synthesize events whenever spans are created and closed: 443 /// 444 /// ```rust 445 /// use tracing_subscriber::fmt; 446 /// use tracing_subscriber::fmt::format::FmtSpan; 447 /// 448 /// let subscriber = fmt() 449 /// .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE) 450 /// .finish(); 451 /// ``` 452 /// 453 /// Note that the generated events will only be part of the log output by 454 /// this formatter; they will not be recorded by other `Subscriber`s or by 455 /// `Layer`s added to this subscriber. 456 /// 457 /// [lifecycle]: https://docs.rs/tracing/latest/tracing/span/index.html#the-span-lifecycle 458 /// [time]: Layer::without_time() with_span_events(self, kind: FmtSpan) -> Self459 pub fn with_span_events(self, kind: FmtSpan) -> Self { 460 Layer { 461 fmt_span: self.fmt_span.with_kind(kind), 462 ..self 463 } 464 } 465 466 /// Sets whether or not an event's target is displayed. with_target(self, display_target: bool) -> Layer<S, N, format::Format<L, T>, W>467 pub fn with_target(self, display_target: bool) -> Layer<S, N, format::Format<L, T>, W> { 468 Layer { 469 fmt_event: self.fmt_event.with_target(display_target), 470 ..self 471 } 472 } 473 /// Sets whether or not an event's [source code file path][file] is 474 /// displayed. 475 /// 476 /// [file]: tracing_core::Metadata::file with_file(self, display_filename: bool) -> Layer<S, N, format::Format<L, T>, W>477 pub fn with_file(self, display_filename: bool) -> Layer<S, N, format::Format<L, T>, W> { 478 Layer { 479 fmt_event: self.fmt_event.with_file(display_filename), 480 ..self 481 } 482 } 483 484 /// Sets whether or not an event's [source code line number][line] is 485 /// displayed. 486 /// 487 /// [line]: tracing_core::Metadata::line with_line_number( self, display_line_number: bool, ) -> Layer<S, N, format::Format<L, T>, W>488 pub fn with_line_number( 489 self, 490 display_line_number: bool, 491 ) -> Layer<S, N, format::Format<L, T>, W> { 492 Layer { 493 fmt_event: self.fmt_event.with_line_number(display_line_number), 494 ..self 495 } 496 } 497 498 /// Sets whether or not an event's level is displayed. with_level(self, display_level: bool) -> Layer<S, N, format::Format<L, T>, W>499 pub fn with_level(self, display_level: bool) -> Layer<S, N, format::Format<L, T>, W> { 500 Layer { 501 fmt_event: self.fmt_event.with_level(display_level), 502 ..self 503 } 504 } 505 506 /// Sets whether or not the [thread ID] of the current thread is displayed 507 /// when formatting events. 508 /// 509 /// [thread ID]: std::thread::ThreadId with_thread_ids(self, display_thread_ids: bool) -> Layer<S, N, format::Format<L, T>, W>510 pub fn with_thread_ids(self, display_thread_ids: bool) -> Layer<S, N, format::Format<L, T>, W> { 511 Layer { 512 fmt_event: self.fmt_event.with_thread_ids(display_thread_ids), 513 ..self 514 } 515 } 516 517 /// Sets whether or not the [name] of the current thread is displayed 518 /// when formatting events. 519 /// 520 /// [name]: std::thread#naming-threads with_thread_names( self, display_thread_names: bool, ) -> Layer<S, N, format::Format<L, T>, W>521 pub fn with_thread_names( 522 self, 523 display_thread_names: bool, 524 ) -> Layer<S, N, format::Format<L, T>, W> { 525 Layer { 526 fmt_event: self.fmt_event.with_thread_names(display_thread_names), 527 ..self 528 } 529 } 530 531 /// Sets the layer being built to use a [less verbose formatter][super::format::Compact]. compact(self) -> Layer<S, N, format::Format<format::Compact, T>, W> where N: for<'writer> FormatFields<'writer> + 'static,532 pub fn compact(self) -> Layer<S, N, format::Format<format::Compact, T>, W> 533 where 534 N: for<'writer> FormatFields<'writer> + 'static, 535 { 536 Layer { 537 fmt_event: self.fmt_event.compact(), 538 fmt_fields: self.fmt_fields, 539 fmt_span: self.fmt_span, 540 make_writer: self.make_writer, 541 is_ansi: self.is_ansi, 542 log_internal_errors: self.log_internal_errors, 543 _inner: self._inner, 544 } 545 } 546 547 /// Sets the layer being built to use an [excessively pretty, human-readable formatter](crate::fmt::format::Pretty). 548 #[cfg(feature = "ansi")] 549 #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))] pretty(self) -> Layer<S, format::Pretty, format::Format<format::Pretty, T>, W>550 pub fn pretty(self) -> Layer<S, format::Pretty, format::Format<format::Pretty, T>, W> { 551 Layer { 552 fmt_event: self.fmt_event.pretty(), 553 fmt_fields: format::Pretty::default(), 554 fmt_span: self.fmt_span, 555 make_writer: self.make_writer, 556 is_ansi: self.is_ansi, 557 log_internal_errors: self.log_internal_errors, 558 _inner: self._inner, 559 } 560 } 561 562 /// Sets the layer being built to use a [JSON formatter][super::format::Json]. 563 /// 564 /// The full format includes fields from all entered spans. 565 /// 566 /// # Example Output 567 /// 568 /// ```ignore,json 569 /// {"timestamp":"Feb 20 11:28:15.096","level":"INFO","target":"mycrate","fields":{"message":"some message", "key": "value"}} 570 /// ``` 571 /// 572 /// # Options 573 /// 574 /// - [`Layer::flatten_event`] can be used to enable flattening event fields into the root 575 /// object. 576 /// 577 /// [`Layer::flatten_event`]: Layer::flatten_event() 578 #[cfg(feature = "json")] 579 #[cfg_attr(docsrs, doc(cfg(feature = "json")))] json(self) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W>580 pub fn json(self) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> { 581 Layer { 582 fmt_event: self.fmt_event.json(), 583 fmt_fields: format::JsonFields::new(), 584 fmt_span: self.fmt_span, 585 make_writer: self.make_writer, 586 // always disable ANSI escapes in JSON mode! 587 is_ansi: false, 588 log_internal_errors: self.log_internal_errors, 589 _inner: self._inner, 590 } 591 } 592 } 593 594 #[cfg(feature = "json")] 595 #[cfg_attr(docsrs, doc(cfg(feature = "json")))] 596 impl<S, T, W> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> { 597 /// Sets the JSON layer being built to flatten event metadata. 598 /// 599 /// See [`format::Json`][super::format::Json] flatten_event( self, flatten_event: bool, ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W>600 pub fn flatten_event( 601 self, 602 flatten_event: bool, 603 ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> { 604 Layer { 605 fmt_event: self.fmt_event.flatten_event(flatten_event), 606 fmt_fields: format::JsonFields::new(), 607 ..self 608 } 609 } 610 611 /// Sets whether or not the formatter will include the current span in 612 /// formatted events. 613 /// 614 /// See [`format::Json`][super::format::Json] with_current_span( self, display_current_span: bool, ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W>615 pub fn with_current_span( 616 self, 617 display_current_span: bool, 618 ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> { 619 Layer { 620 fmt_event: self.fmt_event.with_current_span(display_current_span), 621 fmt_fields: format::JsonFields::new(), 622 ..self 623 } 624 } 625 626 /// Sets whether or not the formatter will include a list (from root to leaf) 627 /// of all currently entered spans in formatted events. 628 /// 629 /// See [`format::Json`][super::format::Json] with_span_list( self, display_span_list: bool, ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W>630 pub fn with_span_list( 631 self, 632 display_span_list: bool, 633 ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> { 634 Layer { 635 fmt_event: self.fmt_event.with_span_list(display_span_list), 636 fmt_fields: format::JsonFields::new(), 637 ..self 638 } 639 } 640 } 641 642 impl<S, N, E, W> Layer<S, N, E, W> { 643 /// Sets the field formatter that the layer being built will use to record 644 /// fields. fmt_fields<N2>(self, fmt_fields: N2) -> Layer<S, N2, E, W> where N2: for<'writer> FormatFields<'writer> + 'static,645 pub fn fmt_fields<N2>(self, fmt_fields: N2) -> Layer<S, N2, E, W> 646 where 647 N2: for<'writer> FormatFields<'writer> + 'static, 648 { 649 Layer { 650 fmt_event: self.fmt_event, 651 fmt_fields, 652 fmt_span: self.fmt_span, 653 make_writer: self.make_writer, 654 is_ansi: self.is_ansi, 655 log_internal_errors: self.log_internal_errors, 656 _inner: self._inner, 657 } 658 } 659 660 /// Updates the field formatter by applying a function to the existing field formatter. 661 /// 662 /// This sets the field formatter that the layer being built will use to record fields. 663 /// 664 /// # Examples 665 /// 666 /// Updating a field formatter: 667 /// 668 /// ```rust 669 /// use tracing_subscriber::field::MakeExt; 670 /// let layer = tracing_subscriber::fmt::layer() 671 /// .map_fmt_fields(|f| f.debug_alt()); 672 /// # // this is necessary for type inference. 673 /// # use tracing_subscriber::Layer as _; 674 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default()); 675 /// ``` map_fmt_fields<N2>(self, f: impl FnOnce(N) -> N2) -> Layer<S, N2, E, W> where N2: for<'writer> FormatFields<'writer> + 'static,676 pub fn map_fmt_fields<N2>(self, f: impl FnOnce(N) -> N2) -> Layer<S, N2, E, W> 677 where 678 N2: for<'writer> FormatFields<'writer> + 'static, 679 { 680 Layer { 681 fmt_event: self.fmt_event, 682 fmt_fields: f(self.fmt_fields), 683 fmt_span: self.fmt_span, 684 make_writer: self.make_writer, 685 is_ansi: self.is_ansi, 686 log_internal_errors: self.log_internal_errors, 687 _inner: self._inner, 688 } 689 } 690 } 691 692 impl<S> Default for Layer<S> { default() -> Self693 fn default() -> Self { 694 // only enable ANSI when the feature is enabled, and the NO_COLOR 695 // environment variable is unset or empty. 696 let ansi = cfg!(feature = "ansi") && env::var("NO_COLOR").map_or(true, |v| v.is_empty()); 697 698 Layer { 699 fmt_fields: format::DefaultFields::default(), 700 fmt_event: format::Format::default(), 701 fmt_span: format::FmtSpanConfig::default(), 702 make_writer: io::stdout, 703 is_ansi: ansi, 704 log_internal_errors: false, 705 _inner: PhantomData, 706 } 707 } 708 } 709 710 impl<S, N, E, W> Layer<S, N, E, W> 711 where 712 S: Subscriber + for<'a> LookupSpan<'a>, 713 N: for<'writer> FormatFields<'writer> + 'static, 714 E: FormatEvent<S, N> + 'static, 715 W: for<'writer> MakeWriter<'writer> + 'static, 716 { 717 #[inline] make_ctx<'a>(&'a self, ctx: Context<'a, S>, event: &'a Event<'a>) -> FmtContext<'a, S, N>718 fn make_ctx<'a>(&'a self, ctx: Context<'a, S>, event: &'a Event<'a>) -> FmtContext<'a, S, N> { 719 FmtContext { 720 ctx, 721 fmt_fields: &self.fmt_fields, 722 event, 723 } 724 } 725 } 726 727 /// A formatted representation of a span's fields stored in its [extensions]. 728 /// 729 /// Because `FormattedFields` is generic over the type of the formatter that 730 /// produced it, multiple versions of a span's formatted fields can be stored in 731 /// the [`Extensions`][extensions] type-map. This means that when multiple 732 /// formatters are in use, each can store its own formatted representation 733 /// without conflicting. 734 /// 735 /// [extensions]: crate::registry::Extensions 736 #[derive(Default)] 737 pub struct FormattedFields<E: ?Sized> { 738 _format_fields: PhantomData<fn(E)>, 739 was_ansi: bool, 740 /// The formatted fields of a span. 741 pub fields: String, 742 } 743 744 impl<E: ?Sized> FormattedFields<E> { 745 /// Returns a new `FormattedFields`. new(fields: String) -> Self746 pub fn new(fields: String) -> Self { 747 Self { 748 fields, 749 was_ansi: false, 750 _format_fields: PhantomData, 751 } 752 } 753 754 /// Returns a new [`format::Writer`] for writing to this `FormattedFields`. 755 /// 756 /// The returned [`format::Writer`] can be used with the 757 /// [`FormatFields::format_fields`] method. as_writer(&mut self) -> format::Writer<'_>758 pub fn as_writer(&mut self) -> format::Writer<'_> { 759 format::Writer::new(&mut self.fields).with_ansi(self.was_ansi) 760 } 761 } 762 763 impl<E: ?Sized> fmt::Debug for FormattedFields<E> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result764 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 765 f.debug_struct("FormattedFields") 766 .field("fields", &self.fields) 767 .field("formatter", &format_args!("{}", std::any::type_name::<E>())) 768 .field("was_ansi", &self.was_ansi) 769 .finish() 770 } 771 } 772 773 impl<E: ?Sized> fmt::Display for FormattedFields<E> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result774 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 775 fmt::Display::fmt(&self.fields, f) 776 } 777 } 778 779 impl<E: ?Sized> Deref for FormattedFields<E> { 780 type Target = String; deref(&self) -> &Self::Target781 fn deref(&self) -> &Self::Target { 782 &self.fields 783 } 784 } 785 786 // === impl FmtLayer === 787 788 macro_rules! with_event_from_span { 789 ($id:ident, $span:ident, $($field:literal = $value:expr),*, |$event:ident| $code:block) => { 790 let meta = $span.metadata(); 791 let cs = meta.callsite(); 792 let fs = field::FieldSet::new(&[$($field),*], cs); 793 #[allow(unused)] 794 let mut iter = fs.iter(); 795 let v = [$( 796 (&iter.next().unwrap(), ::core::option::Option::Some(&$value as &dyn field::Value)), 797 )*]; 798 let vs = fs.value_set(&v); 799 let $event = Event::new_child_of($id, meta, &vs); 800 $code 801 }; 802 } 803 804 impl<S, N, E, W> layer::Layer<S> for Layer<S, N, E, W> 805 where 806 S: Subscriber + for<'a> LookupSpan<'a>, 807 N: for<'writer> FormatFields<'writer> + 'static, 808 E: FormatEvent<S, N> + 'static, 809 W: for<'writer> MakeWriter<'writer> + 'static, 810 { on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)811 fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { 812 let span = ctx.span(id).expect("Span not found, this is a bug"); 813 let mut extensions = span.extensions_mut(); 814 815 if extensions.get_mut::<FormattedFields<N>>().is_none() { 816 let mut fields = FormattedFields::<N>::new(String::new()); 817 if self 818 .fmt_fields 819 .format_fields(fields.as_writer().with_ansi(self.is_ansi), attrs) 820 .is_ok() 821 { 822 fields.was_ansi = self.is_ansi; 823 extensions.insert(fields); 824 } else { 825 eprintln!( 826 "[tracing-subscriber] Unable to format the following event, ignoring: {:?}", 827 attrs 828 ); 829 } 830 } 831 832 if self.fmt_span.fmt_timing 833 && self.fmt_span.trace_close() 834 && extensions.get_mut::<Timings>().is_none() 835 { 836 extensions.insert(Timings::new()); 837 } 838 839 if self.fmt_span.trace_new() { 840 with_event_from_span!(id, span, "message" = "new", |event| { 841 drop(extensions); 842 drop(span); 843 self.on_event(&event, ctx); 844 }); 845 } 846 } 847 on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>)848 fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) { 849 let span = ctx.span(id).expect("Span not found, this is a bug"); 850 let mut extensions = span.extensions_mut(); 851 if let Some(fields) = extensions.get_mut::<FormattedFields<N>>() { 852 let _ = self.fmt_fields.add_fields(fields, values); 853 return; 854 } 855 856 let mut fields = FormattedFields::<N>::new(String::new()); 857 if self 858 .fmt_fields 859 .format_fields(fields.as_writer().with_ansi(self.is_ansi), values) 860 .is_ok() 861 { 862 fields.was_ansi = self.is_ansi; 863 extensions.insert(fields); 864 } 865 } 866 on_enter(&self, id: &Id, ctx: Context<'_, S>)867 fn on_enter(&self, id: &Id, ctx: Context<'_, S>) { 868 if self.fmt_span.trace_enter() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing { 869 let span = ctx.span(id).expect("Span not found, this is a bug"); 870 let mut extensions = span.extensions_mut(); 871 if let Some(timings) = extensions.get_mut::<Timings>() { 872 let now = Instant::now(); 873 timings.idle += (now - timings.last).as_nanos() as u64; 874 timings.last = now; 875 } 876 877 if self.fmt_span.trace_enter() { 878 with_event_from_span!(id, span, "message" = "enter", |event| { 879 drop(extensions); 880 drop(span); 881 self.on_event(&event, ctx); 882 }); 883 } 884 } 885 } 886 on_exit(&self, id: &Id, ctx: Context<'_, S>)887 fn on_exit(&self, id: &Id, ctx: Context<'_, S>) { 888 if self.fmt_span.trace_exit() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing { 889 let span = ctx.span(id).expect("Span not found, this is a bug"); 890 let mut extensions = span.extensions_mut(); 891 if let Some(timings) = extensions.get_mut::<Timings>() { 892 let now = Instant::now(); 893 timings.busy += (now - timings.last).as_nanos() as u64; 894 timings.last = now; 895 } 896 897 if self.fmt_span.trace_exit() { 898 with_event_from_span!(id, span, "message" = "exit", |event| { 899 drop(extensions); 900 drop(span); 901 self.on_event(&event, ctx); 902 }); 903 } 904 } 905 } 906 on_close(&self, id: Id, ctx: Context<'_, S>)907 fn on_close(&self, id: Id, ctx: Context<'_, S>) { 908 if self.fmt_span.trace_close() { 909 let span = ctx.span(&id).expect("Span not found, this is a bug"); 910 let extensions = span.extensions(); 911 if let Some(timing) = extensions.get::<Timings>() { 912 let Timings { 913 busy, 914 mut idle, 915 last, 916 } = *timing; 917 idle += (Instant::now() - last).as_nanos() as u64; 918 919 let t_idle = field::display(TimingDisplay(idle)); 920 let t_busy = field::display(TimingDisplay(busy)); 921 922 with_event_from_span!( 923 id, 924 span, 925 "message" = "close", 926 "time.busy" = t_busy, 927 "time.idle" = t_idle, 928 |event| { 929 drop(extensions); 930 drop(span); 931 self.on_event(&event, ctx); 932 } 933 ); 934 } else { 935 with_event_from_span!(id, span, "message" = "close", |event| { 936 drop(extensions); 937 drop(span); 938 self.on_event(&event, ctx); 939 }); 940 } 941 } 942 } 943 on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)944 fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { 945 thread_local! { 946 static BUF: RefCell<String> = RefCell::new(String::new()); 947 } 948 949 BUF.with(|buf| { 950 let borrow = buf.try_borrow_mut(); 951 let mut a; 952 let mut b; 953 let mut buf = match borrow { 954 Ok(buf) => { 955 a = buf; 956 &mut *a 957 } 958 _ => { 959 b = String::new(); 960 &mut b 961 } 962 }; 963 964 let ctx = self.make_ctx(ctx, event); 965 if self 966 .fmt_event 967 .format_event( 968 &ctx, 969 format::Writer::new(&mut buf).with_ansi(self.is_ansi), 970 event, 971 ) 972 .is_ok() 973 { 974 let mut writer = self.make_writer.make_writer_for(event.metadata()); 975 let res = io::Write::write_all(&mut writer, buf.as_bytes()); 976 if self.log_internal_errors { 977 if let Err(e) = res { 978 eprintln!("[tracing-subscriber] Unable to write an event to the Writer for this Subscriber! Error: {}\n", e); 979 } 980 } 981 } else if self.log_internal_errors { 982 let err_msg = format!("Unable to format the following event. Name: {}; Fields: {:?}\n", 983 event.metadata().name(), event.fields()); 984 let mut writer = self.make_writer.make_writer_for(event.metadata()); 985 let res = io::Write::write_all(&mut writer, err_msg.as_bytes()); 986 if let Err(e) = res { 987 eprintln!("[tracing-subscriber] Unable to write an \"event formatting error\" to the Writer for this Subscriber! Error: {}\n", e); 988 } 989 } 990 991 buf.clear(); 992 }); 993 } 994 downcast_raw(&self, id: TypeId) -> Option<*const ()>995 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { 996 // This `downcast_raw` impl allows downcasting a `fmt` layer to any of 997 // its components (event formatter, field formatter, and `MakeWriter`) 998 // as well as to the layer's type itself. The potential use-cases for 999 // this *may* be somewhat niche, though... 1000 match () { 1001 _ if id == TypeId::of::<Self>() => Some(self as *const Self as *const ()), 1002 _ if id == TypeId::of::<E>() => Some(&self.fmt_event as *const E as *const ()), 1003 _ if id == TypeId::of::<N>() => Some(&self.fmt_fields as *const N as *const ()), 1004 _ if id == TypeId::of::<W>() => Some(&self.make_writer as *const W as *const ()), 1005 _ => None, 1006 } 1007 } 1008 } 1009 1010 /// Provides the current span context to a formatter. 1011 pub struct FmtContext<'a, S, N> { 1012 pub(crate) ctx: Context<'a, S>, 1013 pub(crate) fmt_fields: &'a N, 1014 pub(crate) event: &'a Event<'a>, 1015 } 1016 1017 impl<'a, S, N> fmt::Debug for FmtContext<'a, S, N> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1018 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1019 f.debug_struct("FmtContext").finish() 1020 } 1021 } 1022 1023 impl<'cx, 'writer, S, N> FormatFields<'writer> for FmtContext<'cx, S, N> 1024 where 1025 S: Subscriber + for<'lookup> LookupSpan<'lookup>, 1026 N: FormatFields<'writer> + 'static, 1027 { format_fields<R: RecordFields>( &self, writer: format::Writer<'writer>, fields: R, ) -> fmt::Result1028 fn format_fields<R: RecordFields>( 1029 &self, 1030 writer: format::Writer<'writer>, 1031 fields: R, 1032 ) -> fmt::Result { 1033 self.fmt_fields.format_fields(writer, fields) 1034 } 1035 } 1036 1037 impl<'a, S, N> FmtContext<'a, S, N> 1038 where 1039 S: Subscriber + for<'lookup> LookupSpan<'lookup>, 1040 N: for<'writer> FormatFields<'writer> + 'static, 1041 { 1042 /// Visits every span in the current context with a closure. 1043 /// 1044 /// The provided closure will be called first with the current span, 1045 /// and then with that span's parent, and then that span's parent, 1046 /// and so on until a root span is reached. visit_spans<E, F>(&self, mut f: F) -> Result<(), E> where F: FnMut(&SpanRef<'_, S>) -> Result<(), E>,1047 pub fn visit_spans<E, F>(&self, mut f: F) -> Result<(), E> 1048 where 1049 F: FnMut(&SpanRef<'_, S>) -> Result<(), E>, 1050 { 1051 // visit all the current spans 1052 if let Some(scope) = self.event_scope() { 1053 for span in scope.from_root() { 1054 f(&span)?; 1055 } 1056 } 1057 Ok(()) 1058 } 1059 1060 /// Returns metadata for the span with the given `id`, if it exists. 1061 /// 1062 /// If this returns `None`, then no span exists for that ID (either it has 1063 /// closed or the ID is invalid). 1064 #[inline] metadata(&self, id: &Id) -> Option<&'static Metadata<'static>> where S: for<'lookup> LookupSpan<'lookup>,1065 pub fn metadata(&self, id: &Id) -> Option<&'static Metadata<'static>> 1066 where 1067 S: for<'lookup> LookupSpan<'lookup>, 1068 { 1069 self.ctx.metadata(id) 1070 } 1071 1072 /// Returns [stored data] for the span with the given `id`, if it exists. 1073 /// 1074 /// If this returns `None`, then no span exists for that ID (either it has 1075 /// closed or the ID is invalid). 1076 /// 1077 /// [stored data]: crate::registry::SpanRef 1078 #[inline] span(&self, id: &Id) -> Option<SpanRef<'_, S>> where S: for<'lookup> LookupSpan<'lookup>,1079 pub fn span(&self, id: &Id) -> Option<SpanRef<'_, S>> 1080 where 1081 S: for<'lookup> LookupSpan<'lookup>, 1082 { 1083 self.ctx.span(id) 1084 } 1085 1086 /// Returns `true` if an active span exists for the given `Id`. 1087 #[inline] exists(&self, id: &Id) -> bool where S: for<'lookup> LookupSpan<'lookup>,1088 pub fn exists(&self, id: &Id) -> bool 1089 where 1090 S: for<'lookup> LookupSpan<'lookup>, 1091 { 1092 self.ctx.exists(id) 1093 } 1094 1095 /// Returns [stored data] for the span that the wrapped subscriber considers 1096 /// to be the current. 1097 /// 1098 /// If this returns `None`, then we are not currently within a span. 1099 /// 1100 /// [stored data]: crate::registry::SpanRef 1101 #[inline] lookup_current(&self) -> Option<SpanRef<'_, S>> where S: for<'lookup> LookupSpan<'lookup>,1102 pub fn lookup_current(&self) -> Option<SpanRef<'_, S>> 1103 where 1104 S: for<'lookup> LookupSpan<'lookup>, 1105 { 1106 self.ctx.lookup_current() 1107 } 1108 1109 /// Returns the current span for this formatter. current_span(&self) -> Current1110 pub fn current_span(&self) -> Current { 1111 self.ctx.current_span() 1112 } 1113 1114 /// Returns [stored data] for the parent span of the event currently being 1115 /// formatted. 1116 /// 1117 /// If the event has a contextual parent, this will return the current span. If 1118 /// the event has an explicit parent span, this will return that span. If 1119 /// the event does not have a parent span, this will return `None`. 1120 /// 1121 /// [stored data]: SpanRef parent_span(&self) -> Option<SpanRef<'_, S>>1122 pub fn parent_span(&self) -> Option<SpanRef<'_, S>> { 1123 self.ctx.event_span(self.event) 1124 } 1125 1126 /// Returns an iterator over the [stored data] for all the spans in the 1127 /// current context, starting with the specified span and ending with the 1128 /// root of the trace tree and ending with the current span. 1129 /// 1130 /// This is equivalent to the [`Context::span_scope`] method. 1131 /// 1132 /// <div class="information"> 1133 /// <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div> 1134 /// </div> 1135 /// <div class="example-wrap" style="display:inline-block"> 1136 /// <pre class="ignore" style="white-space:normal;font:inherit;"> 1137 /// <strong>Note</strong>: Compared to <a href="#method.scope"><code>scope</code></a> this 1138 /// returns the spans in reverse order (from leaf to root). Use 1139 /// <a href="../registry/struct.Scope.html#method.from_root"><code>Scope::from_root</code></a> 1140 /// in case root-to-leaf ordering is desired. 1141 /// </pre></div> 1142 /// 1143 /// <div class="example-wrap" style="display:inline-block"> 1144 /// <pre class="ignore" style="white-space:normal;font:inherit;"> 1145 /// <strong>Note</strong>: This requires the wrapped subscriber to implement the 1146 /// <a href="../registry/trait.LookupSpan.html"><code>LookupSpan</code></a> trait. 1147 /// See the documentation on <a href="./struct.Context.html"><code>Context</code>'s 1148 /// declaration</a> for details. 1149 /// </pre></div> 1150 /// 1151 /// [stored data]: crate::registry::SpanRef span_scope(&self, id: &Id) -> Option<registry::Scope<'_, S>> where S: for<'lookup> LookupSpan<'lookup>,1152 pub fn span_scope(&self, id: &Id) -> Option<registry::Scope<'_, S>> 1153 where 1154 S: for<'lookup> LookupSpan<'lookup>, 1155 { 1156 self.ctx.span_scope(id) 1157 } 1158 1159 /// Returns an iterator over the [stored data] for all the spans in the 1160 /// event's span context, starting with its parent span and ending with the 1161 /// root of the trace tree. 1162 /// 1163 /// This is equivalent to calling the [`Context::event_scope`] method and 1164 /// passing the event currently being formatted. 1165 /// 1166 /// <div class="example-wrap" style="display:inline-block"> 1167 /// <pre class="ignore" style="white-space:normal;font:inherit;"> 1168 /// <strong>Note</strong>: Compared to <a href="#method.scope"><code>scope</code></a> this 1169 /// returns the spans in reverse order (from leaf to root). Use 1170 /// <a href="../registry/struct.Scope.html#method.from_root"><code>Scope::from_root</code></a> 1171 /// in case root-to-leaf ordering is desired. 1172 /// </pre></div> 1173 /// 1174 /// <div class="example-wrap" style="display:inline-block"> 1175 /// <pre class="ignore" style="white-space:normal;font:inherit;"> 1176 /// <strong>Note</strong>: This requires the wrapped subscriber to implement the 1177 /// <a href="../registry/trait.LookupSpan.html"><code>LookupSpan</code></a> trait. 1178 /// See the documentation on <a href="./struct.Context.html"><code>Context</code>'s 1179 /// declaration</a> for details. 1180 /// </pre></div> 1181 /// 1182 /// [stored data]: crate::registry::SpanRef event_scope(&self) -> Option<registry::Scope<'_, S>> where S: for<'lookup> registry::LookupSpan<'lookup>,1183 pub fn event_scope(&self) -> Option<registry::Scope<'_, S>> 1184 where 1185 S: for<'lookup> registry::LookupSpan<'lookup>, 1186 { 1187 self.ctx.event_scope(self.event) 1188 } 1189 1190 /// Returns the [field formatter] configured by the subscriber invoking 1191 /// `format_event`. 1192 /// 1193 /// The event formatter may use the returned field formatter to format the 1194 /// fields of any events it records. 1195 /// 1196 /// [field formatter]: FormatFields field_format(&self) -> &N1197 pub fn field_format(&self) -> &N { 1198 self.fmt_fields 1199 } 1200 } 1201 1202 struct Timings { 1203 idle: u64, 1204 busy: u64, 1205 last: Instant, 1206 } 1207 1208 impl Timings { new() -> Self1209 fn new() -> Self { 1210 Self { 1211 idle: 0, 1212 busy: 0, 1213 last: Instant::now(), 1214 } 1215 } 1216 } 1217 1218 #[cfg(test)] 1219 mod test { 1220 use super::*; 1221 use crate::fmt::{ 1222 self, 1223 format::{self, test::MockTime, Format}, 1224 layer::Layer as _, 1225 test::{MockMakeWriter, MockWriter}, 1226 time, 1227 }; 1228 use crate::Registry; 1229 use format::FmtSpan; 1230 use regex::Regex; 1231 use tracing::subscriber::with_default; 1232 use tracing_core::dispatcher::Dispatch; 1233 1234 #[test] impls()1235 fn impls() { 1236 let f = Format::default().with_timer(time::Uptime::default()); 1237 let fmt = fmt::Layer::default().event_format(f); 1238 let subscriber = fmt.with_subscriber(Registry::default()); 1239 let _dispatch = Dispatch::new(subscriber); 1240 1241 let f = format::Format::default(); 1242 let fmt = fmt::Layer::default().event_format(f); 1243 let subscriber = fmt.with_subscriber(Registry::default()); 1244 let _dispatch = Dispatch::new(subscriber); 1245 1246 let f = format::Format::default().compact(); 1247 let fmt = fmt::Layer::default().event_format(f); 1248 let subscriber = fmt.with_subscriber(Registry::default()); 1249 let _dispatch = Dispatch::new(subscriber); 1250 } 1251 1252 #[test] fmt_layer_downcasts()1253 fn fmt_layer_downcasts() { 1254 let f = format::Format::default(); 1255 let fmt = fmt::Layer::default().event_format(f); 1256 let subscriber = fmt.with_subscriber(Registry::default()); 1257 1258 let dispatch = Dispatch::new(subscriber); 1259 assert!(dispatch.downcast_ref::<fmt::Layer<Registry>>().is_some()); 1260 } 1261 1262 #[test] fmt_layer_downcasts_to_parts()1263 fn fmt_layer_downcasts_to_parts() { 1264 let f = format::Format::default(); 1265 let fmt = fmt::Layer::default().event_format(f); 1266 let subscriber = fmt.with_subscriber(Registry::default()); 1267 let dispatch = Dispatch::new(subscriber); 1268 assert!(dispatch.downcast_ref::<format::DefaultFields>().is_some()); 1269 assert!(dispatch.downcast_ref::<format::Format>().is_some()) 1270 } 1271 1272 #[test] is_lookup_span()1273 fn is_lookup_span() { 1274 fn assert_lookup_span<T: for<'a> crate::registry::LookupSpan<'a>>(_: T) {} 1275 let fmt = fmt::Layer::default(); 1276 let subscriber = fmt.with_subscriber(Registry::default()); 1277 assert_lookup_span(subscriber) 1278 } 1279 sanitize_timings(s: String) -> String1280 fn sanitize_timings(s: String) -> String { 1281 let re = Regex::new("time\\.(idle|busy)=([0-9.]+)[mµn]s").unwrap(); 1282 re.replace_all(s.as_str(), "timing").to_string() 1283 } 1284 1285 #[test] format_error_print_to_stderr()1286 fn format_error_print_to_stderr() { 1287 struct AlwaysError; 1288 1289 impl std::fmt::Debug for AlwaysError { 1290 fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 1291 Err(std::fmt::Error) 1292 } 1293 } 1294 1295 let make_writer = MockMakeWriter::default(); 1296 let subscriber = crate::fmt::Subscriber::builder() 1297 .with_writer(make_writer.clone()) 1298 .with_level(false) 1299 .with_ansi(false) 1300 .with_timer(MockTime) 1301 .finish(); 1302 1303 with_default(subscriber, || { 1304 tracing::info!(?AlwaysError); 1305 }); 1306 let actual = sanitize_timings(make_writer.get_string()); 1307 1308 // Only assert the start because the line number and callsite may change. 1309 let expected = concat!( 1310 "Unable to format the following event. Name: event ", 1311 file!(), 1312 ":" 1313 ); 1314 assert!( 1315 actual.as_str().starts_with(expected), 1316 "\nactual = {}\nshould start with expected = {}\n", 1317 actual, 1318 expected 1319 ); 1320 } 1321 1322 #[test] format_error_ignore_if_log_internal_errors_is_false()1323 fn format_error_ignore_if_log_internal_errors_is_false() { 1324 struct AlwaysError; 1325 1326 impl std::fmt::Debug for AlwaysError { 1327 fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 1328 Err(std::fmt::Error) 1329 } 1330 } 1331 1332 let make_writer = MockMakeWriter::default(); 1333 let subscriber = crate::fmt::Subscriber::builder() 1334 .with_writer(make_writer.clone()) 1335 .with_level(false) 1336 .with_ansi(false) 1337 .with_timer(MockTime) 1338 .log_internal_errors(false) 1339 .finish(); 1340 1341 with_default(subscriber, || { 1342 tracing::info!(?AlwaysError); 1343 }); 1344 let actual = sanitize_timings(make_writer.get_string()); 1345 assert_eq!("", actual.as_str()); 1346 } 1347 1348 #[test] synthesize_span_none()1349 fn synthesize_span_none() { 1350 let make_writer = MockMakeWriter::default(); 1351 let subscriber = crate::fmt::Subscriber::builder() 1352 .with_writer(make_writer.clone()) 1353 .with_level(false) 1354 .with_ansi(false) 1355 .with_timer(MockTime) 1356 // check that FmtSpan::NONE is the default 1357 .finish(); 1358 1359 with_default(subscriber, || { 1360 let span1 = tracing::info_span!("span1", x = 42); 1361 let _e = span1.enter(); 1362 }); 1363 let actual = sanitize_timings(make_writer.get_string()); 1364 assert_eq!("", actual.as_str()); 1365 } 1366 1367 #[test] synthesize_span_active()1368 fn synthesize_span_active() { 1369 let make_writer = MockMakeWriter::default(); 1370 let subscriber = crate::fmt::Subscriber::builder() 1371 .with_writer(make_writer.clone()) 1372 .with_level(false) 1373 .with_ansi(false) 1374 .with_timer(MockTime) 1375 .with_span_events(FmtSpan::ACTIVE) 1376 .finish(); 1377 1378 with_default(subscriber, || { 1379 let span1 = tracing::info_span!("span1", x = 42); 1380 let _e = span1.enter(); 1381 }); 1382 let actual = sanitize_timings(make_writer.get_string()); 1383 assert_eq!( 1384 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\ 1385 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n", 1386 actual.as_str() 1387 ); 1388 } 1389 1390 #[test] synthesize_span_close()1391 fn synthesize_span_close() { 1392 let make_writer = MockMakeWriter::default(); 1393 let subscriber = crate::fmt::Subscriber::builder() 1394 .with_writer(make_writer.clone()) 1395 .with_level(false) 1396 .with_ansi(false) 1397 .with_timer(MockTime) 1398 .with_span_events(FmtSpan::CLOSE) 1399 .finish(); 1400 1401 with_default(subscriber, || { 1402 let span1 = tracing::info_span!("span1", x = 42); 1403 let _e = span1.enter(); 1404 }); 1405 let actual = sanitize_timings(make_writer.get_string()); 1406 assert_eq!( 1407 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n", 1408 actual.as_str() 1409 ); 1410 } 1411 1412 #[test] synthesize_span_close_no_timing()1413 fn synthesize_span_close_no_timing() { 1414 let make_writer = MockMakeWriter::default(); 1415 let subscriber = crate::fmt::Subscriber::builder() 1416 .with_writer(make_writer.clone()) 1417 .with_level(false) 1418 .with_ansi(false) 1419 .with_timer(MockTime) 1420 .without_time() 1421 .with_span_events(FmtSpan::CLOSE) 1422 .finish(); 1423 1424 with_default(subscriber, || { 1425 let span1 = tracing::info_span!("span1", x = 42); 1426 let _e = span1.enter(); 1427 }); 1428 let actual = sanitize_timings(make_writer.get_string()); 1429 assert_eq!( 1430 "span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close\n", 1431 actual.as_str() 1432 ); 1433 } 1434 1435 #[test] synthesize_span_full()1436 fn synthesize_span_full() { 1437 let make_writer = MockMakeWriter::default(); 1438 let subscriber = crate::fmt::Subscriber::builder() 1439 .with_writer(make_writer.clone()) 1440 .with_level(false) 1441 .with_ansi(false) 1442 .with_timer(MockTime) 1443 .with_span_events(FmtSpan::FULL) 1444 .finish(); 1445 1446 with_default(subscriber, || { 1447 let span1 = tracing::info_span!("span1", x = 42); 1448 let _e = span1.enter(); 1449 }); 1450 let actual = sanitize_timings(make_writer.get_string()); 1451 assert_eq!( 1452 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: new\n\ 1453 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\ 1454 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n\ 1455 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n", 1456 actual.as_str() 1457 ); 1458 } 1459 1460 #[test] make_writer_based_on_meta()1461 fn make_writer_based_on_meta() { 1462 struct MakeByTarget { 1463 make_writer1: MockMakeWriter, 1464 make_writer2: MockMakeWriter, 1465 } 1466 1467 impl<'a> MakeWriter<'a> for MakeByTarget { 1468 type Writer = MockWriter; 1469 1470 fn make_writer(&'a self) -> Self::Writer { 1471 self.make_writer1.make_writer() 1472 } 1473 1474 fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { 1475 if meta.target() == "writer2" { 1476 return self.make_writer2.make_writer(); 1477 } 1478 self.make_writer() 1479 } 1480 } 1481 1482 let make_writer1 = MockMakeWriter::default(); 1483 let make_writer2 = MockMakeWriter::default(); 1484 1485 let make_writer = MakeByTarget { 1486 make_writer1: make_writer1.clone(), 1487 make_writer2: make_writer2.clone(), 1488 }; 1489 1490 let subscriber = crate::fmt::Subscriber::builder() 1491 .with_writer(make_writer) 1492 .with_level(false) 1493 .with_target(false) 1494 .with_ansi(false) 1495 .with_timer(MockTime) 1496 .with_span_events(FmtSpan::CLOSE) 1497 .finish(); 1498 1499 with_default(subscriber, || { 1500 let span1 = tracing::info_span!("writer1_span", x = 42); 1501 let _e = span1.enter(); 1502 tracing::info!(target: "writer2", "hello writer2!"); 1503 let span2 = tracing::info_span!(target: "writer2", "writer2_span"); 1504 let _e = span2.enter(); 1505 tracing::warn!(target: "writer1", "hello writer1!"); 1506 }); 1507 1508 let actual = sanitize_timings(make_writer1.get_string()); 1509 assert_eq!( 1510 "fake time writer1_span{x=42}:writer2_span: hello writer1!\n\ 1511 fake time writer1_span{x=42}: close timing timing\n", 1512 actual.as_str() 1513 ); 1514 let actual = sanitize_timings(make_writer2.get_string()); 1515 assert_eq!( 1516 "fake time writer1_span{x=42}: hello writer2!\n\ 1517 fake time writer1_span{x=42}:writer2_span: close timing timing\n", 1518 actual.as_str() 1519 ); 1520 } 1521 1522 // Because we need to modify an environment variable for these test cases, 1523 // we do them all in a single test. 1524 #[cfg(feature = "ansi")] 1525 #[test] layer_no_color()1526 fn layer_no_color() { 1527 const NO_COLOR: &str = "NO_COLOR"; 1528 1529 // Restores the previous value of the `NO_COLOR` env variable when 1530 // dropped. 1531 // 1532 // This is done in a `Drop` implementation, rather than just resetting 1533 // the value at the end of the test, so that the previous value is 1534 // restored even if the test panics. 1535 struct RestoreEnvVar(Result<String, env::VarError>); 1536 impl Drop for RestoreEnvVar { 1537 fn drop(&mut self) { 1538 match self.0 { 1539 Ok(ref var) => env::set_var(NO_COLOR, var), 1540 Err(_) => env::remove_var(NO_COLOR), 1541 } 1542 } 1543 } 1544 1545 let _saved_no_color = RestoreEnvVar(env::var(NO_COLOR)); 1546 1547 let cases: Vec<(Option<&str>, bool)> = vec![ 1548 (Some("0"), false), // any non-empty value disables ansi 1549 (Some("off"), false), // any non-empty value disables ansi 1550 (Some("1"), false), 1551 (Some(""), true), // empty value does not disable ansi 1552 (None, true), 1553 ]; 1554 1555 for (var, ansi) in cases { 1556 if let Some(value) = var { 1557 env::set_var(NO_COLOR, value); 1558 } else { 1559 env::remove_var(NO_COLOR); 1560 } 1561 1562 let layer: Layer<()> = fmt::Layer::default(); 1563 assert_eq!( 1564 layer.is_ansi, ansi, 1565 "NO_COLOR={:?}; Layer::default().is_ansi should be {}", 1566 var, ansi 1567 ); 1568 1569 // with_ansi should override any `NO_COLOR` value 1570 let layer: Layer<()> = fmt::Layer::default().with_ansi(true); 1571 assert!( 1572 layer.is_ansi, 1573 "NO_COLOR={:?}; Layer::default().with_ansi(true).is_ansi should be true", 1574 var 1575 ); 1576 1577 // set_ansi should override any `NO_COLOR` value 1578 let mut layer: Layer<()> = fmt::Layer::default(); 1579 layer.set_ansi(true); 1580 assert!( 1581 layer.is_ansi, 1582 "NO_COLOR={:?}; layer.set_ansi(true); layer.is_ansi should be true", 1583 var 1584 ); 1585 } 1586 1587 // dropping `_saved_no_color` will restore the previous value of 1588 // `NO_COLOR`. 1589 } 1590 } 1591