xref: /third_party/rust/crates/log/src/lib.rs (revision 2d8ae3ab)
1// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! A lightweight logging facade.
12//!
13//! The `log` crate provides a single logging API that abstracts over the
14//! actual logging implementation. Libraries can use the logging API provided
15//! by this crate, and the consumer of those libraries can choose the logging
16//! implementation that is most suitable for its use case.
17//!
18//! If no logging implementation is selected, the facade falls back to a "noop"
19//! implementation that ignores all log messages. The overhead in this case
20//! is very small - just an integer load, comparison and jump.
21//!
22//! A log request consists of a _target_, a _level_, and a _body_. A target is a
23//! string which defaults to the module path of the location of the log request,
24//! though that default may be overridden. Logger implementations typically use
25//! the target to filter requests based on some user configuration.
26//!
27//! # Usage
28//!
29//! The basic use of the log crate is through the five logging macros: [`error!`],
30//! [`warn!`], [`info!`], [`debug!`] and [`trace!`]
31//! where `error!` represents the highest-priority log messages
32//! and `trace!` the lowest. The log messages are filtered by configuring
33//! the log level to exclude messages with a lower priority.
34//! Each of these macros accept format strings similarly to [`println!`].
35//!
36//!
37//! [`error!`]: ./macro.error.html
38//! [`warn!`]: ./macro.warn.html
39//! [`info!`]: ./macro.info.html
40//! [`debug!`]: ./macro.debug.html
41//! [`trace!`]: ./macro.trace.html
42//! [`println!`]: https://doc.rust-lang.org/stable/std/macro.println.html
43//!
44//! ## In libraries
45//!
46//! Libraries should link only to the `log` crate, and use the provided
47//! macros to log whatever information will be useful to downstream consumers.
48//!
49//! ### Examples
50//!
51//! ```edition2018
52//! # #[derive(Debug)] pub struct Yak(String);
53//! # impl Yak { fn shave(&mut self, _: u32) {} }
54//! # fn find_a_razor() -> Result<u32, u32> { Ok(1) }
55//! use log::{info, warn};
56//!
57//! pub fn shave_the_yak(yak: &mut Yak) {
58//!     info!(target: "yak_events", "Commencing yak shaving for {:?}", yak);
59//!
60//!     loop {
61//!         match find_a_razor() {
62//!             Ok(razor) => {
63//!                 info!("Razor located: {}", razor);
64//!                 yak.shave(razor);
65//!                 break;
66//!             }
67//!             Err(err) => {
68//!                 warn!("Unable to locate a razor: {}, retrying", err);
69//!             }
70//!         }
71//!     }
72//! }
73//! # fn main() {}
74//! ```
75//!
76//! ## In executables
77//!
78//! Executables should choose a logging implementation and initialize it early in the
79//! runtime of the program. Logging implementations will typically include a
80//! function to do this. Any log messages generated before
81//! the implementation is initialized will be ignored.
82//!
83//! The executable itself may use the `log` crate to log as well.
84//!
85//! ### Warning
86//!
87//! The logging system may only be initialized once.
88//!
89//! ## Structured logging
90//!
91//! If you enable the `kv_unstable` feature you can associate structured values
92//! with your log records. If we take the example from before, we can include
93//! some additional context besides what's in the formatted message:
94//!
95//! ```edition2018
96//! # #[macro_use] extern crate serde;
97//! # #[derive(Debug, Serialize)] pub struct Yak(String);
98//! # impl Yak { fn shave(&mut self, _: u32) {} }
99//! # fn find_a_razor() -> Result<u32, std::io::Error> { Ok(1) }
100//! # #[cfg(feature = "kv_unstable_serde")]
101//! # fn main() {
102//! use log::{info, warn, as_serde, as_error};
103//!
104//! pub fn shave_the_yak(yak: &mut Yak) {
105//!     info!(target: "yak_events", yak = as_serde!(yak); "Commencing yak shaving");
106//!
107//!     loop {
108//!         match find_a_razor() {
109//!             Ok(razor) => {
110//!                 info!(razor = razor; "Razor located");
111//!                 yak.shave(razor);
112//!                 break;
113//!             }
114//!             Err(err) => {
115//!                 warn!(err = as_error!(err); "Unable to locate a razor, retrying");
116//!             }
117//!         }
118//!     }
119//! }
120//! # }
121//! # #[cfg(not(feature = "kv_unstable_serde"))]
122//! # fn main() {}
123//! ```
124//!
125//! # Available logging implementations
126//!
127//! In order to produce log output executables have to use
128//! a logger implementation compatible with the facade.
129//! There are many available implementations to choose from,
130//! here are some of the most popular ones:
131//!
132//! * Simple minimal loggers:
133//!     * [env_logger]
134//!     * [simple_logger]
135//!     * [simplelog]
136//!     * [pretty_env_logger]
137//!     * [stderrlog]
138//!     * [flexi_logger]
139//! * Complex configurable frameworks:
140//!     * [log4rs]
141//!     * [fern]
142//! * Adaptors for other facilities:
143//!     * [syslog]
144//!     * [slog-stdlog]
145//!     * [systemd-journal-logger]
146//!     * [android_log]
147//!     * [win_dbg_logger]
148//!     * [db_logger]
149//! * For WebAssembly binaries:
150//!     * [console_log]
151//! * For dynamic libraries:
152//!     * You may need to construct an FFI-safe wrapper over `log` to initialize in your libraries
153//!
154//! # Implementing a Logger
155//!
156//! Loggers implement the [`Log`] trait. Here's a very basic example that simply
157//! logs all messages at the [`Error`][level_link], [`Warn`][level_link] or
158//! [`Info`][level_link] levels to stdout:
159//!
160//! ```edition2018
161//! use log::{Record, Level, Metadata};
162//!
163//! struct SimpleLogger;
164//!
165//! impl log::Log for SimpleLogger {
166//!     fn enabled(&self, metadata: &Metadata) -> bool {
167//!         metadata.level() <= Level::Info
168//!     }
169//!
170//!     fn log(&self, record: &Record) {
171//!         if self.enabled(record.metadata()) {
172//!             println!("{} - {}", record.level(), record.args());
173//!         }
174//!     }
175//!
176//!     fn flush(&self) {}
177//! }
178//!
179//! # fn main() {}
180//! ```
181//!
182//! Loggers are installed by calling the [`set_logger`] function. The maximum
183//! log level also needs to be adjusted via the [`set_max_level`] function. The
184//! logging facade uses this as an optimization to improve performance of log
185//! messages at levels that are disabled. It's important to set it, as it
186//! defaults to [`Off`][filter_link], so no log messages will ever be captured!
187//! In the case of our example logger, we'll want to set the maximum log level
188//! to [`Info`][filter_link], since we ignore any [`Debug`][level_link] or
189//! [`Trace`][level_link] level log messages. A logging implementation should
190//! provide a function that wraps a call to [`set_logger`] and
191//! [`set_max_level`], handling initialization of the logger:
192//!
193//! ```edition2018
194//! # use log::{Level, Metadata};
195//! # struct SimpleLogger;
196//! # impl log::Log for SimpleLogger {
197//! #   fn enabled(&self, _: &Metadata) -> bool { false }
198//! #   fn log(&self, _: &log::Record) {}
199//! #   fn flush(&self) {}
200//! # }
201//! # fn main() {}
202//! use log::{SetLoggerError, LevelFilter};
203//!
204//! static LOGGER: SimpleLogger = SimpleLogger;
205//!
206//! pub fn init() -> Result<(), SetLoggerError> {
207//!     log::set_logger(&LOGGER)
208//!         .map(|()| log::set_max_level(LevelFilter::Info))
209//! }
210//! ```
211//!
212//! Implementations that adjust their configurations at runtime should take care
213//! to adjust the maximum log level as well.
214//!
215//! # Use with `std`
216//!
217//! `set_logger` requires you to provide a `&'static Log`, which can be hard to
218//! obtain if your logger depends on some runtime configuration. The
219//! `set_boxed_logger` function is available with the `std` Cargo feature. It is
220//! identical to `set_logger` except that it takes a `Box<Log>` rather than a
221//! `&'static Log`:
222//!
223//! ```edition2018
224//! # use log::{Level, LevelFilter, Log, SetLoggerError, Metadata};
225//! # struct SimpleLogger;
226//! # impl log::Log for SimpleLogger {
227//! #   fn enabled(&self, _: &Metadata) -> bool { false }
228//! #   fn log(&self, _: &log::Record) {}
229//! #   fn flush(&self) {}
230//! # }
231//! # fn main() {}
232//! # #[cfg(feature = "std")]
233//! pub fn init() -> Result<(), SetLoggerError> {
234//!     log::set_boxed_logger(Box::new(SimpleLogger))
235//!         .map(|()| log::set_max_level(LevelFilter::Info))
236//! }
237//! ```
238//!
239//! # Compile time filters
240//!
241//! Log levels can be statically disabled at compile time via Cargo features. Log invocations at
242//! disabled levels will be skipped and will not even be present in the resulting binary.
243//! This level is configured separately for release and debug builds. The features are:
244//!
245//! * `max_level_off`
246//! * `max_level_error`
247//! * `max_level_warn`
248//! * `max_level_info`
249//! * `max_level_debug`
250//! * `max_level_trace`
251//! * `release_max_level_off`
252//! * `release_max_level_error`
253//! * `release_max_level_warn`
254//! * `release_max_level_info`
255//! * `release_max_level_debug`
256//! * `release_max_level_trace`
257//!
258//! These features control the value of the `STATIC_MAX_LEVEL` constant. The logging macros check
259//! this value before logging a message. By default, no levels are disabled.
260//!
261//! Libraries should avoid using the max level features because they're global and can't be changed
262//! once they're set.
263//!
264//! For example, a crate can disable trace level logs in debug builds and trace, debug, and info
265//! level logs in release builds with the following configuration:
266//!
267//! ```toml
268//! [dependencies]
269//! log = { version = "0.4", features = ["max_level_debug", "release_max_level_warn"] }
270//! ```
271//! # Crate Feature Flags
272//!
273//! The following crate feature flags are available in addition to the filters. They are
274//! configured in your `Cargo.toml`.
275//!
276//! * `std` allows use of `std` crate instead of the default `core`. Enables using `std::error` and
277//! `set_boxed_logger` functionality.
278//! * `serde` enables support for serialization and deserialization of `Level` and `LevelFilter`.
279//!
280//! ```toml
281//! [dependencies]
282//! log = { version = "0.4", features = ["std", "serde"] }
283//! ```
284//!
285//! # Version compatibility
286//!
287//! The 0.3 and 0.4 versions of the `log` crate are almost entirely compatible. Log messages
288//! made using `log` 0.3 will forward transparently to a logger implementation using `log` 0.4. Log
289//! messages made using `log` 0.4 will forward to a logger implementation using `log` 0.3, but the
290//! module path and file name information associated with the message will unfortunately be lost.
291//!
292//! [`Log`]: trait.Log.html
293//! [level_link]: enum.Level.html
294//! [filter_link]: enum.LevelFilter.html
295//! [`set_logger`]: fn.set_logger.html
296//! [`set_max_level`]: fn.set_max_level.html
297//! [`try_set_logger_raw`]: fn.try_set_logger_raw.html
298//! [`shutdown_logger_raw`]: fn.shutdown_logger_raw.html
299//! [env_logger]: https://docs.rs/env_logger/*/env_logger/
300//! [simple_logger]: https://github.com/borntyping/rust-simple_logger
301//! [simplelog]: https://github.com/drakulix/simplelog.rs
302//! [pretty_env_logger]: https://docs.rs/pretty_env_logger/*/pretty_env_logger/
303//! [stderrlog]: https://docs.rs/stderrlog/*/stderrlog/
304//! [flexi_logger]: https://docs.rs/flexi_logger/*/flexi_logger/
305//! [syslog]: https://docs.rs/syslog/*/syslog/
306//! [slog-stdlog]: https://docs.rs/slog-stdlog/*/slog_stdlog/
307//! [log4rs]: https://docs.rs/log4rs/*/log4rs/
308//! [fern]: https://docs.rs/fern/*/fern/
309//! [systemd-journal-logger]: https://docs.rs/systemd-journal-logger/*/systemd_journal_logger/
310//! [android_log]: https://docs.rs/android_log/*/android_log/
311//! [win_dbg_logger]: https://docs.rs/win_dbg_logger/*/win_dbg_logger/
312//! [console_log]: https://docs.rs/console_log/*/console_log/
313
314#![doc(
315    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
316    html_favicon_url = "https://www.rust-lang.org/favicon.ico",
317    html_root_url = "https://docs.rs/log/0.4.17"
318)]
319#![allow(clippy::derive_hash_xor_eq)]
320#![warn(missing_docs)]
321#![deny(missing_debug_implementations, unconditional_recursion)]
322#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
323// When compiled for the rustc compiler itself we want to make sure that this is
324// an unstable crate
325#![cfg_attr(rustbuild, feature(staged_api, rustc_private))]
326#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))]
327
328#[cfg(all(not(feature = "std"), not(test)))]
329extern crate core as std;
330
331#[macro_use]
332extern crate cfg_if;
333
334use std::cmp;
335#[cfg(feature = "std")]
336use std::error;
337use std::fmt;
338use std::mem;
339use std::str::FromStr;
340
341#[macro_use]
342mod macros;
343mod serde;
344
345#[cfg(feature = "kv_unstable")]
346pub mod kv;
347
348#[cfg(has_atomics)]
349use std::sync::atomic::{AtomicUsize, Ordering};
350
351#[cfg(not(has_atomics))]
352use std::cell::Cell;
353#[cfg(not(has_atomics))]
354use std::sync::atomic::Ordering;
355
356#[cfg(not(has_atomics))]
357struct AtomicUsize {
358    v: Cell<usize>,
359}
360
361#[cfg(not(has_atomics))]
362impl AtomicUsize {
363    const fn new(v: usize) -> AtomicUsize {
364        AtomicUsize { v: Cell::new(v) }
365    }
366
367    fn load(&self, _order: Ordering) -> usize {
368        self.v.get()
369    }
370
371    fn store(&self, val: usize, _order: Ordering) {
372        self.v.set(val)
373    }
374
375    #[cfg(atomic_cas)]
376    fn compare_exchange(
377        &self,
378        current: usize,
379        new: usize,
380        _success: Ordering,
381        _failure: Ordering,
382    ) -> Result<usize, usize> {
383        let prev = self.v.get();
384        if current == prev {
385            self.v.set(new);
386        }
387        Ok(prev)
388    }
389}
390
391// Any platform without atomics is unlikely to have multiple cores, so
392// writing via Cell will not be a race condition.
393#[cfg(not(has_atomics))]
394unsafe impl Sync for AtomicUsize {}
395
396// The LOGGER static holds a pointer to the global logger. It is protected by
397// the STATE static which determines whether LOGGER has been initialized yet.
398static mut LOGGER: &dyn Log = &NopLogger;
399
400static STATE: AtomicUsize = AtomicUsize::new(0);
401
402// There are three different states that we care about: the logger's
403// uninitialized, the logger's initializing (set_logger's been called but
404// LOGGER hasn't actually been set yet), or the logger's active.
405const UNINITIALIZED: usize = 0;
406const INITIALIZING: usize = 1;
407const INITIALIZED: usize = 2;
408
409static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(0);
410
411static LOG_LEVEL_NAMES: [&str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"];
412
413static SET_LOGGER_ERROR: &str = "attempted to set a logger after the logging system \
414                                 was already initialized";
415static LEVEL_PARSE_ERROR: &str =
416    "attempted to convert a string that doesn't match an existing log level";
417
418/// An enum representing the available verbosity levels of the logger.
419///
420/// Typical usage includes: checking if a certain `Level` is enabled with
421/// [`log_enabled!`](macro.log_enabled.html), specifying the `Level` of
422/// [`log!`](macro.log.html), and comparing a `Level` directly to a
423/// [`LevelFilter`](enum.LevelFilter.html).
424#[repr(usize)]
425#[derive(Copy, Eq, Debug, Hash)]
426pub enum Level {
427    /// The "error" level.
428    ///
429    /// Designates very serious errors.
430    // This way these line up with the discriminants for LevelFilter below
431    // This works because Rust treats field-less enums the same way as C does:
432    // https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-field-less-enumerations
433    Error = 1,
434    /// The "warn" level.
435    ///
436    /// Designates hazardous situations.
437    Warn,
438    /// The "info" level.
439    ///
440    /// Designates useful information.
441    Info,
442    /// The "debug" level.
443    ///
444    /// Designates lower priority information.
445    Debug,
446    /// The "trace" level.
447    ///
448    /// Designates very low priority, often extremely verbose, information.
449    Trace,
450}
451
452impl Clone for Level {
453    #[inline]
454    fn clone(&self) -> Level {
455        *self
456    }
457}
458
459impl PartialEq for Level {
460    #[inline]
461    fn eq(&self, other: &Level) -> bool {
462        *self as usize == *other as usize
463    }
464}
465
466impl PartialEq<LevelFilter> for Level {
467    #[inline]
468    fn eq(&self, other: &LevelFilter) -> bool {
469        *self as usize == *other as usize
470    }
471}
472
473impl PartialOrd for Level {
474    #[inline]
475    fn partial_cmp(&self, other: &Level) -> Option<cmp::Ordering> {
476        Some(self.cmp(other))
477    }
478
479    #[inline]
480    fn lt(&self, other: &Level) -> bool {
481        (*self as usize) < *other as usize
482    }
483
484    #[inline]
485    fn le(&self, other: &Level) -> bool {
486        *self as usize <= *other as usize
487    }
488
489    #[inline]
490    fn gt(&self, other: &Level) -> bool {
491        *self as usize > *other as usize
492    }
493
494    #[inline]
495    fn ge(&self, other: &Level) -> bool {
496        *self as usize >= *other as usize
497    }
498}
499
500impl PartialOrd<LevelFilter> for Level {
501    #[inline]
502    fn partial_cmp(&self, other: &LevelFilter) -> Option<cmp::Ordering> {
503        Some((*self as usize).cmp(&(*other as usize)))
504    }
505
506    #[inline]
507    fn lt(&self, other: &LevelFilter) -> bool {
508        (*self as usize) < *other as usize
509    }
510
511    #[inline]
512    fn le(&self, other: &LevelFilter) -> bool {
513        *self as usize <= *other as usize
514    }
515
516    #[inline]
517    fn gt(&self, other: &LevelFilter) -> bool {
518        *self as usize > *other as usize
519    }
520
521    #[inline]
522    fn ge(&self, other: &LevelFilter) -> bool {
523        *self as usize >= *other as usize
524    }
525}
526
527impl Ord for Level {
528    #[inline]
529    fn cmp(&self, other: &Level) -> cmp::Ordering {
530        (*self as usize).cmp(&(*other as usize))
531    }
532}
533
534fn ok_or<T, E>(t: Option<T>, e: E) -> Result<T, E> {
535    match t {
536        Some(t) => Ok(t),
537        None => Err(e),
538    }
539}
540
541// Reimplemented here because std::ascii is not available in libcore
542fn eq_ignore_ascii_case(a: &str, b: &str) -> bool {
543    fn to_ascii_uppercase(c: u8) -> u8 {
544        if c >= b'a' && c <= b'z' {
545            c - b'a' + b'A'
546        } else {
547            c
548        }
549    }
550
551    if a.len() == b.len() {
552        a.bytes()
553            .zip(b.bytes())
554            .all(|(a, b)| to_ascii_uppercase(a) == to_ascii_uppercase(b))
555    } else {
556        false
557    }
558}
559
560impl FromStr for Level {
561    type Err = ParseLevelError;
562    fn from_str(level: &str) -> Result<Level, Self::Err> {
563        ok_or(
564            LOG_LEVEL_NAMES
565                .iter()
566                .position(|&name| eq_ignore_ascii_case(name, level))
567                .into_iter()
568                .filter(|&idx| idx != 0)
569                .map(|idx| Level::from_usize(idx).unwrap())
570                .next(),
571            ParseLevelError(()),
572        )
573    }
574}
575
576impl fmt::Display for Level {
577    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
578        fmt.pad(self.as_str())
579    }
580}
581
582impl Level {
583    fn from_usize(u: usize) -> Option<Level> {
584        match u {
585            1 => Some(Level::Error),
586            2 => Some(Level::Warn),
587            3 => Some(Level::Info),
588            4 => Some(Level::Debug),
589            5 => Some(Level::Trace),
590            _ => None,
591        }
592    }
593
594    /// Returns the most verbose logging level.
595    #[inline]
596    pub fn max() -> Level {
597        Level::Trace
598    }
599
600    /// Converts the `Level` to the equivalent `LevelFilter`.
601    #[inline]
602    pub fn to_level_filter(&self) -> LevelFilter {
603        LevelFilter::from_usize(*self as usize).unwrap()
604    }
605
606    /// Returns the string representation of the `Level`.
607    ///
608    /// This returns the same string as the `fmt::Display` implementation.
609    pub fn as_str(&self) -> &'static str {
610        LOG_LEVEL_NAMES[*self as usize]
611    }
612
613    /// Iterate through all supported logging levels.
614    ///
615    /// The order of iteration is from more severe to less severe log messages.
616    ///
617    /// # Examples
618    ///
619    /// ```
620    /// use log::Level;
621    ///
622    /// let mut levels = Level::iter();
623    ///
624    /// assert_eq!(Some(Level::Error), levels.next());
625    /// assert_eq!(Some(Level::Trace), levels.last());
626    /// ```
627    pub fn iter() -> impl Iterator<Item = Self> {
628        (1..6).map(|i| Self::from_usize(i).unwrap())
629    }
630}
631
632/// An enum representing the available verbosity level filters of the logger.
633///
634/// A `LevelFilter` may be compared directly to a [`Level`]. Use this type
635/// to get and set the maximum log level with [`max_level()`] and [`set_max_level`].
636///
637/// [`Level`]: enum.Level.html
638/// [`max_level()`]: fn.max_level.html
639/// [`set_max_level`]: fn.set_max_level.html
640#[repr(usize)]
641#[derive(Copy, Eq, Debug, Hash)]
642pub enum LevelFilter {
643    /// A level lower than all log levels.
644    Off,
645    /// Corresponds to the `Error` log level.
646    Error,
647    /// Corresponds to the `Warn` log level.
648    Warn,
649    /// Corresponds to the `Info` log level.
650    Info,
651    /// Corresponds to the `Debug` log level.
652    Debug,
653    /// Corresponds to the `Trace` log level.
654    Trace,
655}
656
657// Deriving generates terrible impls of these traits
658
659impl Clone for LevelFilter {
660    #[inline]
661    fn clone(&self) -> LevelFilter {
662        *self
663    }
664}
665
666impl PartialEq for LevelFilter {
667    #[inline]
668    fn eq(&self, other: &LevelFilter) -> bool {
669        *self as usize == *other as usize
670    }
671}
672
673impl PartialEq<Level> for LevelFilter {
674    #[inline]
675    fn eq(&self, other: &Level) -> bool {
676        other.eq(self)
677    }
678}
679
680impl PartialOrd for LevelFilter {
681    #[inline]
682    fn partial_cmp(&self, other: &LevelFilter) -> Option<cmp::Ordering> {
683        Some(self.cmp(other))
684    }
685
686    #[inline]
687    fn lt(&self, other: &LevelFilter) -> bool {
688        (*self as usize) < *other as usize
689    }
690
691    #[inline]
692    fn le(&self, other: &LevelFilter) -> bool {
693        *self as usize <= *other as usize
694    }
695
696    #[inline]
697    fn gt(&self, other: &LevelFilter) -> bool {
698        *self as usize > *other as usize
699    }
700
701    #[inline]
702    fn ge(&self, other: &LevelFilter) -> bool {
703        *self as usize >= *other as usize
704    }
705}
706
707impl PartialOrd<Level> for LevelFilter {
708    #[inline]
709    fn partial_cmp(&self, other: &Level) -> Option<cmp::Ordering> {
710        Some((*self as usize).cmp(&(*other as usize)))
711    }
712
713    #[inline]
714    fn lt(&self, other: &Level) -> bool {
715        (*self as usize) < *other as usize
716    }
717
718    #[inline]
719    fn le(&self, other: &Level) -> bool {
720        *self as usize <= *other as usize
721    }
722
723    #[inline]
724    fn gt(&self, other: &Level) -> bool {
725        *self as usize > *other as usize
726    }
727
728    #[inline]
729    fn ge(&self, other: &Level) -> bool {
730        *self as usize >= *other as usize
731    }
732}
733
734impl Ord for LevelFilter {
735    #[inline]
736    fn cmp(&self, other: &LevelFilter) -> cmp::Ordering {
737        (*self as usize).cmp(&(*other as usize))
738    }
739}
740
741impl FromStr for LevelFilter {
742    type Err = ParseLevelError;
743    fn from_str(level: &str) -> Result<LevelFilter, Self::Err> {
744        ok_or(
745            LOG_LEVEL_NAMES
746                .iter()
747                .position(|&name| eq_ignore_ascii_case(name, level))
748                .map(|p| LevelFilter::from_usize(p).unwrap()),
749            ParseLevelError(()),
750        )
751    }
752}
753
754impl fmt::Display for LevelFilter {
755    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
756        fmt.pad(self.as_str())
757    }
758}
759
760impl LevelFilter {
761    fn from_usize(u: usize) -> Option<LevelFilter> {
762        match u {
763            0 => Some(LevelFilter::Off),
764            1 => Some(LevelFilter::Error),
765            2 => Some(LevelFilter::Warn),
766            3 => Some(LevelFilter::Info),
767            4 => Some(LevelFilter::Debug),
768            5 => Some(LevelFilter::Trace),
769            _ => None,
770        }
771    }
772
773    /// Returns the most verbose logging level filter.
774    #[inline]
775    pub fn max() -> LevelFilter {
776        LevelFilter::Trace
777    }
778
779    /// Converts `self` to the equivalent `Level`.
780    ///
781    /// Returns `None` if `self` is `LevelFilter::Off`.
782    #[inline]
783    pub fn to_level(&self) -> Option<Level> {
784        Level::from_usize(*self as usize)
785    }
786
787    /// Returns the string representation of the `LevelFilter`.
788    ///
789    /// This returns the same string as the `fmt::Display` implementation.
790    pub fn as_str(&self) -> &'static str {
791        LOG_LEVEL_NAMES[*self as usize]
792    }
793
794    /// Iterate through all supported filtering levels.
795    ///
796    /// The order of iteration is from less to more verbose filtering.
797    ///
798    /// # Examples
799    ///
800    /// ```
801    /// use log::LevelFilter;
802    ///
803    /// let mut levels = LevelFilter::iter();
804    ///
805    /// assert_eq!(Some(LevelFilter::Off), levels.next());
806    /// assert_eq!(Some(LevelFilter::Trace), levels.last());
807    /// ```
808    pub fn iter() -> impl Iterator<Item = Self> {
809        (0..6).map(|i| Self::from_usize(i).unwrap())
810    }
811}
812
813#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
814enum MaybeStaticStr<'a> {
815    Static(&'static str),
816    Borrowed(&'a str),
817}
818
819impl<'a> MaybeStaticStr<'a> {
820    #[inline]
821    fn get(&self) -> &'a str {
822        match *self {
823            MaybeStaticStr::Static(s) => s,
824            MaybeStaticStr::Borrowed(s) => s,
825        }
826    }
827}
828
829/// The "payload" of a log message.
830///
831/// # Use
832///
833/// `Record` structures are passed as parameters to the [`log`][method.log]
834/// method of the [`Log`] trait. Logger implementors manipulate these
835/// structures in order to display log messages. `Record`s are automatically
836/// created by the [`log!`] macro and so are not seen by log users.
837///
838/// Note that the [`level()`] and [`target()`] accessors are equivalent to
839/// `self.metadata().level()` and `self.metadata().target()` respectively.
840/// These methods are provided as a convenience for users of this structure.
841///
842/// # Example
843///
844/// The following example shows a simple logger that displays the level,
845/// module path, and message of any `Record` that is passed to it.
846///
847/// ```edition2018
848/// struct SimpleLogger;
849///
850/// impl log::Log for SimpleLogger {
851///    fn enabled(&self, metadata: &log::Metadata) -> bool {
852///        true
853///    }
854///
855///    fn log(&self, record: &log::Record) {
856///        if !self.enabled(record.metadata()) {
857///            return;
858///        }
859///
860///        println!("{}:{} -- {}",
861///                 record.level(),
862///                 record.target(),
863///                 record.args());
864///    }
865///    fn flush(&self) {}
866/// }
867/// ```
868///
869/// [method.log]: trait.Log.html#tymethod.log
870/// [`Log`]: trait.Log.html
871/// [`log!`]: macro.log.html
872/// [`level()`]: struct.Record.html#method.level
873/// [`target()`]: struct.Record.html#method.target
874#[derive(Clone, Debug)]
875pub struct Record<'a> {
876    metadata: Metadata<'a>,
877    args: fmt::Arguments<'a>,
878    module_path: Option<MaybeStaticStr<'a>>,
879    file: Option<MaybeStaticStr<'a>>,
880    line: Option<u32>,
881    #[cfg(feature = "kv_unstable")]
882    key_values: KeyValues<'a>,
883}
884
885// This wrapper type is only needed so we can
886// `#[derive(Debug)]` on `Record`. It also
887// provides a useful `Debug` implementation for
888// the underlying `Source`.
889#[cfg(feature = "kv_unstable")]
890#[derive(Clone)]
891struct KeyValues<'a>(&'a dyn kv::Source);
892
893#[cfg(feature = "kv_unstable")]
894impl<'a> fmt::Debug for KeyValues<'a> {
895    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
896        let mut visitor = f.debug_map();
897        self.0.visit(&mut visitor).map_err(|_| fmt::Error)?;
898        visitor.finish()
899    }
900}
901
902impl<'a> Record<'a> {
903    /// Returns a new builder.
904    #[inline]
905    pub fn builder() -> RecordBuilder<'a> {
906        RecordBuilder::new()
907    }
908
909    /// The message body.
910    #[inline]
911    pub fn args(&self) -> &fmt::Arguments<'a> {
912        &self.args
913    }
914
915    /// Metadata about the log directive.
916    #[inline]
917    pub fn metadata(&self) -> &Metadata<'a> {
918        &self.metadata
919    }
920
921    /// The verbosity level of the message.
922    #[inline]
923    pub fn level(&self) -> Level {
924        self.metadata.level()
925    }
926
927    /// The name of the target of the directive.
928    #[inline]
929    pub fn target(&self) -> &'a str {
930        self.metadata.target()
931    }
932
933    /// The module path of the message.
934    #[inline]
935    pub fn module_path(&self) -> Option<&'a str> {
936        self.module_path.map(|s| s.get())
937    }
938
939    /// The module path of the message, if it is a `'static` string.
940    #[inline]
941    pub fn module_path_static(&self) -> Option<&'static str> {
942        match self.module_path {
943            Some(MaybeStaticStr::Static(s)) => Some(s),
944            _ => None,
945        }
946    }
947
948    /// The source file containing the message.
949    #[inline]
950    pub fn file(&self) -> Option<&'a str> {
951        self.file.map(|s| s.get())
952    }
953
954    /// The module path of the message, if it is a `'static` string.
955    #[inline]
956    pub fn file_static(&self) -> Option<&'static str> {
957        match self.file {
958            Some(MaybeStaticStr::Static(s)) => Some(s),
959            _ => None,
960        }
961    }
962
963    /// The line containing the message.
964    #[inline]
965    pub fn line(&self) -> Option<u32> {
966        self.line
967    }
968
969    /// The structured key-value pairs associated with the message.
970    #[cfg(feature = "kv_unstable")]
971    #[inline]
972    pub fn key_values(&self) -> &dyn kv::Source {
973        self.key_values.0
974    }
975
976    /// Create a new [`RecordBuilder`](struct.RecordBuilder.html) based on this record.
977    #[cfg(feature = "kv_unstable")]
978    #[inline]
979    pub fn to_builder(&self) -> RecordBuilder {
980        RecordBuilder {
981            record: Record {
982                metadata: Metadata {
983                    level: self.metadata.level,
984                    target: self.metadata.target,
985                },
986                args: self.args,
987                module_path: self.module_path,
988                file: self.file,
989                line: self.line,
990                key_values: self.key_values.clone(),
991            },
992        }
993    }
994}
995
996/// Builder for [`Record`](struct.Record.html).
997///
998/// Typically should only be used by log library creators or for testing and "shim loggers".
999/// The `RecordBuilder` can set the different parameters of `Record` object, and returns
1000/// the created object when `build` is called.
1001///
1002/// # Examples
1003///
1004/// ```edition2018
1005/// use log::{Level, Record};
1006///
1007/// let record = Record::builder()
1008///                 .args(format_args!("Error!"))
1009///                 .level(Level::Error)
1010///                 .target("myApp")
1011///                 .file(Some("server.rs"))
1012///                 .line(Some(144))
1013///                 .module_path(Some("server"))
1014///                 .build();
1015/// ```
1016///
1017/// Alternatively, use [`MetadataBuilder`](struct.MetadataBuilder.html):
1018///
1019/// ```edition2018
1020/// use log::{Record, Level, MetadataBuilder};
1021///
1022/// let error_metadata = MetadataBuilder::new()
1023///                         .target("myApp")
1024///                         .level(Level::Error)
1025///                         .build();
1026///
1027/// let record = Record::builder()
1028///                 .metadata(error_metadata)
1029///                 .args(format_args!("Error!"))
1030///                 .line(Some(433))
1031///                 .file(Some("app.rs"))
1032///                 .module_path(Some("server"))
1033///                 .build();
1034/// ```
1035#[derive(Debug)]
1036pub struct RecordBuilder<'a> {
1037    record: Record<'a>,
1038}
1039
1040impl<'a> RecordBuilder<'a> {
1041    /// Construct new `RecordBuilder`.
1042    ///
1043    /// The default options are:
1044    ///
1045    /// - `args`: [`format_args!("")`]
1046    /// - `metadata`: [`Metadata::builder().build()`]
1047    /// - `module_path`: `None`
1048    /// - `file`: `None`
1049    /// - `line`: `None`
1050    ///
1051    /// [`format_args!("")`]: https://doc.rust-lang.org/std/macro.format_args.html
1052    /// [`Metadata::builder().build()`]: struct.MetadataBuilder.html#method.build
1053    #[inline]
1054    pub fn new() -> RecordBuilder<'a> {
1055        RecordBuilder {
1056            record: Record {
1057                args: format_args!(""),
1058                metadata: Metadata::builder().build(),
1059                module_path: None,
1060                file: None,
1061                line: None,
1062                #[cfg(feature = "kv_unstable")]
1063                key_values: KeyValues(&Option::None::<(kv::Key, kv::Value)>),
1064            },
1065        }
1066    }
1067
1068    /// Set [`args`](struct.Record.html#method.args).
1069    #[inline]
1070    pub fn args(&mut self, args: fmt::Arguments<'a>) -> &mut RecordBuilder<'a> {
1071        self.record.args = args;
1072        self
1073    }
1074
1075    /// Set [`metadata`](struct.Record.html#method.metadata). Construct a `Metadata` object with [`MetadataBuilder`](struct.MetadataBuilder.html).
1076    #[inline]
1077    pub fn metadata(&mut self, metadata: Metadata<'a>) -> &mut RecordBuilder<'a> {
1078        self.record.metadata = metadata;
1079        self
1080    }
1081
1082    /// Set [`Metadata::level`](struct.Metadata.html#method.level).
1083    #[inline]
1084    pub fn level(&mut self, level: Level) -> &mut RecordBuilder<'a> {
1085        self.record.metadata.level = level;
1086        self
1087    }
1088
1089    /// Set [`Metadata::target`](struct.Metadata.html#method.target)
1090    #[inline]
1091    pub fn target(&mut self, target: &'a str) -> &mut RecordBuilder<'a> {
1092        self.record.metadata.target = target;
1093        self
1094    }
1095
1096    /// Set [`module_path`](struct.Record.html#method.module_path)
1097    #[inline]
1098    pub fn module_path(&mut self, path: Option<&'a str>) -> &mut RecordBuilder<'a> {
1099        self.record.module_path = path.map(MaybeStaticStr::Borrowed);
1100        self
1101    }
1102
1103    /// Set [`module_path`](struct.Record.html#method.module_path) to a `'static` string
1104    #[inline]
1105    pub fn module_path_static(&mut self, path: Option<&'static str>) -> &mut RecordBuilder<'a> {
1106        self.record.module_path = path.map(MaybeStaticStr::Static);
1107        self
1108    }
1109
1110    /// Set [`file`](struct.Record.html#method.file)
1111    #[inline]
1112    pub fn file(&mut self, file: Option<&'a str>) -> &mut RecordBuilder<'a> {
1113        self.record.file = file.map(MaybeStaticStr::Borrowed);
1114        self
1115    }
1116
1117    /// Set [`file`](struct.Record.html#method.file) to a `'static` string.
1118    #[inline]
1119    pub fn file_static(&mut self, file: Option<&'static str>) -> &mut RecordBuilder<'a> {
1120        self.record.file = file.map(MaybeStaticStr::Static);
1121        self
1122    }
1123
1124    /// Set [`line`](struct.Record.html#method.line)
1125    #[inline]
1126    pub fn line(&mut self, line: Option<u32>) -> &mut RecordBuilder<'a> {
1127        self.record.line = line;
1128        self
1129    }
1130
1131    /// Set [`key_values`](struct.Record.html#method.key_values)
1132    #[cfg(feature = "kv_unstable")]
1133    #[inline]
1134    pub fn key_values(&mut self, kvs: &'a dyn kv::Source) -> &mut RecordBuilder<'a> {
1135        self.record.key_values = KeyValues(kvs);
1136        self
1137    }
1138
1139    /// Invoke the builder and return a `Record`
1140    #[inline]
1141    pub fn build(&self) -> Record<'a> {
1142        self.record.clone()
1143    }
1144}
1145
1146/// Metadata about a log message.
1147///
1148/// # Use
1149///
1150/// `Metadata` structs are created when users of the library use
1151/// logging macros.
1152///
1153/// They are consumed by implementations of the `Log` trait in the
1154/// `enabled` method.
1155///
1156/// `Record`s use `Metadata` to determine the log message's severity
1157/// and target.
1158///
1159/// Users should use the `log_enabled!` macro in their code to avoid
1160/// constructing expensive log messages.
1161///
1162/// # Examples
1163///
1164/// ```edition2018
1165/// use log::{Record, Level, Metadata};
1166///
1167/// struct MyLogger;
1168///
1169/// impl log::Log for MyLogger {
1170///     fn enabled(&self, metadata: &Metadata) -> bool {
1171///         metadata.level() <= Level::Info
1172///     }
1173///
1174///     fn log(&self, record: &Record) {
1175///         if self.enabled(record.metadata()) {
1176///             println!("{} - {}", record.level(), record.args());
1177///         }
1178///     }
1179///     fn flush(&self) {}
1180/// }
1181///
1182/// # fn main(){}
1183/// ```
1184#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1185pub struct Metadata<'a> {
1186    level: Level,
1187    target: &'a str,
1188}
1189
1190impl<'a> Metadata<'a> {
1191    /// Returns a new builder.
1192    #[inline]
1193    pub fn builder() -> MetadataBuilder<'a> {
1194        MetadataBuilder::new()
1195    }
1196
1197    /// The verbosity level of the message.
1198    #[inline]
1199    pub fn level(&self) -> Level {
1200        self.level
1201    }
1202
1203    /// The name of the target of the directive.
1204    #[inline]
1205    pub fn target(&self) -> &'a str {
1206        self.target
1207    }
1208}
1209
1210/// Builder for [`Metadata`](struct.Metadata.html).
1211///
1212/// Typically should only be used by log library creators or for testing and "shim loggers".
1213/// The `MetadataBuilder` can set the different parameters of a `Metadata` object, and returns
1214/// the created object when `build` is called.
1215///
1216/// # Example
1217///
1218/// ```edition2018
1219/// let target = "myApp";
1220/// use log::{Level, MetadataBuilder};
1221/// let metadata = MetadataBuilder::new()
1222///                     .level(Level::Debug)
1223///                     .target(target)
1224///                     .build();
1225/// ```
1226#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1227pub struct MetadataBuilder<'a> {
1228    metadata: Metadata<'a>,
1229}
1230
1231impl<'a> MetadataBuilder<'a> {
1232    /// Construct a new `MetadataBuilder`.
1233    ///
1234    /// The default options are:
1235    ///
1236    /// - `level`: `Level::Info`
1237    /// - `target`: `""`
1238    #[inline]
1239    pub fn new() -> MetadataBuilder<'a> {
1240        MetadataBuilder {
1241            metadata: Metadata {
1242                level: Level::Info,
1243                target: "",
1244            },
1245        }
1246    }
1247
1248    /// Setter for [`level`](struct.Metadata.html#method.level).
1249    #[inline]
1250    pub fn level(&mut self, arg: Level) -> &mut MetadataBuilder<'a> {
1251        self.metadata.level = arg;
1252        self
1253    }
1254
1255    /// Setter for [`target`](struct.Metadata.html#method.target).
1256    #[inline]
1257    pub fn target(&mut self, target: &'a str) -> &mut MetadataBuilder<'a> {
1258        self.metadata.target = target;
1259        self
1260    }
1261
1262    /// Returns a `Metadata` object.
1263    #[inline]
1264    pub fn build(&self) -> Metadata<'a> {
1265        self.metadata.clone()
1266    }
1267}
1268
1269/// A trait encapsulating the operations required of a logger.
1270pub trait Log: Sync + Send {
1271    /// Determines if a log message with the specified metadata would be
1272    /// logged.
1273    ///
1274    /// This is used by the `log_enabled!` macro to allow callers to avoid
1275    /// expensive computation of log message arguments if the message would be
1276    /// discarded anyway.
1277    ///
1278    /// # For implementors
1279    ///
1280    /// This method isn't called automatically by the `log!` macros.
1281    /// It's up to an implementation of the `Log` trait to call `enabled` in its own
1282    /// `log` method implementation to guarantee that filtering is applied.
1283    fn enabled(&self, metadata: &Metadata) -> bool;
1284
1285    /// Logs the `Record`.
1286    ///
1287    /// # For implementors
1288    ///
1289    /// Note that `enabled` is *not* necessarily called before this method.
1290    /// Implementations of `log` should perform all necessary filtering
1291    /// internally.
1292    fn log(&self, record: &Record);
1293
1294    /// Flushes any buffered records.
1295    fn flush(&self);
1296}
1297
1298// Just used as a dummy initial value for LOGGER
1299struct NopLogger;
1300
1301impl Log for NopLogger {
1302    fn enabled(&self, _: &Metadata) -> bool {
1303        false
1304    }
1305
1306    fn log(&self, _: &Record) {}
1307    fn flush(&self) {}
1308}
1309
1310impl<T> Log for &'_ T
1311where
1312    T: ?Sized + Log,
1313{
1314    fn enabled(&self, metadata: &Metadata) -> bool {
1315        (**self).enabled(metadata)
1316    }
1317
1318    fn log(&self, record: &Record) {
1319        (**self).log(record)
1320    }
1321    fn flush(&self) {
1322        (**self).flush()
1323    }
1324}
1325
1326#[cfg(feature = "std")]
1327impl<T> Log for std::boxed::Box<T>
1328where
1329    T: ?Sized + Log,
1330{
1331    fn enabled(&self, metadata: &Metadata) -> bool {
1332        self.as_ref().enabled(metadata)
1333    }
1334
1335    fn log(&self, record: &Record) {
1336        self.as_ref().log(record)
1337    }
1338    fn flush(&self) {
1339        self.as_ref().flush()
1340    }
1341}
1342
1343#[cfg(feature = "std")]
1344impl<T> Log for std::sync::Arc<T>
1345where
1346    T: ?Sized + Log,
1347{
1348    fn enabled(&self, metadata: &Metadata) -> bool {
1349        self.as_ref().enabled(metadata)
1350    }
1351
1352    fn log(&self, record: &Record) {
1353        self.as_ref().log(record)
1354    }
1355    fn flush(&self) {
1356        self.as_ref().flush()
1357    }
1358}
1359
1360/// Sets the global maximum log level.
1361///
1362/// Generally, this should only be called by the active logging implementation.
1363///
1364/// Note that `Trace` is the maximum level, because it provides the maximum amount of detail in the emitted logs.
1365#[inline]
1366pub fn set_max_level(level: LevelFilter) {
1367    MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::Relaxed)
1368}
1369
1370/// Returns the current maximum log level.
1371///
1372/// The [`log!`], [`error!`], [`warn!`], [`info!`], [`debug!`], and [`trace!`] macros check
1373/// this value and discard any message logged at a higher level. The maximum
1374/// log level is set by the [`set_max_level`] function.
1375///
1376/// [`log!`]: macro.log.html
1377/// [`error!`]: macro.error.html
1378/// [`warn!`]: macro.warn.html
1379/// [`info!`]: macro.info.html
1380/// [`debug!`]: macro.debug.html
1381/// [`trace!`]: macro.trace.html
1382/// [`set_max_level`]: fn.set_max_level.html
1383#[inline(always)]
1384pub fn max_level() -> LevelFilter {
1385    // Since `LevelFilter` is `repr(usize)`,
1386    // this transmute is sound if and only if `MAX_LOG_LEVEL_FILTER`
1387    // is set to a usize that is a valid discriminant for `LevelFilter`.
1388    // Since `MAX_LOG_LEVEL_FILTER` is private, the only time it's set
1389    // is by `set_max_level` above, i.e. by casting a `LevelFilter` to `usize`.
1390    // So any usize stored in `MAX_LOG_LEVEL_FILTER` is a valid discriminant.
1391    unsafe { mem::transmute(MAX_LOG_LEVEL_FILTER.load(Ordering::Relaxed)) }
1392}
1393
1394/// Sets the global logger to a `Box<Log>`.
1395///
1396/// This is a simple convenience wrapper over `set_logger`, which takes a
1397/// `Box<Log>` rather than a `&'static Log`. See the documentation for
1398/// [`set_logger`] for more details.
1399///
1400/// Requires the `std` feature.
1401///
1402/// # Errors
1403///
1404/// An error is returned if a logger has already been set.
1405///
1406/// [`set_logger`]: fn.set_logger.html
1407#[cfg(all(feature = "std", atomic_cas))]
1408pub fn set_boxed_logger(logger: Box<dyn Log>) -> Result<(), SetLoggerError> {
1409    set_logger_inner(|| Box::leak(logger))
1410}
1411
1412/// Sets the global logger to a `&'static Log`.
1413///
1414/// This function may only be called once in the lifetime of a program. Any log
1415/// events that occur before the call to `set_logger` completes will be ignored.
1416///
1417/// This function does not typically need to be called manually. Logger
1418/// implementations should provide an initialization method that installs the
1419/// logger internally.
1420///
1421/// # Availability
1422///
1423/// This method is available even when the `std` feature is disabled. However,
1424/// it is currently unavailable on `thumbv6` targets, which lack support for
1425/// some atomic operations which are used by this function. Even on those
1426/// targets, [`set_logger_racy`] will be available.
1427///
1428/// # Errors
1429///
1430/// An error is returned if a logger has already been set.
1431///
1432/// # Examples
1433///
1434/// ```edition2018
1435/// use log::{error, info, warn, Record, Level, Metadata, LevelFilter};
1436///
1437/// static MY_LOGGER: MyLogger = MyLogger;
1438///
1439/// struct MyLogger;
1440///
1441/// impl log::Log for MyLogger {
1442///     fn enabled(&self, metadata: &Metadata) -> bool {
1443///         metadata.level() <= Level::Info
1444///     }
1445///
1446///     fn log(&self, record: &Record) {
1447///         if self.enabled(record.metadata()) {
1448///             println!("{} - {}", record.level(), record.args());
1449///         }
1450///     }
1451///     fn flush(&self) {}
1452/// }
1453///
1454/// # fn main(){
1455/// log::set_logger(&MY_LOGGER).unwrap();
1456/// log::set_max_level(LevelFilter::Info);
1457///
1458/// info!("hello log");
1459/// warn!("warning");
1460/// error!("oops");
1461/// # }
1462/// ```
1463///
1464/// [`set_logger_racy`]: fn.set_logger_racy.html
1465#[cfg(atomic_cas)]
1466pub fn set_logger(logger: &'static dyn Log) -> Result<(), SetLoggerError> {
1467    set_logger_inner(|| logger)
1468}
1469
1470#[cfg(atomic_cas)]
1471fn set_logger_inner<F>(make_logger: F) -> Result<(), SetLoggerError>
1472where
1473    F: FnOnce() -> &'static dyn Log,
1474{
1475    let old_state = match STATE.compare_exchange(
1476        UNINITIALIZED,
1477        INITIALIZING,
1478        Ordering::SeqCst,
1479        Ordering::SeqCst,
1480    ) {
1481        Ok(s) | Err(s) => s,
1482    };
1483    match old_state {
1484        UNINITIALIZED => {
1485            unsafe {
1486                LOGGER = make_logger();
1487            }
1488            STATE.store(INITIALIZED, Ordering::SeqCst);
1489            Ok(())
1490        }
1491        INITIALIZING => {
1492            while STATE.load(Ordering::SeqCst) == INITIALIZING {
1493                // TODO: replace with `hint::spin_loop` once MSRV is 1.49.0.
1494                #[allow(deprecated)]
1495                std::sync::atomic::spin_loop_hint();
1496            }
1497            Err(SetLoggerError(()))
1498        }
1499        _ => Err(SetLoggerError(())),
1500    }
1501}
1502
1503/// A thread-unsafe version of [`set_logger`].
1504///
1505/// This function is available on all platforms, even those that do not have
1506/// support for atomics that is needed by [`set_logger`].
1507///
1508/// In almost all cases, [`set_logger`] should be preferred.
1509///
1510/// # Safety
1511///
1512/// This function is only safe to call when no other logger initialization
1513/// function is called while this function still executes.
1514///
1515/// This can be upheld by (for example) making sure that **there are no other
1516/// threads**, and (on embedded) that **interrupts are disabled**.
1517///
1518/// It is safe to use other logging functions while this function runs
1519/// (including all logging macros).
1520///
1521/// [`set_logger`]: fn.set_logger.html
1522pub unsafe fn set_logger_racy(logger: &'static dyn Log) -> Result<(), SetLoggerError> {
1523    match STATE.load(Ordering::SeqCst) {
1524        UNINITIALIZED => {
1525            LOGGER = logger;
1526            STATE.store(INITIALIZED, Ordering::SeqCst);
1527            Ok(())
1528        }
1529        INITIALIZING => {
1530            // This is just plain UB, since we were racing another initialization function
1531            unreachable!("set_logger_racy must not be used with other initialization functions")
1532        }
1533        _ => Err(SetLoggerError(())),
1534    }
1535}
1536
1537/// The type returned by [`set_logger`] if [`set_logger`] has already been called.
1538///
1539/// [`set_logger`]: fn.set_logger.html
1540#[allow(missing_copy_implementations)]
1541#[derive(Debug)]
1542pub struct SetLoggerError(());
1543
1544impl fmt::Display for SetLoggerError {
1545    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1546        fmt.write_str(SET_LOGGER_ERROR)
1547    }
1548}
1549
1550// The Error trait is not available in libcore
1551#[cfg(feature = "std")]
1552impl error::Error for SetLoggerError {}
1553
1554/// The type returned by [`from_str`] when the string doesn't match any of the log levels.
1555///
1556/// [`from_str`]: https://doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
1557#[allow(missing_copy_implementations)]
1558#[derive(Debug, PartialEq)]
1559pub struct ParseLevelError(());
1560
1561impl fmt::Display for ParseLevelError {
1562    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1563        fmt.write_str(LEVEL_PARSE_ERROR)
1564    }
1565}
1566
1567// The Error trait is not available in libcore
1568#[cfg(feature = "std")]
1569impl error::Error for ParseLevelError {}
1570
1571/// Returns a reference to the logger.
1572///
1573/// If a logger has not been set, a no-op implementation is returned.
1574pub fn logger() -> &'static dyn Log {
1575    if STATE.load(Ordering::SeqCst) != INITIALIZED {
1576        static NOP: NopLogger = NopLogger;
1577        &NOP
1578    } else {
1579        unsafe { LOGGER }
1580    }
1581}
1582
1583// WARNING: this is not part of the crate's public API and is subject to change at any time
1584#[doc(hidden)]
1585#[cfg(not(feature = "kv_unstable"))]
1586pub fn __private_api_log(
1587    args: fmt::Arguments,
1588    level: Level,
1589    &(target, module_path, file, line): &(&str, &'static str, &'static str, u32),
1590    kvs: Option<&[(&str, &str)]>,
1591) {
1592    if kvs.is_some() {
1593        panic!(
1594            "key-value support is experimental and must be enabled using the `kv_unstable` feature"
1595        )
1596    }
1597
1598    logger().log(
1599        &Record::builder()
1600            .args(args)
1601            .level(level)
1602            .target(target)
1603            .module_path_static(Some(module_path))
1604            .file_static(Some(file))
1605            .line(Some(line))
1606            .build(),
1607    );
1608}
1609
1610// WARNING: this is not part of the crate's public API and is subject to change at any time
1611#[doc(hidden)]
1612#[cfg(feature = "kv_unstable")]
1613pub fn __private_api_log(
1614    args: fmt::Arguments,
1615    level: Level,
1616    &(target, module_path, file, line): &(&str, &'static str, &'static str, u32),
1617    kvs: Option<&[(&str, &dyn kv::ToValue)]>,
1618) {
1619    logger().log(
1620        &Record::builder()
1621            .args(args)
1622            .level(level)
1623            .target(target)
1624            .module_path_static(Some(module_path))
1625            .file_static(Some(file))
1626            .line(Some(line))
1627            .key_values(&kvs)
1628            .build(),
1629    );
1630}
1631
1632// WARNING: this is not part of the crate's public API and is subject to change at any time
1633#[doc(hidden)]
1634pub fn __private_api_enabled(level: Level, target: &str) -> bool {
1635    logger().enabled(&Metadata::builder().level(level).target(target).build())
1636}
1637
1638// WARNING: this is not part of the crate's public API and is subject to change at any time
1639#[doc(hidden)]
1640pub mod __private_api {
1641    pub use std::option::Option;
1642}
1643
1644/// The statically resolved maximum log level.
1645///
1646/// See the crate level documentation for information on how to configure this.
1647///
1648/// This value is checked by the log macros, but not by the `Log`ger returned by
1649/// the [`logger`] function. Code that manually calls functions on that value
1650/// should compare the level against this value.
1651///
1652/// [`logger`]: fn.logger.html
1653pub const STATIC_MAX_LEVEL: LevelFilter = MAX_LEVEL_INNER;
1654
1655cfg_if! {
1656    if #[cfg(all(not(debug_assertions), feature = "release_max_level_off"))] {
1657        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Off;
1658    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_error"))] {
1659        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Error;
1660    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_warn"))] {
1661        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Warn;
1662    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_info"))] {
1663        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Info;
1664    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_debug"))] {
1665        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Debug;
1666    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_trace"))] {
1667        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Trace;
1668    } else if #[cfg(feature = "max_level_off")] {
1669        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Off;
1670    } else if #[cfg(feature = "max_level_error")] {
1671        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Error;
1672    } else if #[cfg(feature = "max_level_warn")] {
1673        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Warn;
1674    } else if #[cfg(feature = "max_level_info")] {
1675        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Info;
1676    } else if #[cfg(feature = "max_level_debug")] {
1677        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Debug;
1678    } else {
1679        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Trace;
1680    }
1681}
1682
1683#[cfg(test)]
1684mod tests {
1685    extern crate std;
1686    use super::{Level, LevelFilter, ParseLevelError};
1687    use tests::std::string::ToString;
1688
1689    #[test]
1690    fn test_levelfilter_from_str() {
1691        let tests = [
1692            ("off", Ok(LevelFilter::Off)),
1693            ("error", Ok(LevelFilter::Error)),
1694            ("warn", Ok(LevelFilter::Warn)),
1695            ("info", Ok(LevelFilter::Info)),
1696            ("debug", Ok(LevelFilter::Debug)),
1697            ("trace", Ok(LevelFilter::Trace)),
1698            ("OFF", Ok(LevelFilter::Off)),
1699            ("ERROR", Ok(LevelFilter::Error)),
1700            ("WARN", Ok(LevelFilter::Warn)),
1701            ("INFO", Ok(LevelFilter::Info)),
1702            ("DEBUG", Ok(LevelFilter::Debug)),
1703            ("TRACE", Ok(LevelFilter::Trace)),
1704            ("asdf", Err(ParseLevelError(()))),
1705        ];
1706        for &(s, ref expected) in &tests {
1707            assert_eq!(expected, &s.parse());
1708        }
1709    }
1710
1711    #[test]
1712    fn test_level_from_str() {
1713        let tests = [
1714            ("OFF", Err(ParseLevelError(()))),
1715            ("error", Ok(Level::Error)),
1716            ("warn", Ok(Level::Warn)),
1717            ("info", Ok(Level::Info)),
1718            ("debug", Ok(Level::Debug)),
1719            ("trace", Ok(Level::Trace)),
1720            ("ERROR", Ok(Level::Error)),
1721            ("WARN", Ok(Level::Warn)),
1722            ("INFO", Ok(Level::Info)),
1723            ("DEBUG", Ok(Level::Debug)),
1724            ("TRACE", Ok(Level::Trace)),
1725            ("asdf", Err(ParseLevelError(()))),
1726        ];
1727        for &(s, ref expected) in &tests {
1728            assert_eq!(expected, &s.parse());
1729        }
1730    }
1731
1732    #[test]
1733    fn test_level_as_str() {
1734        let tests = &[
1735            (Level::Error, "ERROR"),
1736            (Level::Warn, "WARN"),
1737            (Level::Info, "INFO"),
1738            (Level::Debug, "DEBUG"),
1739            (Level::Trace, "TRACE"),
1740        ];
1741        for (input, expected) in tests {
1742            assert_eq!(*expected, input.as_str());
1743        }
1744    }
1745
1746    #[test]
1747    fn test_level_show() {
1748        assert_eq!("INFO", Level::Info.to_string());
1749        assert_eq!("ERROR", Level::Error.to_string());
1750    }
1751
1752    #[test]
1753    fn test_levelfilter_show() {
1754        assert_eq!("OFF", LevelFilter::Off.to_string());
1755        assert_eq!("ERROR", LevelFilter::Error.to_string());
1756    }
1757
1758    #[test]
1759    fn test_cross_cmp() {
1760        assert!(Level::Debug > LevelFilter::Error);
1761        assert!(LevelFilter::Warn < Level::Trace);
1762        assert!(LevelFilter::Off < Level::Error);
1763    }
1764
1765    #[test]
1766    fn test_cross_eq() {
1767        assert!(Level::Error == LevelFilter::Error);
1768        assert!(LevelFilter::Off != Level::Error);
1769        assert!(Level::Trace == LevelFilter::Trace);
1770    }
1771
1772    #[test]
1773    fn test_to_level() {
1774        assert_eq!(Some(Level::Error), LevelFilter::Error.to_level());
1775        assert_eq!(None, LevelFilter::Off.to_level());
1776        assert_eq!(Some(Level::Debug), LevelFilter::Debug.to_level());
1777    }
1778
1779    #[test]
1780    fn test_to_level_filter() {
1781        assert_eq!(LevelFilter::Error, Level::Error.to_level_filter());
1782        assert_eq!(LevelFilter::Trace, Level::Trace.to_level_filter());
1783    }
1784
1785    #[test]
1786    fn test_level_filter_as_str() {
1787        let tests = &[
1788            (LevelFilter::Off, "OFF"),
1789            (LevelFilter::Error, "ERROR"),
1790            (LevelFilter::Warn, "WARN"),
1791            (LevelFilter::Info, "INFO"),
1792            (LevelFilter::Debug, "DEBUG"),
1793            (LevelFilter::Trace, "TRACE"),
1794        ];
1795        for (input, expected) in tests {
1796            assert_eq!(*expected, input.as_str());
1797        }
1798    }
1799
1800    #[test]
1801    #[cfg(feature = "std")]
1802    fn test_error_trait() {
1803        use super::SetLoggerError;
1804        let e = SetLoggerError(());
1805        assert_eq!(
1806            &e.to_string(),
1807            "attempted to set a logger after the logging system \
1808             was already initialized"
1809        );
1810    }
1811
1812    #[test]
1813    fn test_metadata_builder() {
1814        use super::MetadataBuilder;
1815        let target = "myApp";
1816        let metadata_test = MetadataBuilder::new()
1817            .level(Level::Debug)
1818            .target(target)
1819            .build();
1820        assert_eq!(metadata_test.level(), Level::Debug);
1821        assert_eq!(metadata_test.target(), "myApp");
1822    }
1823
1824    #[test]
1825    fn test_metadata_convenience_builder() {
1826        use super::Metadata;
1827        let target = "myApp";
1828        let metadata_test = Metadata::builder()
1829            .level(Level::Debug)
1830            .target(target)
1831            .build();
1832        assert_eq!(metadata_test.level(), Level::Debug);
1833        assert_eq!(metadata_test.target(), "myApp");
1834    }
1835
1836    #[test]
1837    fn test_record_builder() {
1838        use super::{MetadataBuilder, RecordBuilder};
1839        let target = "myApp";
1840        let metadata = MetadataBuilder::new().target(target).build();
1841        let fmt_args = format_args!("hello");
1842        let record_test = RecordBuilder::new()
1843            .args(fmt_args)
1844            .metadata(metadata)
1845            .module_path(Some("foo"))
1846            .file(Some("bar"))
1847            .line(Some(30))
1848            .build();
1849        assert_eq!(record_test.metadata().target(), "myApp");
1850        assert_eq!(record_test.module_path(), Some("foo"));
1851        assert_eq!(record_test.file(), Some("bar"));
1852        assert_eq!(record_test.line(), Some(30));
1853    }
1854
1855    #[test]
1856    fn test_record_convenience_builder() {
1857        use super::{Metadata, Record};
1858        let target = "myApp";
1859        let metadata = Metadata::builder().target(target).build();
1860        let fmt_args = format_args!("hello");
1861        let record_test = Record::builder()
1862            .args(fmt_args)
1863            .metadata(metadata)
1864            .module_path(Some("foo"))
1865            .file(Some("bar"))
1866            .line(Some(30))
1867            .build();
1868        assert_eq!(record_test.target(), "myApp");
1869        assert_eq!(record_test.module_path(), Some("foo"));
1870        assert_eq!(record_test.file(), Some("bar"));
1871        assert_eq!(record_test.line(), Some(30));
1872    }
1873
1874    #[test]
1875    fn test_record_complete_builder() {
1876        use super::{Level, Record};
1877        let target = "myApp";
1878        let record_test = Record::builder()
1879            .module_path(Some("foo"))
1880            .file(Some("bar"))
1881            .line(Some(30))
1882            .target(target)
1883            .level(Level::Error)
1884            .build();
1885        assert_eq!(record_test.target(), "myApp");
1886        assert_eq!(record_test.level(), Level::Error);
1887        assert_eq!(record_test.module_path(), Some("foo"));
1888        assert_eq!(record_test.file(), Some("bar"));
1889        assert_eq!(record_test.line(), Some(30));
1890    }
1891
1892    #[test]
1893    #[cfg(feature = "kv_unstable")]
1894    fn test_record_key_values_builder() {
1895        use super::Record;
1896        use kv::{self, Visitor};
1897
1898        struct TestVisitor {
1899            seen_pairs: usize,
1900        }
1901
1902        impl<'kvs> Visitor<'kvs> for TestVisitor {
1903            fn visit_pair(
1904                &mut self,
1905                _: kv::Key<'kvs>,
1906                _: kv::Value<'kvs>,
1907            ) -> Result<(), kv::Error> {
1908                self.seen_pairs += 1;
1909                Ok(())
1910            }
1911        }
1912
1913        let kvs: &[(&str, i32)] = &[("a", 1), ("b", 2)];
1914        let record_test = Record::builder().key_values(&kvs).build();
1915
1916        let mut visitor = TestVisitor { seen_pairs: 0 };
1917
1918        record_test.key_values().visit(&mut visitor).unwrap();
1919
1920        assert_eq!(2, visitor.seen_pairs);
1921    }
1922
1923    #[test]
1924    #[cfg(feature = "kv_unstable")]
1925    fn test_record_key_values_get_coerce() {
1926        use super::Record;
1927
1928        let kvs: &[(&str, &str)] = &[("a", "1"), ("b", "2")];
1929        let record = Record::builder().key_values(&kvs).build();
1930
1931        assert_eq!(
1932            "2",
1933            record
1934                .key_values()
1935                .get("b".into())
1936                .expect("missing key")
1937                .to_borrowed_str()
1938                .expect("invalid value")
1939        );
1940    }
1941
1942    // Test that the `impl Log for Foo` blocks work
1943    // This test mostly operates on a type level, so failures will be compile errors
1944    #[test]
1945    fn test_foreign_impl() {
1946        use super::Log;
1947        #[cfg(feature = "std")]
1948        use std::sync::Arc;
1949
1950        fn assert_is_log<T: Log + ?Sized>() {}
1951
1952        assert_is_log::<&dyn Log>();
1953
1954        #[cfg(feature = "std")]
1955        assert_is_log::<Box<dyn Log>>();
1956
1957        #[cfg(feature = "std")]
1958        assert_is_log::<Arc<dyn Log>>();
1959
1960        // Assert these statements for all T: Log + ?Sized
1961        #[allow(unused)]
1962        fn forall<T: Log + ?Sized>() {
1963            #[cfg(feature = "std")]
1964            assert_is_log::<Box<T>>();
1965
1966            assert_is_log::<&T>();
1967
1968            #[cfg(feature = "std")]
1969            assert_is_log::<Arc<T>>();
1970        }
1971    }
1972}
1973