|
396 | 396 | //! # Ok(()) } |
397 | 397 | //! ``` |
398 | 398 | //! |
| 399 | +//! |
| 400 | +//! ## Runtime Configuration With Subscribers |
| 401 | +//! |
| 402 | +//! In some cases, a particular [subscriber] may be enabled or disabled based on |
| 403 | +//! runtime configuration. This can introduce challenges, because the type of a |
| 404 | +//! layered [collector] depends on which subscribers are added to it: if an `if` |
| 405 | +//! or `match` expression adds some [`Subscribe`] implementation in one branch, |
| 406 | +//! and other subscribers in another, the [collector] values returned by those |
| 407 | +//! branches will have different types. For example, the following _will not_ |
| 408 | +//! work: |
| 409 | +//! |
| 410 | +//! ```compile_fail |
| 411 | +//! # fn docs() -> Result<(), Box<dyn std::error::Error + 'static>> { |
| 412 | +//! # struct Config { |
| 413 | +//! # is_prod: bool, |
| 414 | +//! # path: &'static str, |
| 415 | +//! # } |
| 416 | +//! # let cfg = Config { is_prod: false, path: "debug.log" }; |
| 417 | +//! use std::fs::File; |
| 418 | +//! use tracing_subscriber::{Registry, prelude::*}; |
| 419 | +//! |
| 420 | +//! let stdout_log = tracing_subscriber::fmt::subscriber().pretty(); |
| 421 | +//! let collector = Registry::default().with(stdout_log); |
| 422 | +//! |
| 423 | +//! // The compile error will occur here because the if and else |
| 424 | +//! // branches have different (and therefore incompatible) types. |
| 425 | +//! let collector = if cfg.is_prod { |
| 426 | +//! let file = File::create(cfg.path)?; |
| 427 | +//! let collector = tracing_subscriber::fmt::subscriber() |
| 428 | +//! .json() |
| 429 | +//! .with_writer(Arc::new(file)); |
| 430 | +//! collector.with(subscriber) |
| 431 | +//! } else { |
| 432 | +//! collector |
| 433 | +//! }; |
| 434 | +//! |
| 435 | +//! tracing::collect::set_global_default(collector) |
| 436 | +//! .expect("Unable to set global collector"); |
| 437 | +//! # Ok(()) } |
| 438 | +//! ``` |
| 439 | +//! |
| 440 | +//! However, a [`Subscribe`] wrapped in an [`Option`] [also implements the `Subscribe` |
| 441 | +//! trait][option-impl]. This allows individual layers to be enabled or disabled at |
| 442 | +//! runtime while always producing a [`Collect`] of the same type. For |
| 443 | +//! example: |
| 444 | +//! |
| 445 | +//! ``` |
| 446 | +//! # fn docs() -> Result<(), Box<dyn std::error::Error + 'static>> { |
| 447 | +//! # struct Config { |
| 448 | +//! # is_prod: bool, |
| 449 | +//! # path: &'static str, |
| 450 | +//! # } |
| 451 | +//! # let cfg = Config { is_prod: false, path: "debug.log" }; |
| 452 | +//! use std::fs::File; |
| 453 | +//! use tracing_subscriber::{Registry, prelude::*}; |
| 454 | +//! |
| 455 | +//! let stdout_log = tracing_subscriber::fmt::subscriber().pretty(); |
| 456 | +//! let collector = Registry::default().with(stdout_log); |
| 457 | +//! |
| 458 | +//! // if `cfg.is_prod` is true, also log JSON-formatted logs to a file. |
| 459 | +//! let json_log = if cfg.is_prod { |
| 460 | +//! let file = File::create(cfg.path)?; |
| 461 | +//! let json_log = tracing_subscriber::fmt::subscriber() |
| 462 | +//! .json() |
| 463 | +//! .with_writer(file); |
| 464 | +//! Some(json_log) |
| 465 | +//! } else { |
| 466 | +//! None |
| 467 | +//! }; |
| 468 | +//! |
| 469 | +//! // If `cfg.is_prod` is false, then `json` will be `None`, and this subscriber |
| 470 | +//! // will do nothing. However, the collector will still have the same type |
| 471 | +//! // regardless of whether the `Option`'s value is `None` or `Some`. |
| 472 | +//! let collector = collector.with(json_log); |
| 473 | +//! |
| 474 | +//! tracing::collect::set_global_default(collector) |
| 475 | +//! .expect("Unable to set global collector"); |
| 476 | +//! # Ok(()) } |
| 477 | +//! ``` |
399 | 478 | //! [subscriber]: Subscribe |
400 | 479 | //! [`Collect`]:tracing_core::Collect |
401 | 480 | //! [collector]: tracing_core::Collect |
|
407 | 486 | //! [`Subscribe::register_callsite`]: Subscribe::register_callsite |
408 | 487 | //! [`Subscribe::enabled`]: Subscribe::enabled |
409 | 488 | //! [`Interest::never()`]: tracing_core::collect::Interest::never |
| 489 | +//! [option-impl]: crate::subscribe::Subscribe#impl-Subscribe<C>-for-Option<S> |
410 | 490 | //! [`Filtered`]: crate::filter::Filtered |
411 | 491 | //! [`filter`]: crate::filter |
412 | 492 | //! [`Targets`]: crate::filter::Targets |
|
0 commit comments