diff --git a/src/lib.rs b/src/lib.rs
index c79219d..83b78d0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,1668 +1,1679 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A lightweight logging facade.
-//!
-//! The `log` crate provides a single logging API that abstracts over the
-//! actual logging implementation. Libraries can use the logging API provided
-//! by this crate, and the consumer of those libraries can choose the logging
-//! implementation that is most suitable for its use case.
-//!
-//! If no logging implementation is selected, the facade falls back to a "noop"
-//! implementation that ignores all log messages. The overhead in this case
-//! is very small - just an integer load, comparison and jump.
-//!
-//! A log request consists of a _target_, a _level_, and a _body_. A target is a
-//! string which defaults to the module path of the location of the log request,
-//! though that default may be overridden. Logger implementations typically use
-//! the target to filter requests based on some user configuration.
-//!
-//! # Use
-//!
-//! The basic use of the log crate is through the five logging macros: [`error!`],
-//! [`warn!`], [`info!`], [`debug!`] and [`trace!`]
-//! where `error!` represents the highest-priority log messages
-//! and `trace!` the lowest. The log messages are filtered by configuring
-//! the log level to exclude messages with a lower priority.
-//! Each of these macros accept format strings similarly to [`println!`].
-//!
-//!
-//! [`error!`]: ./macro.error.html
-//! [`warn!`]: ./macro.warn.html
-//! [`info!`]: ./macro.info.html
-//! [`debug!`]: ./macro.debug.html
-//! [`trace!`]: ./macro.trace.html
-//! [`println!`]: https://doc.rust-lang.org/stable/std/macro.println.html
-//!
-//! ## In libraries
-//!
-//! Libraries should link only to the `log` crate, and use the provided
-//! macros to log whatever information will be useful to downstream consumers.
-//!
-//! ### Examples
-//!
-//! ```edition2018
-//! # #[derive(Debug)] pub struct Yak(String);
-//! # impl Yak { fn shave(&mut self, _: u32) {} }
-//! # fn find_a_razor() -> Result<u32, u32> { Ok(1) }
-//! use log::{info, warn};
-//!
-//! pub fn shave_the_yak(yak: &mut Yak) {
-//!     info!(target: "yak_events", "Commencing yak shaving for {:?}", yak);
-//!
-//!     loop {
-//!         match find_a_razor() {
-//!             Ok(razor) => {
-//!                 info!("Razor located: {}", razor);
-//!                 yak.shave(razor);
-//!                 break;
-//!             }
-//!             Err(err) => {
-//!                 warn!("Unable to locate a razor: {}, retrying", err);
-//!             }
-//!         }
-//!     }
-//! }
-//! # fn main() {}
-//! ```
-//!
-//! ## In executables
-//!
-//! Executables should choose a logging implementation and initialize it early in the
-//! runtime of the program. Logging implementations will typically include a
-//! function to do this. Any log messages generated before
-//! the implementation is initialized will be ignored.
-//!
-//! The executable itself may use the `log` crate to log as well.
-//!
-//! ### Warning
-//!
-//! The logging system may only be initialized once.
-//!
-//! # Available logging implementations
-//!
-//! In order to produce log output executables have to use
-//! a logger implementation compatible with the facade.
-//! There are many available implementations to choose from,
-//! here are some of the most popular ones:
-//!
-//! * Simple minimal loggers:
-//!     * [env_logger]
-//!     * [simple_logger]
-//!     * [simplelog]
-//!     * [pretty_env_logger]
-//!     * [stderrlog]
-//!     * [flexi_logger]
-//! * Complex configurable frameworks:
-//!     * [log4rs]
-//!     * [fern]
-//! * Adaptors for other facilities:
-//!     * [syslog]
-//!     * [slog-stdlog]
-//!
-//! # Implementing a Logger
-//!
-//! Loggers implement the [`Log`] trait. Here's a very basic example that simply
-//! logs all messages at the [`Error`][level_link], [`Warn`][level_link] or
-//! [`Info`][level_link] levels to stdout:
-//!
-//! ```edition2018
-//! use log::{Record, Level, Metadata};
-//!
-//! struct SimpleLogger;
-//!
-//! impl log::Log for SimpleLogger {
-//!     fn enabled(&self, metadata: &Metadata) -> bool {
-//!         metadata.level() <= Level::Info
-//!     }
-//!
-//!     fn log(&self, record: &Record) {
-//!         if self.enabled(record.metadata()) {
-//!             println!("{} - {}", record.level(), record.args());
-//!         }
-//!     }
-//!
-//!     fn flush(&self) {}
-//! }
-//!
-//! # fn main() {}
-//! ```
-//!
-//! Loggers are installed by calling the [`set_logger`] function. The maximum
-//! log level also needs to be adjusted via the [`set_max_level`] function. The
-//! logging facade uses this as an optimization to improve performance of log
-//! messages at levels that are disabled. It's important to set it, as it
-//! defaults to [`Off`][filter_link], so no log messages will ever be captured!
-//! In the case of our example logger, we'll want to set the maximum log level
-//! to [`Info`][filter_link], since we ignore any [`Debug`][level_link] or
-//! [`Trace`][level_link] level log messages. A logging implementation should
-//! provide a function that wraps a call to [`set_logger`] and
-//! [`set_max_level`], handling initialization of the logger:
-//!
-//! ```edition2018
-//! # use log::{Level, Metadata};
-//! # struct SimpleLogger;
-//! # impl log::Log for SimpleLogger {
-//! #   fn enabled(&self, _: &Metadata) -> bool { false }
-//! #   fn log(&self, _: &log::Record) {}
-//! #   fn flush(&self) {}
-//! # }
-//! # fn main() {}
-//! use log::{SetLoggerError, LevelFilter};
-//!
-//! static LOGGER: SimpleLogger = SimpleLogger;
-//!
-//! pub fn init() -> Result<(), SetLoggerError> {
-//!     log::set_logger(&LOGGER)
-//!         .map(|()| log::set_max_level(LevelFilter::Info))
-//! }
-//! ```
-//!
-//! Implementations that adjust their configurations at runtime should take care
-//! to adjust the maximum log level as well.
-//!
-//! # Use with `std`
-//!
-//! `set_logger` requires you to provide a `&'static Log`, which can be hard to
-//! obtain if your logger depends on some runtime configuration. The
-//! `set_boxed_logger` function is available with the `std` Cargo feature. It is
-//! identical to `set_logger` except that it takes a `Box<Log>` rather than a
-//! `&'static Log`:
-//!
-//! ```edition2018
-//! # use log::{Level, LevelFilter, Log, SetLoggerError, Metadata};
-//! # struct SimpleLogger;
-//! # impl log::Log for SimpleLogger {
-//! #   fn enabled(&self, _: &Metadata) -> bool { false }
-//! #   fn log(&self, _: &log::Record) {}
-//! #   fn flush(&self) {}
-//! # }
-//! # fn main() {}
-//! # #[cfg(feature = "std")]
-//! pub fn init() -> Result<(), SetLoggerError> {
-//!     log::set_boxed_logger(Box::new(SimpleLogger))
-//!         .map(|()| log::set_max_level(LevelFilter::Info))
-//! }
-//! ```
-//!
-//! # Compile time filters
-//!
-//! Log levels can be statically disabled at compile time via Cargo features. Log invocations at
-//! disabled levels will be skipped and will not even be present in the resulting binary unless the
-//! log level is specified dynamically. This level is configured separately for release and debug
-//! builds. The features are:
-//!
-//! * `max_level_off`
-//! * `max_level_error`
-//! * `max_level_warn`
-//! * `max_level_info`
-//! * `max_level_debug`
-//! * `max_level_trace`
-//! * `release_max_level_off`
-//! * `release_max_level_error`
-//! * `release_max_level_warn`
-//! * `release_max_level_info`
-//! * `release_max_level_debug`
-//! * `release_max_level_trace`
-//!
-//! These features control the value of the `STATIC_MAX_LEVEL` constant. The logging macros check
-//! this value before logging a message. By default, no levels are disabled.
-//!
-//! Libraries should avoid using the max level features because they're global and can't be changed
-//! once they're set.
-//!
-//! For example, a crate can disable trace level logs in debug builds and trace, debug, and info
-//! level logs in release builds with the following configuration:
-//!
-//! ```toml
-//! [dependencies]
-//! log = { version = "0.4", features = ["max_level_debug", "release_max_level_warn"] }
-//! ```
-//! # Crate Feature Flags
-//!
-//! The following crate feature flags are avaliable in addition to the filters. They are
-//! configured in your `Cargo.toml`.
-//!
-//! * `std` allows use of `std` crate instead of the default `core`. Enables using `std::error` and
-//! `set_boxed_logger` functionality.
-//! * `serde` enables support for serialization and deserialization of `Level` and `LevelFilter`.
-//!
-//! ```toml
-//! [dependencies]
-//! log = { version = "0.4", features = ["std", "serde"] }
-//! ```
-//!
-//! # Version compatibility
-//!
-//! The 0.3 and 0.4 versions of the `log` crate are almost entirely compatible. Log messages
-//! made using `log` 0.3 will forward transparently to a logger implementation using `log` 0.4. Log
-//! messages made using `log` 0.4 will forward to a logger implementation using `log` 0.3, but the
-//! module path and file name information associated with the message will unfortunately be lost.
-//!
-//! [`Log`]: trait.Log.html
-//! [level_link]: enum.Level.html
-//! [filter_link]: enum.LevelFilter.html
-//! [`set_logger`]: fn.set_logger.html
-//! [`set_max_level`]: fn.set_max_level.html
-//! [`try_set_logger_raw`]: fn.try_set_logger_raw.html
-//! [`shutdown_logger_raw`]: fn.shutdown_logger_raw.html
-//! [env_logger]: https://docs.rs/env_logger/*/env_logger/
-//! [simple_logger]: https://github.com/borntyping/rust-simple_logger
-//! [simplelog]: https://github.com/drakulix/simplelog.rs
-//! [pretty_env_logger]: https://docs.rs/pretty_env_logger/*/pretty_env_logger/
-//! [stderrlog]: https://docs.rs/stderrlog/*/stderrlog/
-//! [flexi_logger]: https://docs.rs/flexi_logger/*/flexi_logger/
-//! [syslog]: https://docs.rs/syslog/*/syslog/
-//! [slog-stdlog]: https://docs.rs/slog-stdlog/*/slog_stdlog/
-//! [log4rs]: https://docs.rs/log4rs/*/log4rs/
-//! [fern]: https://docs.rs/fern/*/fern/
-
-#![doc(
-    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-    html_favicon_url = "https://www.rust-lang.org/favicon.ico",
-    html_root_url = "https://docs.rs/log/0.4.8"
-)]
-#![warn(missing_docs)]
-#![deny(missing_debug_implementations)]
-#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
-// When compiled for the rustc compiler itself we want to make sure that this is
-// an unstable crate
-#![cfg_attr(rustbuild, feature(staged_api, rustc_private))]
-#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))]
-
-#[cfg(all(not(feature = "std"), not(test)))]
-extern crate core as std;
-
-#[macro_use]
-extern crate cfg_if;
-
-use std::cmp;
-#[cfg(feature = "std")]
-use std::error;
-use std::fmt;
-use std::mem;
-use std::str::FromStr;
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-// FIXME: ATOMIC_USIZE_INIT was deprecated in rust 1.34. Silence the
-// deprecation warning until our MSRV >= 1.24, where we can use the
-// replacement const fn `AtomicUsize::new`
-#[allow(deprecated)]
-use std::sync::atomic::ATOMIC_USIZE_INIT;
-
-#[macro_use]
-mod macros;
-mod serde;
-
-#[cfg(feature = "kv_unstable")]
-pub mod kv;
-
-// The LOGGER static holds a pointer to the global logger. It is protected by
-// the STATE static which determines whether LOGGER has been initialized yet.
-static mut LOGGER: &'static Log = &NopLogger;
-
-#[allow(deprecated)]
-static STATE: AtomicUsize = ATOMIC_USIZE_INIT;
-
-// There are three different states that we care about: the logger's
-// uninitialized, the logger's initializing (set_logger's been called but
-// LOGGER hasn't actually been set yet), or the logger's active.
-const UNINITIALIZED: usize = 0;
-const INITIALIZING: usize = 1;
-const INITIALIZED: usize = 2;
-
-#[allow(deprecated)]
-static MAX_LOG_LEVEL_FILTER: AtomicUsize = ATOMIC_USIZE_INIT;
-
-static LOG_LEVEL_NAMES: [&'static str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"];
-
-static SET_LOGGER_ERROR: &'static str = "attempted to set a logger after the logging system \
-                                         was already initialized";
-static LEVEL_PARSE_ERROR: &'static str =
-    "attempted to convert a string that doesn't match an existing log level";
-
-/// An enum representing the available verbosity levels of the logger.
-///
-/// Typical usage includes: checking if a certain `Level` is enabled with
-/// [`log_enabled!`](macro.log_enabled.html), specifying the `Level` of
-/// [`log!`](macro.log.html), and comparing a `Level` directly to a
-/// [`LevelFilter`](enum.LevelFilter.html).
-#[repr(usize)]
-#[derive(Copy, Eq, Debug, Hash)]
-pub enum Level {
-    /// The "error" level.
-    ///
-    /// Designates very serious errors.
-    Error = 1, // This way these line up with the discriminants for LevelFilter below
-    /// The "warn" level.
-    ///
-    /// Designates hazardous situations.
-    Warn,
-    /// The "info" level.
-    ///
-    /// Designates useful information.
-    Info,
-    /// The "debug" level.
-    ///
-    /// Designates lower priority information.
-    Debug,
-    /// The "trace" level.
-    ///
-    /// Designates very low priority, often extremely verbose, information.
-    Trace,
-}
-
-impl Clone for Level {
-    #[inline]
-    fn clone(&self) -> Level {
-        *self
-    }
-}
-
-impl PartialEq for Level {
-    #[inline]
-    fn eq(&self, other: &Level) -> bool {
-        *self as usize == *other as usize
-    }
-}
-
-impl PartialEq<LevelFilter> for Level {
-    #[inline]
-    fn eq(&self, other: &LevelFilter) -> bool {
-        *self as usize == *other as usize
-    }
-}
-
-impl PartialOrd for Level {
-    #[inline]
-    fn partial_cmp(&self, other: &Level) -> Option<cmp::Ordering> {
-        Some(self.cmp(other))
-    }
-
-    #[inline]
-    fn lt(&self, other: &Level) -> bool {
-        (*self as usize) < *other as usize
-    }
-
-    #[inline]
-    fn le(&self, other: &Level) -> bool {
-        *self as usize <= *other as usize
-    }
-
-    #[inline]
-    fn gt(&self, other: &Level) -> bool {
-        *self as usize > *other as usize
-    }
-
-    #[inline]
-    fn ge(&self, other: &Level) -> bool {
-        *self as usize >= *other as usize
-    }
-}
-
-impl PartialOrd<LevelFilter> for Level {
-    #[inline]
-    fn partial_cmp(&self, other: &LevelFilter) -> Option<cmp::Ordering> {
-        Some((*self as usize).cmp(&(*other as usize)))
-    }
-
-    #[inline]
-    fn lt(&self, other: &LevelFilter) -> bool {
-        (*self as usize) < *other as usize
-    }
-
-    #[inline]
-    fn le(&self, other: &LevelFilter) -> bool {
-        *self as usize <= *other as usize
-    }
-
-    #[inline]
-    fn gt(&self, other: &LevelFilter) -> bool {
-        *self as usize > *other as usize
-    }
-
-    #[inline]
-    fn ge(&self, other: &LevelFilter) -> bool {
-        *self as usize >= *other as usize
-    }
-}
-
-impl Ord for Level {
-    #[inline]
-    fn cmp(&self, other: &Level) -> cmp::Ordering {
-        (*self as usize).cmp(&(*other as usize))
-    }
-}
-
-fn ok_or<T, E>(t: Option<T>, e: E) -> Result<T, E> {
-    match t {
-        Some(t) => Ok(t),
-        None => Err(e),
-    }
-}
-
-// Reimplemented here because std::ascii is not available in libcore
-fn eq_ignore_ascii_case(a: &str, b: &str) -> bool {
-    fn to_ascii_uppercase(c: u8) -> u8 {
-        if c >= b'a' && c <= b'z' {
-            c - b'a' + b'A'
-        } else {
-            c
-        }
-    }
-
-    if a.len() == b.len() {
-        a.bytes()
-            .zip(b.bytes())
-            .all(|(a, b)| to_ascii_uppercase(a) == to_ascii_uppercase(b))
-    } else {
-        false
-    }
-}
-
-impl FromStr for Level {
-    type Err = ParseLevelError;
-    fn from_str(level: &str) -> Result<Level, Self::Err> {
-        ok_or(
-            LOG_LEVEL_NAMES
-                .iter()
-                .position(|&name| eq_ignore_ascii_case(name, level))
-                .into_iter()
-                .filter(|&idx| idx != 0)
-                .map(|idx| Level::from_usize(idx).unwrap())
-                .next(),
-            ParseLevelError(()),
-        )
-    }
-}
-
-impl fmt::Display for Level {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        fmt.pad(LOG_LEVEL_NAMES[*self as usize])
-    }
-}
-
-impl Level {
-    fn from_usize(u: usize) -> Option<Level> {
-        match u {
-            1 => Some(Level::Error),
-            2 => Some(Level::Warn),
-            3 => Some(Level::Info),
-            4 => Some(Level::Debug),
-            5 => Some(Level::Trace),
-            _ => None,
-        }
-    }
-
-    /// Returns the most verbose logging level.
-    #[inline]
-    pub fn max() -> Level {
-        Level::Trace
-    }
-
-    /// Converts the `Level` to the equivalent `LevelFilter`.
-    #[inline]
-    pub fn to_level_filter(&self) -> LevelFilter {
-        LevelFilter::from_usize(*self as usize).unwrap()
-    }
-}
-
-/// An enum representing the available verbosity level filters of the logger.
-///
-/// A `LevelFilter` may be compared directly to a [`Level`]. Use this type
-/// to get and set the maximum log level with [`max_level()`] and [`set_max_level`].
-///
-/// [`Level`]: enum.Level.html
-/// [`max_level()`]: fn.max_level.html
-/// [`set_max_level`]: fn.set_max_level.html
-#[repr(usize)]
-#[derive(Copy, Eq, Debug, Hash)]
-pub enum LevelFilter {
-    /// A level lower than all log levels.
-    Off,
-    /// Corresponds to the `Error` log level.
-    Error,
-    /// Corresponds to the `Warn` log level.
-    Warn,
-    /// Corresponds to the `Info` log level.
-    Info,
-    /// Corresponds to the `Debug` log level.
-    Debug,
-    /// Corresponds to the `Trace` log level.
-    Trace,
-}
-
-// Deriving generates terrible impls of these traits
-
-impl Clone for LevelFilter {
-    #[inline]
-    fn clone(&self) -> LevelFilter {
-        *self
-    }
-}
-
-impl PartialEq for LevelFilter {
-    #[inline]
-    fn eq(&self, other: &LevelFilter) -> bool {
-        *self as usize == *other as usize
-    }
-}
-
-impl PartialEq<Level> for LevelFilter {
-    #[inline]
-    fn eq(&self, other: &Level) -> bool {
-        other.eq(self)
-    }
-}
-
-impl PartialOrd for LevelFilter {
-    #[inline]
-    fn partial_cmp(&self, other: &LevelFilter) -> Option<cmp::Ordering> {
-        Some(self.cmp(other))
-    }
-
-    #[inline]
-    fn lt(&self, other: &LevelFilter) -> bool {
-        (*self as usize) < *other as usize
-    }
-
-    #[inline]
-    fn le(&self, other: &LevelFilter) -> bool {
-        *self as usize <= *other as usize
-    }
-
-    #[inline]
-    fn gt(&self, other: &LevelFilter) -> bool {
-        *self as usize > *other as usize
-    }
-
-    #[inline]
-    fn ge(&self, other: &LevelFilter) -> bool {
-        *self as usize >= *other as usize
-    }
-}
-
-impl PartialOrd<Level> for LevelFilter {
-    #[inline]
-    fn partial_cmp(&self, other: &Level) -> Option<cmp::Ordering> {
-        Some((*self as usize).cmp(&(*other as usize)))
-    }
-
-    #[inline]
-    fn lt(&self, other: &Level) -> bool {
-        (*self as usize) < *other as usize
-    }
-
-    #[inline]
-    fn le(&self, other: &Level) -> bool {
-        *self as usize <= *other as usize
-    }
-
-    #[inline]
-    fn gt(&self, other: &Level) -> bool {
-        *self as usize > *other as usize
-    }
-
-    #[inline]
-    fn ge(&self, other: &Level) -> bool {
-        *self as usize >= *other as usize
-    }
-}
-
-impl Ord for LevelFilter {
-    #[inline]
-    fn cmp(&self, other: &LevelFilter) -> cmp::Ordering {
-        (*self as usize).cmp(&(*other as usize))
-    }
-}
-
-impl FromStr for LevelFilter {
-    type Err = ParseLevelError;
-    fn from_str(level: &str) -> Result<LevelFilter, Self::Err> {
-        ok_or(
-            LOG_LEVEL_NAMES
-                .iter()
-                .position(|&name| eq_ignore_ascii_case(name, level))
-                .map(|p| LevelFilter::from_usize(p).unwrap()),
-            ParseLevelError(()),
-        )
-    }
-}
-
-impl fmt::Display for LevelFilter {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        fmt.pad(LOG_LEVEL_NAMES[*self as usize])
-    }
-}
-
-impl LevelFilter {
-    fn from_usize(u: usize) -> Option<LevelFilter> {
-        match u {
-            0 => Some(LevelFilter::Off),
-            1 => Some(LevelFilter::Error),
-            2 => Some(LevelFilter::Warn),
-            3 => Some(LevelFilter::Info),
-            4 => Some(LevelFilter::Debug),
-            5 => Some(LevelFilter::Trace),
-            _ => None,
-        }
-    }
-    /// Returns the most verbose logging level filter.
-    #[inline]
-    pub fn max() -> LevelFilter {
-        LevelFilter::Trace
-    }
-
-    /// Converts `self` to the equivalent `Level`.
-    ///
-    /// Returns `None` if `self` is `LevelFilter::Off`.
-    #[inline]
-    pub fn to_level(&self) -> Option<Level> {
-        Level::from_usize(*self as usize)
-    }
-}
-
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
-enum MaybeStaticStr<'a> {
-    Static(&'static str),
-    Borrowed(&'a str),
-}
-
-impl<'a> MaybeStaticStr<'a> {
-    #[inline]
-    fn get(&self) -> &'a str {
-        match *self {
-            MaybeStaticStr::Static(s) => s,
-            MaybeStaticStr::Borrowed(s) => s,
-        }
-    }
-}
-
-/// The "payload" of a log message.
-///
-/// # Use
-///
-/// `Record` structures are passed as parameters to the [`log`][method.log]
-/// method of the [`Log`] trait. Logger implementors manipulate these
-/// structures in order to display log messages. `Record`s are automatically
-/// created by the [`log!`] macro and so are not seen by log users.
-///
-/// Note that the [`level()`] and [`target()`] accessors are equivalent to
-/// `self.metadata().level()` and `self.metadata().target()` respectively.
-/// These methods are provided as a convenience for users of this structure.
-///
-/// # Example
-///
-/// The following example shows a simple logger that displays the level,
-/// module path, and message of any `Record` that is passed to it.
-///
-/// ```edition2018
-/// struct SimpleLogger;
-///
-/// impl log::Log for SimpleLogger {
-///    fn enabled(&self, metadata: &log::Metadata) -> bool {
-///        true
-///    }
-///
-///    fn log(&self, record: &log::Record) {
-///        if !self.enabled(record.metadata()) {
-///            return;
-///        }
-///
-///        println!("{}:{} -- {}",
-///                 record.level(),
-///                 record.target(),
-///                 record.args());
-///    }
-///    fn flush(&self) {}
-/// }
-/// ```
-///
-/// [method.log]: trait.Log.html#tymethod.log
-/// [`Log`]: trait.Log.html
-/// [`log!`]: macro.log.html
-/// [`level()`]: struct.Record.html#method.level
-/// [`target()`]: struct.Record.html#method.target
-#[derive(Clone, Debug)]
-pub struct Record<'a> {
-    metadata: Metadata<'a>,
-    args: fmt::Arguments<'a>,
-    module_path: Option<MaybeStaticStr<'a>>,
-    file: Option<MaybeStaticStr<'a>>,
-    line: Option<u32>,
-    #[cfg(feature = "kv_unstable")]
-    key_values: KeyValues<'a>,
-}
-
-// This wrapper type is only needed so we can
-// `#[derive(Debug)]` on `Record`. It also
-// provides a useful `Debug` implementation for
-// the underlying `Source`.
-#[cfg(feature = "kv_unstable")]
-#[derive(Clone)]
-struct KeyValues<'a>(&'a kv::Source);
-
-#[cfg(feature = "kv_unstable")]
-impl<'a> fmt::Debug for KeyValues<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let mut visitor = f.debug_map();
-        self.0.visit(&mut visitor)?;
-        visitor.finish()
-    }
-}
-
-impl<'a> Record<'a> {
-    /// Returns a new builder.
-    #[inline]
-    pub fn builder() -> RecordBuilder<'a> {
-        RecordBuilder::new()
-    }
-
-    /// The message body.
-    #[inline]
-    pub fn args(&self) -> &fmt::Arguments<'a> {
-        &self.args
-    }
-
-    /// Metadata about the log directive.
-    #[inline]
-    pub fn metadata(&self) -> &Metadata<'a> {
-        &self.metadata
-    }
-
-    /// The verbosity level of the message.
-    #[inline]
-    pub fn level(&self) -> Level {
-        self.metadata.level()
-    }
-
-    /// The name of the target of the directive.
-    #[inline]
-    pub fn target(&self) -> &'a str {
-        self.metadata.target()
-    }
-
-    /// The module path of the message.
-    #[inline]
-    pub fn module_path(&self) -> Option<&'a str> {
-        self.module_path.map(|s| s.get())
-    }
-
-    /// The module path of the message, if it is a `'static` string.
-    #[inline]
-    pub fn module_path_static(&self) -> Option<&'static str> {
-        match self.module_path {
-            Some(MaybeStaticStr::Static(s)) => Some(s),
-            _ => None,
-        }
-    }
-
-    /// The source file containing the message.
-    #[inline]
-    pub fn file(&self) -> Option<&'a str> {
-        self.file.map(|s| s.get())
-    }
-
-    /// The module path of the message, if it is a `'static` string.
-    #[inline]
-    pub fn file_static(&self) -> Option<&'static str> {
-        match self.file {
-            Some(MaybeStaticStr::Static(s)) => Some(s),
-            _ => None,
-        }
-    }
-
-    /// The line containing the message.
-    #[inline]
-    pub fn line(&self) -> Option<u32> {
-        self.line
-    }
-
-    /// The structued key-value pairs associated with the message.
-    #[cfg(feature = "kv_unstable")]
-    #[inline]
-    pub fn key_values(&self) -> &kv::Source {
-        self.key_values.0
-    }
-
-    /// Create a new [`Builder`](struct.Builder.html) based on this record.
-    #[cfg(feature = "kv_unstable")]
-    #[inline]
-    pub fn to_builder(&self) -> RecordBuilder {
-        RecordBuilder {
-            record: Record {
-                metadata: Metadata {
-                    level: self.metadata.level,
-                    target: self.metadata.target,
-                },
-                args: self.args,
-                module_path: self.module_path,
-                file: self.file,
-                line: self.line,
-                key_values: self.key_values.clone(),
-            }
-        }
-    }
-}
-
-/// Builder for [`Record`](struct.Record.html).
-///
-/// Typically should only be used by log library creators or for testing and "shim loggers".
-/// The `RecordBuilder` can set the different parameters of `Record` object, and returns
-/// the created object when `build` is called.
-///
-/// # Examples
-///
-///
-/// ```edition2018
-/// use log::{Level, Record};
-///
-/// let record = Record::builder()
-///                 .args(format_args!("Error!"))
-///                 .level(Level::Error)
-///                 .target("myApp")
-///                 .file(Some("server.rs"))
-///                 .line(Some(144))
-///                 .module_path(Some("server"))
-///                 .build();
-/// ```
-///
-/// Alternatively, use [`MetadataBuilder`](struct.MetadataBuilder.html):
-///
-/// ```edition2018
-/// use log::{Record, Level, MetadataBuilder};
-///
-/// let error_metadata = MetadataBuilder::new()
-///                         .target("myApp")
-///                         .level(Level::Error)
-///                         .build();
-///
-/// let record = Record::builder()
-///                 .metadata(error_metadata)
-///                 .args(format_args!("Error!"))
-///                 .line(Some(433))
-///                 .file(Some("app.rs"))
-///                 .module_path(Some("server"))
-///                 .build();
-/// ```
-#[derive(Debug)]
-pub struct RecordBuilder<'a> {
-    record: Record<'a>,
-}
-
-impl<'a> RecordBuilder<'a> {
-    /// Construct new `RecordBuilder`.
-    ///
-    /// The default options are:
-    ///
-    /// - `args`: [`format_args!("")`]
-    /// - `metadata`: [`Metadata::builder().build()`]
-    /// - `module_path`: `None`
-    /// - `file`: `None`
-    /// - `line`: `None`
-    ///
-    /// [`format_args!("")`]: https://doc.rust-lang.org/std/macro.format_args.html
-    /// [`Metadata::builder().build()`]: struct.MetadataBuilder.html#method.build
-    #[inline]
-    pub fn new() -> RecordBuilder<'a> {
-        #[cfg(feature = "kv_unstable")]
-        return RecordBuilder {
-            record: Record {
-                args: format_args!(""),
-                metadata: Metadata::builder().build(),
-                module_path: None,
-                file: None,
-                line: None,
-                key_values: KeyValues(&Option::None::<(kv::Key, kv::Value)>),
-            },
-        };
-
-        #[cfg(not(feature = "kv_unstable"))]
-        return RecordBuilder {
-            record: Record {
-                args: format_args!(""),
-                metadata: Metadata::builder().build(),
-                module_path: None,
-                file: None,
-                line: None,
-            },
-        };
-    }
-
-    /// Set [`args`](struct.Record.html#method.args).
-    #[inline]
-    pub fn args(&mut self, args: fmt::Arguments<'a>) -> &mut RecordBuilder<'a> {
-        self.record.args = args;
-        self
-    }
-
-    /// Set [`metadata`](struct.Record.html#method.metadata). Construct a `Metadata` object with [`MetadataBuilder`](struct.MetadataBuilder.html).
-    #[inline]
-    pub fn metadata(&mut self, metadata: Metadata<'a>) -> &mut RecordBuilder<'a> {
-        self.record.metadata = metadata;
-        self
-    }
-
-    /// Set [`Metadata::level`](struct.Metadata.html#method.level).
-    #[inline]
-    pub fn level(&mut self, level: Level) -> &mut RecordBuilder<'a> {
-        self.record.metadata.level = level;
-        self
-    }
-
-    /// Set [`Metadata::target`](struct.Metadata.html#method.target)
-    #[inline]
-    pub fn target(&mut self, target: &'a str) -> &mut RecordBuilder<'a> {
-        self.record.metadata.target = target;
-        self
-    }
-
-    /// Set [`module_path`](struct.Record.html#method.module_path)
-    #[inline]
-    pub fn module_path(&mut self, path: Option<&'a str>) -> &mut RecordBuilder<'a> {
-        self.record.module_path = path.map(MaybeStaticStr::Borrowed);
-        self
-    }
-
-    /// Set [`module_path`](struct.Record.html#method.module_path) to a `'static` string
-    #[inline]
-    pub fn module_path_static(&mut self, path: Option<&'static str>) -> &mut RecordBuilder<'a> {
-        self.record.module_path = path.map(MaybeStaticStr::Static);
-        self
-    }
-
-    /// Set [`file`](struct.Record.html#method.file)
-    #[inline]
-    pub fn file(&mut self, file: Option<&'a str>) -> &mut RecordBuilder<'a> {
-        self.record.file = file.map(MaybeStaticStr::Borrowed);
-        self
-    }
-
-    /// Set [`file`](struct.Record.html#method.file) to a `'static` string.
-    #[inline]
-    pub fn file_static(&mut self, file: Option<&'static str>) -> &mut RecordBuilder<'a> {
-        self.record.file = file.map(MaybeStaticStr::Static);
-        self
-    }
-
-    /// Set [`line`](struct.Record.html#method.line)
-    #[inline]
-    pub fn line(&mut self, line: Option<u32>) -> &mut RecordBuilder<'a> {
-        self.record.line = line;
-        self
-    }
-
-    /// Set [`key_values`](struct.Record.html#method.key_values)
-    #[cfg(feature = "kv_unstable")]
-    #[inline]
-    pub fn key_values(&mut self, kvs: &'a kv::Source) -> &mut RecordBuilder<'a> {
-        self.record.key_values = KeyValues(kvs);
-        self
-    }
-
-    /// Invoke the builder and return a `Record`
-    #[inline]
-    pub fn build(&self) -> Record<'a> {
-        self.record.clone()
-    }
-}
-
-/// Metadata about a log message.
-///
-/// # Use
-///
-/// `Metadata` structs are created when users of the library use
-/// logging macros.
-///
-/// They are consumed by implementations of the `Log` trait in the
-/// `enabled` method.
-///
-/// `Record`s use `Metadata` to determine the log message's severity
-/// and target.
-///
-/// Users should use the `log_enabled!` macro in their code to avoid
-/// constructing expensive log messages.
-///
-/// # Examples
-///
-/// ```edition2018
-/// use log::{Record, Level, Metadata};
-///
-/// struct MyLogger;
-///
-/// impl log::Log for MyLogger {
-///     fn enabled(&self, metadata: &Metadata) -> bool {
-///         metadata.level() <= Level::Info
-///     }
-///
-///     fn log(&self, record: &Record) {
-///         if self.enabled(record.metadata()) {
-///             println!("{} - {}", record.level(), record.args());
-///         }
-///     }
-///     fn flush(&self) {}
-/// }
-///
-/// # fn main(){}
-/// ```
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
-pub struct Metadata<'a> {
-    level: Level,
-    target: &'a str,
-}
-
-impl<'a> Metadata<'a> {
-    /// Returns a new builder.
-    #[inline]
-    pub fn builder() -> MetadataBuilder<'a> {
-        MetadataBuilder::new()
-    }
-
-    /// The verbosity level of the message.
-    #[inline]
-    pub fn level(&self) -> Level {
-        self.level
-    }
-
-    /// The name of the target of the directive.
-    #[inline]
-    pub fn target(&self) -> &'a str {
-        self.target
-    }
-}
-
-/// Builder for [`Metadata`](struct.Metadata.html).
-///
-/// Typically should only be used by log library creators or for testing and "shim loggers".
-/// The `MetadataBuilder` can set the different parameters of a `Metadata` object, and returns
-/// the created object when `build` is called.
-///
-/// # Example
-///
-/// ```edition2018
-/// let target = "myApp";
-/// use log::{Level, MetadataBuilder};
-/// let metadata = MetadataBuilder::new()
-///                     .level(Level::Debug)
-///                     .target(target)
-///                     .build();
-/// ```
-#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
-pub struct MetadataBuilder<'a> {
-    metadata: Metadata<'a>,
-}
-
-impl<'a> MetadataBuilder<'a> {
-    /// Construct a new `MetadataBuilder`.
-    ///
-    /// The default options are:
-    ///
-    /// - `level`: `Level::Info`
-    /// - `target`: `""`
-    #[inline]
-    pub fn new() -> MetadataBuilder<'a> {
-        MetadataBuilder {
-            metadata: Metadata {
-                level: Level::Info,
-                target: "",
-            },
-        }
-    }
-
-    /// Setter for [`level`](struct.Metadata.html#method.level).
-    #[inline]
-    pub fn level(&mut self, arg: Level) -> &mut MetadataBuilder<'a> {
-        self.metadata.level = arg;
-        self
-    }
-
-    /// Setter for [`target`](struct.Metadata.html#method.target).
-    #[inline]
-    pub fn target(&mut self, target: &'a str) -> &mut MetadataBuilder<'a> {
-        self.metadata.target = target;
-        self
-    }
-
-    /// Returns a `Metadata` object.
-    #[inline]
-    pub fn build(&self) -> Metadata<'a> {
-        self.metadata.clone()
-    }
-}
-
-/// A trait encapsulating the operations required of a logger.
-pub trait Log: Sync + Send {
-    /// Determines if a log message with the specified metadata would be
-    /// logged.
-    ///
-    /// This is used by the `log_enabled!` macro to allow callers to avoid
-    /// expensive computation of log message arguments if the message would be
-    /// discarded anyway.
-    fn enabled(&self, metadata: &Metadata) -> bool;
-
-    /// Logs the `Record`.
-    ///
-    /// Note that `enabled` is *not* necessarily called before this method.
-    /// Implementations of `log` should perform all necessary filtering
-    /// internally.
-    fn log(&self, record: &Record);
-
-    /// Flushes any buffered records.
-    fn flush(&self);
-}
-
-// Just used as a dummy initial value for LOGGER
-struct NopLogger;
-
-impl Log for NopLogger {
-    fn enabled(&self, _: &Metadata) -> bool {
-        false
-    }
-
-    fn log(&self, _: &Record) {}
-    fn flush(&self) {}
-}
-
-/// Sets the global maximum log level.
-///
-/// Generally, this should only be called by the active logging implementation.
-#[inline]
-pub fn set_max_level(level: LevelFilter) {
-    MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::SeqCst)
-}
-
-/// Returns the current maximum log level.
-///
-/// The [`log!`], [`error!`], [`warn!`], [`info!`], [`debug!`], and [`trace!`] macros check
-/// this value and discard any message logged at a higher level. The maximum
-/// log level is set by the [`set_max_level`] function.
-///
-/// [`log!`]: macro.log.html
-/// [`error!`]: macro.error.html
-/// [`warn!`]: macro.warn.html
-/// [`info!`]: macro.info.html
-/// [`debug!`]: macro.debug.html
-/// [`trace!`]: macro.trace.html
-/// [`set_max_level`]: fn.set_max_level.html
-#[inline(always)]
-pub fn max_level() -> LevelFilter {
-    unsafe { mem::transmute(MAX_LOG_LEVEL_FILTER.load(Ordering::Relaxed)) }
-}
-
-/// Sets the global logger to a `Box<Log>`.
-///
-/// This is a simple convenience wrapper over `set_logger`, which takes a
-/// `Box<Log>` rather than a `&'static Log`. See the documentation for
-/// [`set_logger`] for more details.
-///
-/// Requires the `std` feature.
-///
-/// # Errors
-///
-/// An error is returned if a logger has already been set.
-///
-/// [`set_logger`]: fn.set_logger.html
-#[cfg(all(feature = "std", atomic_cas))]
-pub fn set_boxed_logger(logger: Box<Log>) -> Result<(), SetLoggerError> {
-    set_logger_inner(|| unsafe { &*Box::into_raw(logger) })
-}
-
-/// Sets the global logger to a `&'static Log`.
-///
-/// This function may only be called once in the lifetime of a program. Any log
-/// events that occur before the call to `set_logger` completes will be ignored.
-///
-/// This function does not typically need to be called manually. Logger
-/// implementations should provide an initialization method that installs the
-/// logger internally.
-///
-/// # Availability
-///
-/// This method is available even when the `std` feature is disabled. However,
-/// it is currently unavailable on `thumbv6` targets, which lack support for
-/// some atomic operations which are used by this function. Even on those
-/// targets, [`set_logger_racy`] will be available.
-///
-/// # Errors
-///
-/// An error is returned if a logger has already been set.
-///
-/// # Examples
-///
-/// ```edition2018
-/// use log::{error, info, warn, Record, Level, Metadata, LevelFilter};
-///
-/// static MY_LOGGER: MyLogger = MyLogger;
-///
-/// struct MyLogger;
-///
-/// impl log::Log for MyLogger {
-///     fn enabled(&self, metadata: &Metadata) -> bool {
-///         metadata.level() <= Level::Info
-///     }
-///
-///     fn log(&self, record: &Record) {
-///         if self.enabled(record.metadata()) {
-///             println!("{} - {}", record.level(), record.args());
-///         }
-///     }
-///     fn flush(&self) {}
-/// }
-///
-/// # fn main(){
-/// log::set_logger(&MY_LOGGER).unwrap();
-/// log::set_max_level(LevelFilter::Info);
-///
-/// info!("hello log");
-/// warn!("warning");
-/// error!("oops");
-/// # }
-/// ```
-///
-/// [`set_logger_racy`]: fn.set_logger_racy.html
-#[cfg(atomic_cas)]
-pub fn set_logger(logger: &'static Log) -> Result<(), SetLoggerError> {
-    set_logger_inner(|| logger)
-}
-
-#[cfg(atomic_cas)]
-fn set_logger_inner<F>(make_logger: F) -> Result<(), SetLoggerError>
-where
-    F: FnOnce() -> &'static Log,
-{
-    unsafe {
-        match STATE.compare_and_swap(UNINITIALIZED, INITIALIZING, Ordering::SeqCst) {
-            UNINITIALIZED => {
-                LOGGER = make_logger();
-                STATE.store(INITIALIZED, Ordering::SeqCst);
-                Ok(())
-            }
-            INITIALIZING => {
-                while STATE.load(Ordering::SeqCst) == INITIALIZING {}
-                Err(SetLoggerError(()))
-            }
-            _ => Err(SetLoggerError(())),
-        }
-    }
-}
-
-/// A thread-unsafe version of [`set_logger`].
-///
-/// This function is available on all platforms, even those that do not have
-/// support for atomics that is needed by [`set_logger`].
-///
-/// In almost all cases, [`set_logger`] should be preferred.
-///
-/// # Safety
-///
-/// This function is only safe to call when no other logger initialization
-/// function is called while this function still executes.
-///
-/// This can be upheld by (for example) making sure that **there are no other
-/// threads**, and (on embedded) that **interrupts are disabled**.
-///
-/// It is safe to use other logging functions while this function runs
-/// (including all logging macros).
-///
-/// [`set_logger`]: fn.set_logger.html
-pub unsafe fn set_logger_racy(logger: &'static Log) -> Result<(), SetLoggerError> {
-    match STATE.load(Ordering::SeqCst) {
-        UNINITIALIZED => {
-            LOGGER = logger;
-            STATE.store(INITIALIZED, Ordering::SeqCst);
-            Ok(())
-        }
-        INITIALIZING => {
-            // This is just plain UB, since we were racing another initialization function
-            unreachable!("set_logger_racy must not be used with other initialization functions")
-        }
-        _ => Err(SetLoggerError(())),
-    }
-}
-
-/// The type returned by [`set_logger`] if [`set_logger`] has already been called.
-///
-/// [`set_logger`]: fn.set_logger.html
-#[allow(missing_copy_implementations)]
-#[derive(Debug)]
-pub struct SetLoggerError(());
-
-impl fmt::Display for SetLoggerError {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        fmt.write_str(SET_LOGGER_ERROR)
-    }
-}
-
-// The Error trait is not available in libcore
-#[cfg(feature = "std")]
-impl error::Error for SetLoggerError {
-    fn description(&self) -> &str {
-        SET_LOGGER_ERROR
-    }
-}
-
-/// The type returned by [`from_str`] when the string doesn't match any of the log levels.
-///
-/// [`from_str`]: https://doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
-#[allow(missing_copy_implementations)]
-#[derive(Debug, PartialEq)]
-pub struct ParseLevelError(());
-
-impl fmt::Display for ParseLevelError {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        fmt.write_str(LEVEL_PARSE_ERROR)
-    }
-}
-
-// The Error trait is not available in libcore
-#[cfg(feature = "std")]
-impl error::Error for ParseLevelError {
-    fn description(&self) -> &str {
-        LEVEL_PARSE_ERROR
-    }
-}
-
-/// Returns a reference to the logger.
-///
-/// If a logger has not been set, a no-op implementation is returned.
-pub fn logger() -> &'static Log {
-    unsafe {
-        if STATE.load(Ordering::SeqCst) != INITIALIZED {
-            static NOP: NopLogger = NopLogger;
-            &NOP
-        } else {
-            LOGGER
-        }
-    }
-}
-
-// WARNING: this is not part of the crate's public API and is subject to change at any time
-#[doc(hidden)]
-pub fn __private_api_log(
-    args: fmt::Arguments,
-    level: Level,
-    &(target, module_path, file, line): &(&str, &'static str, &'static str, u32),
-) {
-    logger().log(
-        &Record::builder()
-            .args(args)
-            .level(level)
-            .target(target)
-            .module_path_static(Some(module_path))
-            .file_static(Some(file))
-            .line(Some(line))
-            .build(),
-    );
-}
-
-// WARNING: this is not part of the crate's public API and is subject to change at any time
-#[doc(hidden)]
-pub fn __private_api_enabled(level: Level, target: &str) -> bool {
-    logger().enabled(&Metadata::builder().level(level).target(target).build())
-}
-
-/// The statically resolved maximum log level.
-///
-/// See the crate level documentation for information on how to configure this.
-///
-/// This value is checked by the log macros, but not by the `Log`ger returned by
-/// the [`logger`] function. Code that manually calls functions on that value
-/// should compare the level against this value.
-///
-/// [`logger`]: fn.logger.html
-pub const STATIC_MAX_LEVEL: LevelFilter = MAX_LEVEL_INNER;
-
-cfg_if! {
-    if #[cfg(all(not(debug_assertions), feature = "release_max_level_off"))] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Off;
-    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_error"))] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Error;
-    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_warn"))] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Warn;
-    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_info"))] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Info;
-    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_debug"))] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Debug;
-    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_trace"))] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Trace;
-    } else if #[cfg(feature = "max_level_off")] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Off;
-    } else if #[cfg(feature = "max_level_error")] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Error;
-    } else if #[cfg(feature = "max_level_warn")] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Warn;
-    } else if #[cfg(feature = "max_level_info")] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Info;
-    } else if #[cfg(feature = "max_level_debug")] {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Debug;
-    } else {
-        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Trace;
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    extern crate std;
-    use super::{Level, LevelFilter, ParseLevelError};
-    use tests::std::string::ToString;
-
-    #[test]
-    fn test_levelfilter_from_str() {
-        let tests = [
-            ("off", Ok(LevelFilter::Off)),
-            ("error", Ok(LevelFilter::Error)),
-            ("warn", Ok(LevelFilter::Warn)),
-            ("info", Ok(LevelFilter::Info)),
-            ("debug", Ok(LevelFilter::Debug)),
-            ("trace", Ok(LevelFilter::Trace)),
-            ("OFF", Ok(LevelFilter::Off)),
-            ("ERROR", Ok(LevelFilter::Error)),
-            ("WARN", Ok(LevelFilter::Warn)),
-            ("INFO", Ok(LevelFilter::Info)),
-            ("DEBUG", Ok(LevelFilter::Debug)),
-            ("TRACE", Ok(LevelFilter::Trace)),
-            ("asdf", Err(ParseLevelError(()))),
-        ];
-        for &(s, ref expected) in &tests {
-            assert_eq!(expected, &s.parse());
-        }
-    }
-
-    #[test]
-    fn test_level_from_str() {
-        let tests = [
-            ("OFF", Err(ParseLevelError(()))),
-            ("error", Ok(Level::Error)),
-            ("warn", Ok(Level::Warn)),
-            ("info", Ok(Level::Info)),
-            ("debug", Ok(Level::Debug)),
-            ("trace", Ok(Level::Trace)),
-            ("ERROR", Ok(Level::Error)),
-            ("WARN", Ok(Level::Warn)),
-            ("INFO", Ok(Level::Info)),
-            ("DEBUG", Ok(Level::Debug)),
-            ("TRACE", Ok(Level::Trace)),
-            ("asdf", Err(ParseLevelError(()))),
-        ];
-        for &(s, ref expected) in &tests {
-            assert_eq!(expected, &s.parse());
-        }
-    }
-
-    #[test]
-    fn test_level_show() {
-        assert_eq!("INFO", Level::Info.to_string());
-        assert_eq!("ERROR", Level::Error.to_string());
-    }
-
-    #[test]
-    fn test_levelfilter_show() {
-        assert_eq!("OFF", LevelFilter::Off.to_string());
-        assert_eq!("ERROR", LevelFilter::Error.to_string());
-    }
-
-    #[test]
-    fn test_cross_cmp() {
-        assert!(Level::Debug > LevelFilter::Error);
-        assert!(LevelFilter::Warn < Level::Trace);
-        assert!(LevelFilter::Off < Level::Error);
-    }
-
-    #[test]
-    fn test_cross_eq() {
-        assert!(Level::Error == LevelFilter::Error);
-        assert!(LevelFilter::Off != Level::Error);
-        assert!(Level::Trace == LevelFilter::Trace);
-    }
-
-    #[test]
-    fn test_to_level() {
-        assert_eq!(Some(Level::Error), LevelFilter::Error.to_level());
-        assert_eq!(None, LevelFilter::Off.to_level());
-        assert_eq!(Some(Level::Debug), LevelFilter::Debug.to_level());
-    }
-
-    #[test]
-    fn test_to_level_filter() {
-        assert_eq!(LevelFilter::Error, Level::Error.to_level_filter());
-        assert_eq!(LevelFilter::Trace, Level::Trace.to_level_filter());
-    }
-
-    #[test]
-    #[cfg(feature = "std")]
-    fn test_error_trait() {
-        use super::SetLoggerError;
-        use std::error::Error;
-        let e = SetLoggerError(());
-        assert_eq!(
-            e.description(),
-            "attempted to set a logger after the logging system \
-             was already initialized"
-        );
-    }
-
-    #[test]
-    fn test_metadata_builder() {
-        use super::MetadataBuilder;
-        let target = "myApp";
-        let metadata_test = MetadataBuilder::new()
-            .level(Level::Debug)
-            .target(target)
-            .build();
-        assert_eq!(metadata_test.level(), Level::Debug);
-        assert_eq!(metadata_test.target(), "myApp");
-    }
-
-    #[test]
-    fn test_metadata_convenience_builder() {
-        use super::Metadata;
-        let target = "myApp";
-        let metadata_test = Metadata::builder()
-            .level(Level::Debug)
-            .target(target)
-            .build();
-        assert_eq!(metadata_test.level(), Level::Debug);
-        assert_eq!(metadata_test.target(), "myApp");
-    }
-
-    #[test]
-    fn test_record_builder() {
-        use super::{MetadataBuilder, RecordBuilder};
-        let target = "myApp";
-        let metadata = MetadataBuilder::new().target(target).build();
-        let fmt_args = format_args!("hello");
-        let record_test = RecordBuilder::new()
-            .args(fmt_args)
-            .metadata(metadata)
-            .module_path(Some("foo"))
-            .file(Some("bar"))
-            .line(Some(30))
-            .build();
-        assert_eq!(record_test.metadata().target(), "myApp");
-        assert_eq!(record_test.module_path(), Some("foo"));
-        assert_eq!(record_test.file(), Some("bar"));
-        assert_eq!(record_test.line(), Some(30));
-    }
-
-    #[test]
-    fn test_record_convenience_builder() {
-        use super::{Metadata, Record};
-        let target = "myApp";
-        let metadata = Metadata::builder().target(target).build();
-        let fmt_args = format_args!("hello");
-        let record_test = Record::builder()
-            .args(fmt_args)
-            .metadata(metadata)
-            .module_path(Some("foo"))
-            .file(Some("bar"))
-            .line(Some(30))
-            .build();
-        assert_eq!(record_test.target(), "myApp");
-        assert_eq!(record_test.module_path(), Some("foo"));
-        assert_eq!(record_test.file(), Some("bar"));
-        assert_eq!(record_test.line(), Some(30));
-    }
-
-    #[test]
-    fn test_record_complete_builder() {
-        use super::{Level, Record};
-        let target = "myApp";
-        let record_test = Record::builder()
-            .module_path(Some("foo"))
-            .file(Some("bar"))
-            .line(Some(30))
-            .target(target)
-            .level(Level::Error)
-            .build();
-        assert_eq!(record_test.target(), "myApp");
-        assert_eq!(record_test.level(), Level::Error);
-        assert_eq!(record_test.module_path(), Some("foo"));
-        assert_eq!(record_test.file(), Some("bar"));
-        assert_eq!(record_test.line(), Some(30));
-    }
-
-    #[test]
-    #[cfg(feature = "kv_unstable")]
-    fn test_record_key_values_builder() {
-        use super::Record;
-        use kv::{self, Visitor};
-
-        struct TestVisitor {
-            seen_pairs: usize,
-        }
-
-        impl<'kvs> Visitor<'kvs> for TestVisitor {
-            fn visit_pair(
-                &mut self,
-                _: kv::Key<'kvs>,
-                _: kv::Value<'kvs>
-            ) -> Result<(), kv::Error> {
-                self.seen_pairs += 1;
-                Ok(())
-            }
-        }
-
-        let kvs: &[(&str, i32)] = &[
-            ("a", 1),
-            ("b", 2)
-        ];
-        let record_test = Record::builder()
-            .key_values(&kvs)
-            .build();
-
-        let mut visitor = TestVisitor {
-            seen_pairs: 0,
-        };
-
-        record_test.key_values().visit(&mut visitor).unwrap();
-
-        assert_eq!(2, visitor.seen_pairs);
-    }
-}
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A lightweight logging facade.
+//!
+//! The `log` crate provides a single logging API that abstracts over the
+//! actual logging implementation. Libraries can use the logging API provided
+//! by this crate, and the consumer of those libraries can choose the logging
+//! implementation that is most suitable for its use case.
+//!
+//! If no logging implementation is selected, the facade falls back to a "noop"
+//! implementation that ignores all log messages. The overhead in this case
+//! is very small - just an integer load, comparison and jump.
+//!
+//! A log request consists of a _target_, a _level_, and a _body_. A target is a
+//! string which defaults to the module path of the location of the log request,
+//! though that default may be overridden. Logger implementations typically use
+//! the target to filter requests based on some user configuration.
+//!
+//! # Use
+//!
+//! The basic use of the log crate is through the five logging macros: [`error!`],
+//! [`warn!`], [`info!`], [`debug!`] and [`trace!`]
+//! where `error!` represents the highest-priority log messages
+//! and `trace!` the lowest. The log messages are filtered by configuring
+//! the log level to exclude messages with a lower priority.
+//! Each of these macros accept format strings similarly to [`println!`].
+//!
+//!
+//! [`error!`]: ./macro.error.html
+//! [`warn!`]: ./macro.warn.html
+//! [`info!`]: ./macro.info.html
+//! [`debug!`]: ./macro.debug.html
+//! [`trace!`]: ./macro.trace.html
+//! [`println!`]: https://doc.rust-lang.org/stable/std/macro.println.html
+//!
+//! ## In libraries
+//!
+//! Libraries should link only to the `log` crate, and use the provided
+//! macros to log whatever information will be useful to downstream consumers.
+//!
+//! ### Examples
+//!
+//! ```edition2018
+//! # #[derive(Debug)] pub struct Yak(String);
+//! # impl Yak { fn shave(&mut self, _: u32) {} }
+//! # fn find_a_razor() -> Result<u32, u32> { Ok(1) }
+//! use log::{info, warn};
+//!
+//! pub fn shave_the_yak(yak: &mut Yak) {
+//!     info!(target: "yak_events", "Commencing yak shaving for {:?}", yak);
+//!
+//!     loop {
+//!         match find_a_razor() {
+//!             Ok(razor) => {
+//!                 info!("Razor located: {}", razor);
+//!                 yak.shave(razor);
+//!                 break;
+//!             }
+//!             Err(err) => {
+//!                 warn!("Unable to locate a razor: {}, retrying", err);
+//!             }
+//!         }
+//!     }
+//! }
+//! # fn main() {}
+//! ```
+//!
+//! ## In executables
+//!
+//! Executables should choose a logging implementation and initialize it early in the
+//! runtime of the program. Logging implementations will typically include a
+//! function to do this. Any log messages generated before
+//! the implementation is initialized will be ignored.
+//!
+//! The executable itself may use the `log` crate to log as well.
+//!
+//! ### Warning
+//!
+//! The logging system may only be initialized once.
+//!
+//! # Available logging implementations
+//!
+//! In order to produce log output executables have to use
+//! a logger implementation compatible with the facade.
+//! There are many available implementations to choose from,
+//! here are some of the most popular ones:
+//!
+//! * Simple minimal loggers:
+//!     * [env_logger]
+//!     * [simple_logger]
+//!     * [simplelog]
+//!     * [pretty_env_logger]
+//!     * [stderrlog]
+//!     * [flexi_logger]
+//! * Complex configurable frameworks:
+//!     * [log4rs]
+//!     * [fern]
+//! * Adaptors for other facilities:
+//!     * [syslog]
+//!     * [slog-stdlog]
+//!
+//! # Implementing a Logger
+//!
+//! Loggers implement the [`Log`] trait. Here's a very basic example that simply
+//! logs all messages at the [`Error`][level_link], [`Warn`][level_link] or
+//! [`Info`][level_link] levels to stdout:
+//!
+//! ```edition2018
+//! use log::{Record, Level, Metadata};
+//!
+//! struct SimpleLogger;
+//!
+//! impl log::Log for SimpleLogger {
+//!     fn enabled(&self, metadata: &Metadata) -> bool {
+//!         metadata.level() <= Level::Info
+//!     }
+//!
+//!     fn log(&self, record: &Record) {
+//!         if self.enabled(record.metadata()) {
+//!             println!("{} - {}", record.level(), record.args());
+//!         }
+//!     }
+//!
+//!     fn flush(&self) {}
+//! }
+//!
+//! # fn main() {}
+//! ```
+//!
+//! Loggers are installed by calling the [`set_logger`] function. The maximum
+//! log level also needs to be adjusted via the [`set_max_level`] function. The
+//! logging facade uses this as an optimization to improve performance of log
+//! messages at levels that are disabled. It's important to set it, as it
+//! defaults to [`Off`][filter_link], so no log messages will ever be captured!
+//! In the case of our example logger, we'll want to set the maximum log level
+//! to [`Info`][filter_link], since we ignore any [`Debug`][level_link] or
+//! [`Trace`][level_link] level log messages. A logging implementation should
+//! provide a function that wraps a call to [`set_logger`] and
+//! [`set_max_level`], handling initialization of the logger:
+//!
+//! ```edition2018
+//! # use log::{Level, Metadata};
+//! # struct SimpleLogger;
+//! # impl log::Log for SimpleLogger {
+//! #   fn enabled(&self, _: &Metadata) -> bool { false }
+//! #   fn log(&self, _: &log::Record) {}
+//! #   fn flush(&self) {}
+//! # }
+//! # fn main() {}
+//! use log::{SetLoggerError, LevelFilter};
+//!
+//! static LOGGER: SimpleLogger = SimpleLogger;
+//!
+//! pub fn init() -> Result<(), SetLoggerError> {
+//!     log::set_logger(&LOGGER)
+//!         .map(|()| log::set_max_level(LevelFilter::Info))
+//! }
+//! ```
+//!
+//! Implementations that adjust their configurations at runtime should take care
+//! to adjust the maximum log level as well.
+//!
+//! # Use with `std`
+//!
+//! `set_logger` requires you to provide a `&'static Log`, which can be hard to
+//! obtain if your logger depends on some runtime configuration. The
+//! `set_boxed_logger` function is available with the `std` Cargo feature. It is
+//! identical to `set_logger` except that it takes a `Box<Log>` rather than a
+//! `&'static Log`:
+//!
+//! ```edition2018
+//! # use log::{Level, LevelFilter, Log, SetLoggerError, Metadata};
+//! # struct SimpleLogger;
+//! # impl log::Log for SimpleLogger {
+//! #   fn enabled(&self, _: &Metadata) -> bool { false }
+//! #   fn log(&self, _: &log::Record) {}
+//! #   fn flush(&self) {}
+//! # }
+//! # fn main() {}
+//! # #[cfg(feature = "std")]
+//! pub fn init() -> Result<(), SetLoggerError> {
+//!     log::set_boxed_logger(Box::new(SimpleLogger))
+//!         .map(|()| log::set_max_level(LevelFilter::Info))
+//! }
+//! ```
+//!
+//! # Compile time filters
+//!
+//! Log levels can be statically disabled at compile time via Cargo features. Log invocations at
+//! disabled levels will be skipped and will not even be present in the resulting binary.
+//! This level is configured separately for release and debug builds. The features are:
+//!
+//! * `max_level_off`
+//! * `max_level_error`
+//! * `max_level_warn`
+//! * `max_level_info`
+//! * `max_level_debug`
+//! * `max_level_trace`
+//! * `release_max_level_off`
+//! * `release_max_level_error`
+//! * `release_max_level_warn`
+//! * `release_max_level_info`
+//! * `release_max_level_debug`
+//! * `release_max_level_trace`
+//!
+//! These features control the value of the `STATIC_MAX_LEVEL` constant. The logging macros check
+//! this value before logging a message. By default, no levels are disabled.
+//!
+//! Libraries should avoid using the max level features because they're global and can't be changed
+//! once they're set.
+//!
+//! For example, a crate can disable trace level logs in debug builds and trace, debug, and info
+//! level logs in release builds with the following configuration:
+//!
+//! ```toml
+//! [dependencies]
+//! log = { version = "0.4", features = ["max_level_debug", "release_max_level_warn"] }
+//! ```
+//! # Crate Feature Flags
+//!
+//! The following crate feature flags are available in addition to the filters. They are
+//! configured in your `Cargo.toml`.
+//!
+//! * `std` allows use of `std` crate instead of the default `core`. Enables using `std::error` and
+//! `set_boxed_logger` functionality.
+//! * `serde` enables support for serialization and deserialization of `Level` and `LevelFilter`.
+//!
+//! ```toml
+//! [dependencies]
+//! log = { version = "0.4", features = ["std", "serde"] }
+//! ```
+//!
+//! # Version compatibility
+//!
+//! The 0.3 and 0.4 versions of the `log` crate are almost entirely compatible. Log messages
+//! made using `log` 0.3 will forward transparently to a logger implementation using `log` 0.4. Log
+//! messages made using `log` 0.4 will forward to a logger implementation using `log` 0.3, but the
+//! module path and file name information associated with the message will unfortunately be lost.
+//!
+//! [`Log`]: trait.Log.html
+//! [level_link]: enum.Level.html
+//! [filter_link]: enum.LevelFilter.html
+//! [`set_logger`]: fn.set_logger.html
+//! [`set_max_level`]: fn.set_max_level.html
+//! [`try_set_logger_raw`]: fn.try_set_logger_raw.html
+//! [`shutdown_logger_raw`]: fn.shutdown_logger_raw.html
+//! [env_logger]: https://docs.rs/env_logger/*/env_logger/
+//! [simple_logger]: https://github.com/borntyping/rust-simple_logger
+//! [simplelog]: https://github.com/drakulix/simplelog.rs
+//! [pretty_env_logger]: https://docs.rs/pretty_env_logger/*/pretty_env_logger/
+//! [stderrlog]: https://docs.rs/stderrlog/*/stderrlog/
+//! [flexi_logger]: https://docs.rs/flexi_logger/*/flexi_logger/
+//! [syslog]: https://docs.rs/syslog/*/syslog/
+//! [slog-stdlog]: https://docs.rs/slog-stdlog/*/slog_stdlog/
+//! [log4rs]: https://docs.rs/log4rs/*/log4rs/
+//! [fern]: https://docs.rs/fern/*/fern/
+
+#![doc(
+    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+    html_favicon_url = "https://www.rust-lang.org/favicon.ico",
+    html_root_url = "https://docs.rs/log/0.4.11"
+)]
+#![warn(missing_docs)]
+#![deny(missing_debug_implementations)]
+#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
+// When compiled for the rustc compiler itself we want to make sure that this is
+// an unstable crate
+#![cfg_attr(rustbuild, feature(staged_api, rustc_private))]
+#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))]
+
+#[cfg(all(not(feature = "std"), not(test)))]
+extern crate core as std;
+
+#[macro_use]
+extern crate cfg_if;
+
+use std::cmp;
+#[cfg(feature = "std")]
+use std::error;
+use std::fmt;
+use std::mem;
+use std::str::FromStr;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+#[macro_use]
+mod macros;
+mod serde;
+
+#[cfg(feature = "kv_unstable")]
+pub mod kv;
+
+// The LOGGER static holds a pointer to the global logger. It is protected by
+// the STATE static which determines whether LOGGER has been initialized yet.
+static mut LOGGER: &dyn Log = &NopLogger;
+
+static STATE: AtomicUsize = AtomicUsize::new(0);
+
+// There are three different states that we care about: the logger's
+// uninitialized, the logger's initializing (set_logger's been called but
+// LOGGER hasn't actually been set yet), or the logger's active.
+const UNINITIALIZED: usize = 0;
+const INITIALIZING: usize = 1;
+const INITIALIZED: usize = 2;
+
+static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(0);
+
+static LOG_LEVEL_NAMES: [&str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"];
+
+static SET_LOGGER_ERROR: &str = "attempted to set a logger after the logging system \
+                                 was already initialized";
+static LEVEL_PARSE_ERROR: &str =
+    "attempted to convert a string that doesn't match an existing log level";
+
+/// An enum representing the available verbosity levels of the logger.
+///
+/// Typical usage includes: checking if a certain `Level` is enabled with
+/// [`log_enabled!`](macro.log_enabled.html), specifying the `Level` of
+/// [`log!`](macro.log.html), and comparing a `Level` directly to a
+/// [`LevelFilter`](enum.LevelFilter.html).
+#[repr(usize)]
+#[derive(Copy, Eq, Debug, Hash)]
+pub enum Level {
+    /// The "error" level.
+    ///
+    /// Designates very serious errors.
+    // This way these line up with the discriminants for LevelFilter below
+    // This works because Rust treats field-less enums the same way as C does:
+    // https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-field-less-enumerations
+    Error = 1,
+    /// The "warn" level.
+    ///
+    /// Designates hazardous situations.
+    Warn,
+    /// The "info" level.
+    ///
+    /// Designates useful information.
+    Info,
+    /// The "debug" level.
+    ///
+    /// Designates lower priority information.
+    Debug,
+    /// The "trace" level.
+    ///
+    /// Designates very low priority, often extremely verbose, information.
+    Trace,
+}
+
+impl Clone for Level {
+    #[inline]
+    fn clone(&self) -> Level {
+        *self
+    }
+}
+
+impl PartialEq for Level {
+    #[inline]
+    fn eq(&self, other: &Level) -> bool {
+        *self as usize == *other as usize
+    }
+}
+
+impl PartialEq<LevelFilter> for Level {
+    #[inline]
+    fn eq(&self, other: &LevelFilter) -> bool {
+        *self as usize == *other as usize
+    }
+}
+
+impl PartialOrd for Level {
+    #[inline]
+    fn partial_cmp(&self, other: &Level) -> Option<cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+
+    #[inline]
+    fn lt(&self, other: &Level) -> bool {
+        (*self as usize) < *other as usize
+    }
+
+    #[inline]
+    fn le(&self, other: &Level) -> bool {
+        *self as usize <= *other as usize
+    }
+
+    #[inline]
+    fn gt(&self, other: &Level) -> bool {
+        *self as usize > *other as usize
+    }
+
+    #[inline]
+    fn ge(&self, other: &Level) -> bool {
+        *self as usize >= *other as usize
+    }
+}
+
+impl PartialOrd<LevelFilter> for Level {
+    #[inline]
+    fn partial_cmp(&self, other: &LevelFilter) -> Option<cmp::Ordering> {
+        Some((*self as usize).cmp(&(*other as usize)))
+    }
+
+    #[inline]
+    fn lt(&self, other: &LevelFilter) -> bool {
+        (*self as usize) < *other as usize
+    }
+
+    #[inline]
+    fn le(&self, other: &LevelFilter) -> bool {
+        *self as usize <= *other as usize
+    }
+
+    #[inline]
+    fn gt(&self, other: &LevelFilter) -> bool {
+        *self as usize > *other as usize
+    }
+
+    #[inline]
+    fn ge(&self, other: &LevelFilter) -> bool {
+        *self as usize >= *other as usize
+    }
+}
+
+impl Ord for Level {
+    #[inline]
+    fn cmp(&self, other: &Level) -> cmp::Ordering {
+        (*self as usize).cmp(&(*other as usize))
+    }
+}
+
+fn ok_or<T, E>(t: Option<T>, e: E) -> Result<T, E> {
+    match t {
+        Some(t) => Ok(t),
+        None => Err(e),
+    }
+}
+
+// Reimplemented here because std::ascii is not available in libcore
+fn eq_ignore_ascii_case(a: &str, b: &str) -> bool {
+    fn to_ascii_uppercase(c: u8) -> u8 {
+        if c >= b'a' && c <= b'z' {
+            c - b'a' + b'A'
+        } else {
+            c
+        }
+    }
+
+    if a.len() == b.len() {
+        a.bytes()
+            .zip(b.bytes())
+            .all(|(a, b)| to_ascii_uppercase(a) == to_ascii_uppercase(b))
+    } else {
+        false
+    }
+}
+
+impl FromStr for Level {
+    type Err = ParseLevelError;
+    fn from_str(level: &str) -> Result<Level, Self::Err> {
+        ok_or(
+            LOG_LEVEL_NAMES
+                .iter()
+                .position(|&name| eq_ignore_ascii_case(name, level))
+                .into_iter()
+                .filter(|&idx| idx != 0)
+                .map(|idx| Level::from_usize(idx).unwrap())
+                .next(),
+            ParseLevelError(()),
+        )
+    }
+}
+
+impl fmt::Display for Level {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.pad(LOG_LEVEL_NAMES[*self as usize])
+    }
+}
+
+impl Level {
+    fn from_usize(u: usize) -> Option<Level> {
+        match u {
+            1 => Some(Level::Error),
+            2 => Some(Level::Warn),
+            3 => Some(Level::Info),
+            4 => Some(Level::Debug),
+            5 => Some(Level::Trace),
+            _ => None,
+        }
+    }
+
+    /// Returns the most verbose logging level.
+    #[inline]
+    pub fn max() -> Level {
+        Level::Trace
+    }
+
+    /// Converts the `Level` to the equivalent `LevelFilter`.
+    #[inline]
+    pub fn to_level_filter(&self) -> LevelFilter {
+        LevelFilter::from_usize(*self as usize).unwrap()
+    }
+}
+
+/// An enum representing the available verbosity level filters of the logger.
+///
+/// A `LevelFilter` may be compared directly to a [`Level`]. Use this type
+/// to get and set the maximum log level with [`max_level()`] and [`set_max_level`].
+///
+/// [`Level`]: enum.Level.html
+/// [`max_level()`]: fn.max_level.html
+/// [`set_max_level`]: fn.set_max_level.html
+#[repr(usize)]
+#[derive(Copy, Eq, Debug, Hash)]
+pub enum LevelFilter {
+    /// A level lower than all log levels.
+    Off,
+    /// Corresponds to the `Error` log level.
+    Error,
+    /// Corresponds to the `Warn` log level.
+    Warn,
+    /// Corresponds to the `Info` log level.
+    Info,
+    /// Corresponds to the `Debug` log level.
+    Debug,
+    /// Corresponds to the `Trace` log level.
+    Trace,
+}
+
+// Deriving generates terrible impls of these traits
+
+impl Clone for LevelFilter {
+    #[inline]
+    fn clone(&self) -> LevelFilter {
+        *self
+    }
+}
+
+impl PartialEq for LevelFilter {
+    #[inline]
+    fn eq(&self, other: &LevelFilter) -> bool {
+        *self as usize == *other as usize
+    }
+}
+
+impl PartialEq<Level> for LevelFilter {
+    #[inline]
+    fn eq(&self, other: &Level) -> bool {
+        other.eq(self)
+    }
+}
+
+impl PartialOrd for LevelFilter {
+    #[inline]
+    fn partial_cmp(&self, other: &LevelFilter) -> Option<cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+
+    #[inline]
+    fn lt(&self, other: &LevelFilter) -> bool {
+        (*self as usize) < *other as usize
+    }
+
+    #[inline]
+    fn le(&self, other: &LevelFilter) -> bool {
+        *self as usize <= *other as usize
+    }
+
+    #[inline]
+    fn gt(&self, other: &LevelFilter) -> bool {
+        *self as usize > *other as usize
+    }
+
+    #[inline]
+    fn ge(&self, other: &LevelFilter) -> bool {
+        *self as usize >= *other as usize
+    }
+}
+
+impl PartialOrd<Level> for LevelFilter {
+    #[inline]
+    fn partial_cmp(&self, other: &Level) -> Option<cmp::Ordering> {
+        Some((*self as usize).cmp(&(*other as usize)))
+    }
+
+    #[inline]
+    fn lt(&self, other: &Level) -> bool {
+        (*self as usize) < *other as usize
+    }
+
+    #[inline]
+    fn le(&self, other: &Level) -> bool {
+        *self as usize <= *other as usize
+    }
+
+    #[inline]
+    fn gt(&self, other: &Level) -> bool {
+        *self as usize > *other as usize
+    }
+
+    #[inline]
+    fn ge(&self, other: &Level) -> bool {
+        *self as usize >= *other as usize
+    }
+}
+
+impl Ord for LevelFilter {
+    #[inline]
+    fn cmp(&self, other: &LevelFilter) -> cmp::Ordering {
+        (*self as usize).cmp(&(*other as usize))
+    }
+}
+
+impl FromStr for LevelFilter {
+    type Err = ParseLevelError;
+    fn from_str(level: &str) -> Result<LevelFilter, Self::Err> {
+        ok_or(
+            LOG_LEVEL_NAMES
+                .iter()
+                .position(|&name| eq_ignore_ascii_case(name, level))
+                .map(|p| LevelFilter::from_usize(p).unwrap()),
+            ParseLevelError(()),
+        )
+    }
+}
+
+impl fmt::Display for LevelFilter {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.pad(LOG_LEVEL_NAMES[*self as usize])
+    }
+}
+
+impl LevelFilter {
+    fn from_usize(u: usize) -> Option<LevelFilter> {
+        match u {
+            0 => Some(LevelFilter::Off),
+            1 => Some(LevelFilter::Error),
+            2 => Some(LevelFilter::Warn),
+            3 => Some(LevelFilter::Info),
+            4 => Some(LevelFilter::Debug),
+            5 => Some(LevelFilter::Trace),
+            _ => None,
+        }
+    }
+    /// Returns the most verbose logging level filter.
+    #[inline]
+    pub fn max() -> LevelFilter {
+        LevelFilter::Trace
+    }
+
+    /// Converts `self` to the equivalent `Level`.
+    ///
+    /// Returns `None` if `self` is `LevelFilter::Off`.
+    #[inline]
+    pub fn to_level(&self) -> Option<Level> {
+        Level::from_usize(*self as usize)
+    }
+}
+
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
+enum MaybeStaticStr<'a> {
+    Static(&'static str),
+    Borrowed(&'a str),
+}
+
+impl<'a> MaybeStaticStr<'a> {
+    #[inline]
+    fn get(&self) -> &'a str {
+        match *self {
+            MaybeStaticStr::Static(s) => s,
+            MaybeStaticStr::Borrowed(s) => s,
+        }
+    }
+}
+
+/// The "payload" of a log message.
+///
+/// # Use
+///
+/// `Record` structures are passed as parameters to the [`log`][method.log]
+/// method of the [`Log`] trait. Logger implementors manipulate these
+/// structures in order to display log messages. `Record`s are automatically
+/// created by the [`log!`] macro and so are not seen by log users.
+///
+/// Note that the [`level()`] and [`target()`] accessors are equivalent to
+/// `self.metadata().level()` and `self.metadata().target()` respectively.
+/// These methods are provided as a convenience for users of this structure.
+///
+/// # Example
+///
+/// The following example shows a simple logger that displays the level,
+/// module path, and message of any `Record` that is passed to it.
+///
+/// ```edition2018
+/// struct SimpleLogger;
+///
+/// impl log::Log for SimpleLogger {
+///    fn enabled(&self, metadata: &log::Metadata) -> bool {
+///        true
+///    }
+///
+///    fn log(&self, record: &log::Record) {
+///        if !self.enabled(record.metadata()) {
+///            return;
+///        }
+///
+///        println!("{}:{} -- {}",
+///                 record.level(),
+///                 record.target(),
+///                 record.args());
+///    }
+///    fn flush(&self) {}
+/// }
+/// ```
+///
+/// [method.log]: trait.Log.html#tymethod.log
+/// [`Log`]: trait.Log.html
+/// [`log!`]: macro.log.html
+/// [`level()`]: struct.Record.html#method.level
+/// [`target()`]: struct.Record.html#method.target
+#[derive(Clone, Debug)]
+pub struct Record<'a> {
+    metadata: Metadata<'a>,
+    args: fmt::Arguments<'a>,
+    module_path: Option<MaybeStaticStr<'a>>,
+    file: Option<MaybeStaticStr<'a>>,
+    line: Option<u32>,
+    #[cfg(feature = "kv_unstable")]
+    key_values: KeyValues<'a>,
+}
+
+// This wrapper type is only needed so we can
+// `#[derive(Debug)]` on `Record`. It also
+// provides a useful `Debug` implementation for
+// the underlying `Source`.
+#[cfg(feature = "kv_unstable")]
+#[derive(Clone)]
+struct KeyValues<'a>(&'a dyn kv::Source);
+
+#[cfg(feature = "kv_unstable")]
+impl<'a> fmt::Debug for KeyValues<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut visitor = f.debug_map();
+        self.0.visit(&mut visitor).map_err(|_| fmt::Error)?;
+        visitor.finish()
+    }
+}
+
+impl<'a> Record<'a> {
+    /// Returns a new builder.
+    #[inline]
+    pub fn builder() -> RecordBuilder<'a> {
+        RecordBuilder::new()
+    }
+
+    /// The message body.
+    #[inline]
+    pub fn args(&self) -> &fmt::Arguments<'a> {
+        &self.args
+    }
+
+    /// Metadata about the log directive.
+    #[inline]
+    pub fn metadata(&self) -> &Metadata<'a> {
+        &self.metadata
+    }
+
+    /// The verbosity level of the message.
+    #[inline]
+    pub fn level(&self) -> Level {
+        self.metadata.level()
+    }
+
+    /// The name of the target of the directive.
+    #[inline]
+    pub fn target(&self) -> &'a str {
+        self.metadata.target()
+    }
+
+    /// The module path of the message.
+    #[inline]
+    pub fn module_path(&self) -> Option<&'a str> {
+        self.module_path.map(|s| s.get())
+    }
+
+    /// The module path of the message, if it is a `'static` string.
+    #[inline]
+    pub fn module_path_static(&self) -> Option<&'static str> {
+        match self.module_path {
+            Some(MaybeStaticStr::Static(s)) => Some(s),
+            _ => None,
+        }
+    }
+
+    /// The source file containing the message.
+    #[inline]
+    pub fn file(&self) -> Option<&'a str> {
+        self.file.map(|s| s.get())
+    }
+
+    /// The module path of the message, if it is a `'static` string.
+    #[inline]
+    pub fn file_static(&self) -> Option<&'static str> {
+        match self.file {
+            Some(MaybeStaticStr::Static(s)) => Some(s),
+            _ => None,
+        }
+    }
+
+    /// The line containing the message.
+    #[inline]
+    pub fn line(&self) -> Option<u32> {
+        self.line
+    }
+
+    /// The structued key-value pairs associated with the message.
+    #[cfg(feature = "kv_unstable")]
+    #[inline]
+    pub fn key_values(&self) -> &dyn kv::Source {
+        self.key_values.0
+    }
+
+    /// Create a new [`RecordBuilder`](struct.RecordBuilder.html) based on this record.
+    #[cfg(feature = "kv_unstable")]
+    #[inline]
+    pub fn to_builder(&self) -> RecordBuilder {
+        RecordBuilder {
+            record: Record {
+                metadata: Metadata {
+                    level: self.metadata.level,
+                    target: self.metadata.target,
+                },
+                args: self.args,
+                module_path: self.module_path,
+                file: self.file,
+                line: self.line,
+                key_values: self.key_values.clone(),
+            },
+        }
+    }
+}
+
+/// Builder for [`Record`](struct.Record.html).
+///
+/// Typically should only be used by log library creators or for testing and "shim loggers".
+/// The `RecordBuilder` can set the different parameters of `Record` object, and returns
+/// the created object when `build` is called.
+///
+/// # Examples
+///
+///
+/// ```edition2018
+/// use log::{Level, Record};
+///
+/// let record = Record::builder()
+///                 .args(format_args!("Error!"))
+///                 .level(Level::Error)
+///                 .target("myApp")
+///                 .file(Some("server.rs"))
+///                 .line(Some(144))
+///                 .module_path(Some("server"))
+///                 .build();
+/// ```
+///
+/// Alternatively, use [`MetadataBuilder`](struct.MetadataBuilder.html):
+///
+/// ```edition2018
+/// use log::{Record, Level, MetadataBuilder};
+///
+/// let error_metadata = MetadataBuilder::new()
+///                         .target("myApp")
+///                         .level(Level::Error)
+///                         .build();
+///
+/// let record = Record::builder()
+///                 .metadata(error_metadata)
+///                 .args(format_args!("Error!"))
+///                 .line(Some(433))
+///                 .file(Some("app.rs"))
+///                 .module_path(Some("server"))
+///                 .build();
+/// ```
+#[derive(Debug)]
+pub struct RecordBuilder<'a> {
+    record: Record<'a>,
+}
+
+impl<'a> RecordBuilder<'a> {
+    /// Construct new `RecordBuilder`.
+    ///
+    /// The default options are:
+    ///
+    /// - `args`: [`format_args!("")`]
+    /// - `metadata`: [`Metadata::builder().build()`]
+    /// - `module_path`: `None`
+    /// - `file`: `None`
+    /// - `line`: `None`
+    ///
+    /// [`format_args!("")`]: https://doc.rust-lang.org/std/macro.format_args.html
+    /// [`Metadata::builder().build()`]: struct.MetadataBuilder.html#method.build
+    #[inline]
+    pub fn new() -> RecordBuilder<'a> {
+        RecordBuilder {
+            record: Record {
+                args: format_args!(""),
+                metadata: Metadata::builder().build(),
+                module_path: None,
+                file: None,
+                line: None,
+                #[cfg(feature = "kv_unstable")]
+                key_values: KeyValues(&Option::None::<(kv::Key, kv::Value)>),
+            },
+        }
+    }
+
+    /// Set [`args`](struct.Record.html#method.args).
+    #[inline]
+    pub fn args(&mut self, args: fmt::Arguments<'a>) -> &mut RecordBuilder<'a> {
+        self.record.args = args;
+        self
+    }
+
+    /// Set [`metadata`](struct.Record.html#method.metadata). Construct a `Metadata` object with [`MetadataBuilder`](struct.MetadataBuilder.html).
+    #[inline]
+    pub fn metadata(&mut self, metadata: Metadata<'a>) -> &mut RecordBuilder<'a> {
+        self.record.metadata = metadata;
+        self
+    }
+
+    /// Set [`Metadata::level`](struct.Metadata.html#method.level).
+    #[inline]
+    pub fn level(&mut self, level: Level) -> &mut RecordBuilder<'a> {
+        self.record.metadata.level = level;
+        self
+    }
+
+    /// Set [`Metadata::target`](struct.Metadata.html#method.target)
+    #[inline]
+    pub fn target(&mut self, target: &'a str) -> &mut RecordBuilder<'a> {
+        self.record.metadata.target = target;
+        self
+    }
+
+    /// Set [`module_path`](struct.Record.html#method.module_path)
+    #[inline]
+    pub fn module_path(&mut self, path: Option<&'a str>) -> &mut RecordBuilder<'a> {
+        self.record.module_path = path.map(MaybeStaticStr::Borrowed);
+        self
+    }
+
+    /// Set [`module_path`](struct.Record.html#method.module_path) to a `'static` string
+    #[inline]
+    pub fn module_path_static(&mut self, path: Option<&'static str>) -> &mut RecordBuilder<'a> {
+        self.record.module_path = path.map(MaybeStaticStr::Static);
+        self
+    }
+
+    /// Set [`file`](struct.Record.html#method.file)
+    #[inline]
+    pub fn file(&mut self, file: Option<&'a str>) -> &mut RecordBuilder<'a> {
+        self.record.file = file.map(MaybeStaticStr::Borrowed);
+        self
+    }
+
+    /// Set [`file`](struct.Record.html#method.file) to a `'static` string.
+    #[inline]
+    pub fn file_static(&mut self, file: Option<&'static str>) -> &mut RecordBuilder<'a> {
+        self.record.file = file.map(MaybeStaticStr::Static);
+        self
+    }
+
+    /// Set [`line`](struct.Record.html#method.line)
+    #[inline]
+    pub fn line(&mut self, line: Option<u32>) -> &mut RecordBuilder<'a> {
+        self.record.line = line;
+        self
+    }
+
+    /// Set [`key_values`](struct.Record.html#method.key_values)
+    #[cfg(feature = "kv_unstable")]
+    #[inline]
+    pub fn key_values(&mut self, kvs: &'a dyn kv::Source) -> &mut RecordBuilder<'a> {
+        self.record.key_values = KeyValues(kvs);
+        self
+    }
+
+    /// Invoke the builder and return a `Record`
+    #[inline]
+    pub fn build(&self) -> Record<'a> {
+        self.record.clone()
+    }
+}
+
+/// Metadata about a log message.
+///
+/// # Use
+///
+/// `Metadata` structs are created when users of the library use
+/// logging macros.
+///
+/// They are consumed by implementations of the `Log` trait in the
+/// `enabled` method.
+///
+/// `Record`s use `Metadata` to determine the log message's severity
+/// and target.
+///
+/// Users should use the `log_enabled!` macro in their code to avoid
+/// constructing expensive log messages.
+///
+/// # Examples
+///
+/// ```edition2018
+/// use log::{Record, Level, Metadata};
+///
+/// struct MyLogger;
+///
+/// impl log::Log for MyLogger {
+///     fn enabled(&self, metadata: &Metadata) -> bool {
+///         metadata.level() <= Level::Info
+///     }
+///
+///     fn log(&self, record: &Record) {
+///         if self.enabled(record.metadata()) {
+///             println!("{} - {}", record.level(), record.args());
+///         }
+///     }
+///     fn flush(&self) {}
+/// }
+///
+/// # fn main(){}
+/// ```
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
+pub struct Metadata<'a> {
+    level: Level,
+    target: &'a str,
+}
+
+impl<'a> Metadata<'a> {
+    /// Returns a new builder.
+    #[inline]
+    pub fn builder() -> MetadataBuilder<'a> {
+        MetadataBuilder::new()
+    }
+
+    /// The verbosity level of the message.
+    #[inline]
+    pub fn level(&self) -> Level {
+        self.level
+    }
+
+    /// The name of the target of the directive.
+    #[inline]
+    pub fn target(&self) -> &'a str {
+        self.target
+    }
+}
+
+/// Builder for [`Metadata`](struct.Metadata.html).
+///
+/// Typically should only be used by log library creators or for testing and "shim loggers".
+/// The `MetadataBuilder` can set the different parameters of a `Metadata` object, and returns
+/// the created object when `build` is called.
+///
+/// # Example
+///
+/// ```edition2018
+/// let target = "myApp";
+/// use log::{Level, MetadataBuilder};
+/// let metadata = MetadataBuilder::new()
+///                     .level(Level::Debug)
+///                     .target(target)
+///                     .build();
+/// ```
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
+pub struct MetadataBuilder<'a> {
+    metadata: Metadata<'a>,
+}
+
+impl<'a> MetadataBuilder<'a> {
+    /// Construct a new `MetadataBuilder`.
+    ///
+    /// The default options are:
+    ///
+    /// - `level`: `Level::Info`
+    /// - `target`: `""`
+    #[inline]
+    pub fn new() -> MetadataBuilder<'a> {
+        MetadataBuilder {
+            metadata: Metadata {
+                level: Level::Info,
+                target: "",
+            },
+        }
+    }
+
+    /// Setter for [`level`](struct.Metadata.html#method.level).
+    #[inline]
+    pub fn level(&mut self, arg: Level) -> &mut MetadataBuilder<'a> {
+        self.metadata.level = arg;
+        self
+    }
+
+    /// Setter for [`target`](struct.Metadata.html#method.target).
+    #[inline]
+    pub fn target(&mut self, target: &'a str) -> &mut MetadataBuilder<'a> {
+        self.metadata.target = target;
+        self
+    }
+
+    /// Returns a `Metadata` object.
+    #[inline]
+    pub fn build(&self) -> Metadata<'a> {
+        self.metadata.clone()
+    }
+}
+
+/// A trait encapsulating the operations required of a logger.
+pub trait Log: Sync + Send {
+    /// Determines if a log message with the specified metadata would be
+    /// logged.
+    ///
+    /// This is used by the `log_enabled!` macro to allow callers to avoid
+    /// expensive computation of log message arguments if the message would be
+    /// discarded anyway.
+    fn enabled(&self, metadata: &Metadata) -> bool;
+
+    /// Logs the `Record`.
+    ///
+    /// Note that `enabled` is *not* necessarily called before this method.
+    /// Implementations of `log` should perform all necessary filtering
+    /// internally.
+    fn log(&self, record: &Record);
+
+    /// Flushes any buffered records.
+    fn flush(&self);
+}
+
+// Just used as a dummy initial value for LOGGER
+struct NopLogger;
+
+impl Log for NopLogger {
+    fn enabled(&self, _: &Metadata) -> bool {
+        false
+    }
+
+    fn log(&self, _: &Record) {}
+    fn flush(&self) {}
+}
+
+/// Sets the global maximum log level.
+///
+/// Generally, this should only be called by the active logging implementation.
+#[inline]
+pub fn set_max_level(level: LevelFilter) {
+    MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::SeqCst)
+}
+
+/// Returns the current maximum log level.
+///
+/// The [`log!`], [`error!`], [`warn!`], [`info!`], [`debug!`], and [`trace!`] macros check
+/// this value and discard any message logged at a higher level. The maximum
+/// log level is set by the [`set_max_level`] function.
+///
+/// [`log!`]: macro.log.html
+/// [`error!`]: macro.error.html
+/// [`warn!`]: macro.warn.html
+/// [`info!`]: macro.info.html
+/// [`debug!`]: macro.debug.html
+/// [`trace!`]: macro.trace.html
+/// [`set_max_level`]: fn.set_max_level.html
+#[inline(always)]
+pub fn max_level() -> LevelFilter {
+    // Since `LevelFilter` is `repr(usize)`,
+    // this transmute is sound if and only if `MAX_LOG_LEVEL_FILTER`
+    // is set to a usize that is a valid discriminant for `LevelFilter`.
+    // Since `MAX_LOG_LEVEL_FILTER` is private, the only time it's set
+    // is by `set_max_level` above, i.e. by casting a `LevelFilter` to `usize`.
+    // So any usize stored in `MAX_LOG_LEVEL_FILTER` is a valid discriminant.
+    unsafe { mem::transmute(MAX_LOG_LEVEL_FILTER.load(Ordering::Relaxed)) }
+}
+
+/// Sets the global logger to a `Box<Log>`.
+///
+/// This is a simple convenience wrapper over `set_logger`, which takes a
+/// `Box<Log>` rather than a `&'static Log`. See the documentation for
+/// [`set_logger`] for more details.
+///
+/// Requires the `std` feature.
+///
+/// # Errors
+///
+/// An error is returned if a logger has already been set.
+///
+/// [`set_logger`]: fn.set_logger.html
+#[cfg(all(feature = "std", atomic_cas))]
+pub fn set_boxed_logger(logger: Box<dyn Log>) -> Result<(), SetLoggerError> {
+    set_logger_inner(|| Box::leak(logger))
+}
+
+/// Sets the global logger to a `&'static Log`.
+///
+/// This function may only be called once in the lifetime of a program. Any log
+/// events that occur before the call to `set_logger` completes will be ignored.
+///
+/// This function does not typically need to be called manually. Logger
+/// implementations should provide an initialization method that installs the
+/// logger internally.
+///
+/// # Availability
+///
+/// This method is available even when the `std` feature is disabled. However,
+/// it is currently unavailable on `thumbv6` targets, which lack support for
+/// some atomic operations which are used by this function. Even on those
+/// targets, [`set_logger_racy`] will be available.
+///
+/// # Errors
+///
+/// An error is returned if a logger has already been set.
+///
+/// # Examples
+///
+/// ```edition2018
+/// use log::{error, info, warn, Record, Level, Metadata, LevelFilter};
+///
+/// static MY_LOGGER: MyLogger = MyLogger;
+///
+/// struct MyLogger;
+///
+/// impl log::Log for MyLogger {
+///     fn enabled(&self, metadata: &Metadata) -> bool {
+///         metadata.level() <= Level::Info
+///     }
+///
+///     fn log(&self, record: &Record) {
+///         if self.enabled(record.metadata()) {
+///             println!("{} - {}", record.level(), record.args());
+///         }
+///     }
+///     fn flush(&self) {}
+/// }
+///
+/// # fn main(){
+/// log::set_logger(&MY_LOGGER).unwrap();
+/// log::set_max_level(LevelFilter::Info);
+///
+/// info!("hello log");
+/// warn!("warning");
+/// error!("oops");
+/// # }
+/// ```
+///
+/// [`set_logger_racy`]: fn.set_logger_racy.html
+#[cfg(atomic_cas)]
+pub fn set_logger(logger: &'static dyn Log) -> Result<(), SetLoggerError> {
+    set_logger_inner(|| logger)
+}
+
+#[cfg(atomic_cas)]
+fn set_logger_inner<F>(make_logger: F) -> Result<(), SetLoggerError>
+where
+    F: FnOnce() -> &'static dyn Log,
+{
+    match STATE.compare_and_swap(UNINITIALIZED, INITIALIZING, Ordering::SeqCst) {
+        UNINITIALIZED => {
+            unsafe {
+                LOGGER = make_logger();
+            }
+            STATE.store(INITIALIZED, Ordering::SeqCst);
+            Ok(())
+        }
+        INITIALIZING => {
+            while STATE.load(Ordering::SeqCst) == INITIALIZING {
+                std::sync::atomic::spin_loop_hint();
+            }
+            Err(SetLoggerError(()))
+        }
+        _ => Err(SetLoggerError(())),
+    }
+}
+
+/// A thread-unsafe version of [`set_logger`].
+///
+/// This function is available on all platforms, even those that do not have
+/// support for atomics that is needed by [`set_logger`].
+///
+/// In almost all cases, [`set_logger`] should be preferred.
+///
+/// # Safety
+///
+/// This function is only safe to call when no other logger initialization
+/// function is called while this function still executes.
+///
+/// This can be upheld by (for example) making sure that **there are no other
+/// threads**, and (on embedded) that **interrupts are disabled**.
+///
+/// It is safe to use other logging functions while this function runs
+/// (including all logging macros).
+///
+/// [`set_logger`]: fn.set_logger.html
+pub unsafe fn set_logger_racy(logger: &'static dyn Log) -> Result<(), SetLoggerError> {
+    match STATE.load(Ordering::SeqCst) {
+        UNINITIALIZED => {
+            LOGGER = logger;
+            STATE.store(INITIALIZED, Ordering::SeqCst);
+            Ok(())
+        }
+        INITIALIZING => {
+            // This is just plain UB, since we were racing another initialization function
+            unreachable!("set_logger_racy must not be used with other initialization functions")
+        }
+        _ => Err(SetLoggerError(())),
+    }
+}
+
+/// The type returned by [`set_logger`] if [`set_logger`] has already been called.
+///
+/// [`set_logger`]: fn.set_logger.html
+#[allow(missing_copy_implementations)]
+#[derive(Debug)]
+pub struct SetLoggerError(());
+
+impl fmt::Display for SetLoggerError {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.write_str(SET_LOGGER_ERROR)
+    }
+}
+
+// The Error trait is not available in libcore
+#[cfg(feature = "std")]
+impl error::Error for SetLoggerError {}
+
+/// The type returned by [`from_str`] when the string doesn't match any of the log levels.
+///
+/// [`from_str`]: https://doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str
+#[allow(missing_copy_implementations)]
+#[derive(Debug, PartialEq)]
+pub struct ParseLevelError(());
+
+impl fmt::Display for ParseLevelError {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.write_str(LEVEL_PARSE_ERROR)
+    }
+}
+
+// The Error trait is not available in libcore
+#[cfg(feature = "std")]
+impl error::Error for ParseLevelError {}
+
+/// Returns a reference to the logger.
+///
+/// If a logger has not been set, a no-op implementation is returned.
+pub fn logger() -> &'static dyn Log {
+    if STATE.load(Ordering::SeqCst) != INITIALIZED {
+        static NOP: NopLogger = NopLogger;
+        &NOP
+    } else {
+        unsafe { LOGGER }
+    }
+}
+
+// WARNING: this is not part of the crate's public API and is subject to change at any time
+#[doc(hidden)]
+pub fn __private_api_log(
+    args: fmt::Arguments,
+    level: Level,
+    &(target, module_path, file, line): &(&str, &'static str, &'static str, u32),
+) {
+    logger().log(
+        &Record::builder()
+            .args(args)
+            .level(level)
+            .target(target)
+            .module_path_static(Some(module_path))
+            .file_static(Some(file))
+            .line(Some(line))
+            .build(),
+    );
+}
+
+// WARNING: this is not part of the crate's public API and is subject to change at any time
+#[doc(hidden)]
+pub fn __private_api_log_lit(
+    message: &str,
+    level: Level,
+    &(target, module_path, file, line): &(&str, &'static str, &'static str, u32),
+) {
+    logger().log(
+        &Record::builder()
+            .args(format_args!("{}", message))
+            .level(level)
+            .target(target)
+            .module_path_static(Some(module_path))
+            .file_static(Some(file))
+            .line(Some(line))
+            .build(),
+    );
+}
+
+// WARNING: this is not part of the crate's public API and is subject to change at any time
+#[doc(hidden)]
+pub fn __private_api_enabled(level: Level, target: &str) -> bool {
+    logger().enabled(&Metadata::builder().level(level).target(target).build())
+}
+
+/// The statically resolved maximum log level.
+///
+/// See the crate level documentation for information on how to configure this.
+///
+/// This value is checked by the log macros, but not by the `Log`ger returned by
+/// the [`logger`] function. Code that manually calls functions on that value
+/// should compare the level against this value.
+///
+/// [`logger`]: fn.logger.html
+pub const STATIC_MAX_LEVEL: LevelFilter = MAX_LEVEL_INNER;
+
+cfg_if! {
+    if #[cfg(all(not(debug_assertions), feature = "release_max_level_off"))] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Off;
+    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_error"))] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Error;
+    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_warn"))] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Warn;
+    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_info"))] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Info;
+    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_debug"))] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Debug;
+    } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_trace"))] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Trace;
+    } else if #[cfg(feature = "max_level_off")] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Off;
+    } else if #[cfg(feature = "max_level_error")] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Error;
+    } else if #[cfg(feature = "max_level_warn")] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Warn;
+    } else if #[cfg(feature = "max_level_info")] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Info;
+    } else if #[cfg(feature = "max_level_debug")] {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Debug;
+    } else {
+        const MAX_LEVEL_INNER: LevelFilter = LevelFilter::Trace;
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    extern crate std;
+    use super::{Level, LevelFilter, ParseLevelError};
+    use tests::std::string::ToString;
+
+    #[test]
+    fn test_levelfilter_from_str() {
+        let tests = [
+            ("off", Ok(LevelFilter::Off)),
+            ("error", Ok(LevelFilter::Error)),
+            ("warn", Ok(LevelFilter::Warn)),
+            ("info", Ok(LevelFilter::Info)),
+            ("debug", Ok(LevelFilter::Debug)),
+            ("trace", Ok(LevelFilter::Trace)),
+            ("OFF", Ok(LevelFilter::Off)),
+            ("ERROR", Ok(LevelFilter::Error)),
+            ("WARN", Ok(LevelFilter::Warn)),
+            ("INFO", Ok(LevelFilter::Info)),
+            ("DEBUG", Ok(LevelFilter::Debug)),
+            ("TRACE", Ok(LevelFilter::Trace)),
+            ("asdf", Err(ParseLevelError(()))),
+        ];
+        for &(s, ref expected) in &tests {
+            assert_eq!(expected, &s.parse());
+        }
+    }
+
+    #[test]
+    fn test_level_from_str() {
+        let tests = [
+            ("OFF", Err(ParseLevelError(()))),
+            ("error", Ok(Level::Error)),
+            ("warn", Ok(Level::Warn)),
+            ("info", Ok(Level::Info)),
+            ("debug", Ok(Level::Debug)),
+            ("trace", Ok(Level::Trace)),
+            ("ERROR", Ok(Level::Error)),
+            ("WARN", Ok(Level::Warn)),
+            ("INFO", Ok(Level::Info)),
+            ("DEBUG", Ok(Level::Debug)),
+            ("TRACE", Ok(Level::Trace)),
+            ("asdf", Err(ParseLevelError(()))),
+        ];
+        for &(s, ref expected) in &tests {
+            assert_eq!(expected, &s.parse());
+        }
+    }
+
+    #[test]
+    fn test_level_show() {
+        assert_eq!("INFO", Level::Info.to_string());
+        assert_eq!("ERROR", Level::Error.to_string());
+    }
+
+    #[test]
+    fn test_levelfilter_show() {
+        assert_eq!("OFF", LevelFilter::Off.to_string());
+        assert_eq!("ERROR", LevelFilter::Error.to_string());
+    }
+
+    #[test]
+    fn test_cross_cmp() {
+        assert!(Level::Debug > LevelFilter::Error);
+        assert!(LevelFilter::Warn < Level::Trace);
+        assert!(LevelFilter::Off < Level::Error);
+    }
+
+    #[test]
+    fn test_cross_eq() {
+        assert!(Level::Error == LevelFilter::Error);
+        assert!(LevelFilter::Off != Level::Error);
+        assert!(Level::Trace == LevelFilter::Trace);
+    }
+
+    #[test]
+    fn test_to_level() {
+        assert_eq!(Some(Level::Error), LevelFilter::Error.to_level());
+        assert_eq!(None, LevelFilter::Off.to_level());
+        assert_eq!(Some(Level::Debug), LevelFilter::Debug.to_level());
+    }
+
+    #[test]
+    fn test_to_level_filter() {
+        assert_eq!(LevelFilter::Error, Level::Error.to_level_filter());
+        assert_eq!(LevelFilter::Trace, Level::Trace.to_level_filter());
+    }
+
+    #[test]
+    #[cfg(feature = "std")]
+    fn test_error_trait() {
+        use super::SetLoggerError;
+        let e = SetLoggerError(());
+        assert_eq!(
+            &e.to_string(),
+            "attempted to set a logger after the logging system \
+             was already initialized"
+        );
+    }
+
+    #[test]
+    fn test_metadata_builder() {
+        use super::MetadataBuilder;
+        let target = "myApp";
+        let metadata_test = MetadataBuilder::new()
+            .level(Level::Debug)
+            .target(target)
+            .build();
+        assert_eq!(metadata_test.level(), Level::Debug);
+        assert_eq!(metadata_test.target(), "myApp");
+    }
+
+    #[test]
+    fn test_metadata_convenience_builder() {
+        use super::Metadata;
+        let target = "myApp";
+        let metadata_test = Metadata::builder()
+            .level(Level::Debug)
+            .target(target)
+            .build();
+        assert_eq!(metadata_test.level(), Level::Debug);
+        assert_eq!(metadata_test.target(), "myApp");
+    }
+
+    #[test]
+    fn test_record_builder() {
+        use super::{MetadataBuilder, RecordBuilder};
+        let target = "myApp";
+        let metadata = MetadataBuilder::new().target(target).build();
+        let fmt_args = format_args!("hello");
+        let record_test = RecordBuilder::new()
+            .args(fmt_args)
+            .metadata(metadata)
+            .module_path(Some("foo"))
+            .file(Some("bar"))
+            .line(Some(30))
+            .build();
+        assert_eq!(record_test.metadata().target(), "myApp");
+        assert_eq!(record_test.module_path(), Some("foo"));
+        assert_eq!(record_test.file(), Some("bar"));
+        assert_eq!(record_test.line(), Some(30));
+    }
+
+    #[test]
+    fn test_record_convenience_builder() {
+        use super::{Metadata, Record};
+        let target = "myApp";
+        let metadata = Metadata::builder().target(target).build();
+        let fmt_args = format_args!("hello");
+        let record_test = Record::builder()
+            .args(fmt_args)
+            .metadata(metadata)
+            .module_path(Some("foo"))
+            .file(Some("bar"))
+            .line(Some(30))
+            .build();
+        assert_eq!(record_test.target(), "myApp");
+        assert_eq!(record_test.module_path(), Some("foo"));
+        assert_eq!(record_test.file(), Some("bar"));
+        assert_eq!(record_test.line(), Some(30));
+    }
+
+    #[test]
+    fn test_record_complete_builder() {
+        use super::{Level, Record};
+        let target = "myApp";
+        let record_test = Record::builder()
+            .module_path(Some("foo"))
+            .file(Some("bar"))
+            .line(Some(30))
+            .target(target)
+            .level(Level::Error)
+            .build();
+        assert_eq!(record_test.target(), "myApp");
+        assert_eq!(record_test.level(), Level::Error);
+        assert_eq!(record_test.module_path(), Some("foo"));
+        assert_eq!(record_test.file(), Some("bar"));
+        assert_eq!(record_test.line(), Some(30));
+    }
+
+    #[test]
+    #[cfg(feature = "kv_unstable")]
+    fn test_record_key_values_builder() {
+        use super::Record;
+        use kv::{self, Visitor};
+
+        struct TestVisitor {
+            seen_pairs: usize,
+        }
+
+        impl<'kvs> Visitor<'kvs> for TestVisitor {
+            fn visit_pair(
+                &mut self,
+                _: kv::Key<'kvs>,
+                _: kv::Value<'kvs>,
+            ) -> Result<(), kv::Error> {
+                self.seen_pairs += 1;
+                Ok(())
+            }
+        }
+
+        let kvs: &[(&str, i32)] = &[("a", 1), ("b", 2)];
+        let record_test = Record::builder().key_values(&kvs).build();
+
+        let mut visitor = TestVisitor { seen_pairs: 0 };
+
+        record_test.key_values().visit(&mut visitor).unwrap();
+
+        assert_eq!(2, visitor.seen_pairs);
+    }
+
+    #[test]
+    #[cfg(feature = "kv_unstable")]
+    fn test_record_key_values_get_coerce() {
+        use super::Record;
+
+        let kvs: &[(&str, &str)] = &[("a", "1"), ("b", "2")];
+        let record = Record::builder().key_values(&kvs).build();
+
+        assert_eq!(
+            "2",
+            record
+                .key_values()
+                .get("b".into())
+                .expect("missing key")
+                .to_borrowed_str()
+                .expect("invalid value")
+        );
+    }
+}
