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