12d8ae3abSopenharmony_ci// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
22d8ae3abSopenharmony_ci// file at the top-level directory of this distribution and at
32d8ae3abSopenharmony_ci// http://rust-lang.org/COPYRIGHT.
42d8ae3abSopenharmony_ci//
52d8ae3abSopenharmony_ci// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
62d8ae3abSopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
72d8ae3abSopenharmony_ci// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
82d8ae3abSopenharmony_ci// option. This file may not be copied, modified, or distributed
92d8ae3abSopenharmony_ci// except according to those terms.
102d8ae3abSopenharmony_ci
112d8ae3abSopenharmony_ci/// The standard logging macro.
122d8ae3abSopenharmony_ci///
132d8ae3abSopenharmony_ci/// This macro will generically log with the specified `Level` and `format!`
142d8ae3abSopenharmony_ci/// based argument list.
152d8ae3abSopenharmony_ci///
162d8ae3abSopenharmony_ci/// # Examples
172d8ae3abSopenharmony_ci///
182d8ae3abSopenharmony_ci/// ```edition2018
192d8ae3abSopenharmony_ci/// use log::{log, Level};
202d8ae3abSopenharmony_ci///
212d8ae3abSopenharmony_ci/// # fn main() {
222d8ae3abSopenharmony_ci/// let data = (42, "Forty-two");
232d8ae3abSopenharmony_ci/// let private_data = "private";
242d8ae3abSopenharmony_ci///
252d8ae3abSopenharmony_ci/// log!(Level::Error, "Received errors: {}, {}", data.0, data.1);
262d8ae3abSopenharmony_ci/// log!(target: "app_events", Level::Warn, "App warning: {}, {}, {}",
272d8ae3abSopenharmony_ci///     data.0, data.1, private_data);
282d8ae3abSopenharmony_ci/// # }
292d8ae3abSopenharmony_ci/// ```
302d8ae3abSopenharmony_ci#[macro_export(local_inner_macros)]
312d8ae3abSopenharmony_cimacro_rules! log {
322d8ae3abSopenharmony_ci    // log!(target: "my_target", Level::Info; key1 = 42, key2 = true; "a {} event", "log");
332d8ae3abSopenharmony_ci    (target: $target:expr, $lvl:expr, $($key:tt = $value:expr),+; $($arg:tt)+) => ({
342d8ae3abSopenharmony_ci        let lvl = $lvl;
352d8ae3abSopenharmony_ci        if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() {
362d8ae3abSopenharmony_ci            $crate::__private_api_log(
372d8ae3abSopenharmony_ci                __log_format_args!($($arg)+),
382d8ae3abSopenharmony_ci                lvl,
392d8ae3abSopenharmony_ci                &($target, __log_module_path!(), __log_file!(), __log_line!()),
402d8ae3abSopenharmony_ci                $crate::__private_api::Option::Some(&[$((__log_key!($key), &$value)),+])
412d8ae3abSopenharmony_ci            );
422d8ae3abSopenharmony_ci        }
432d8ae3abSopenharmony_ci    });
442d8ae3abSopenharmony_ci
452d8ae3abSopenharmony_ci    // log!(target: "my_target", Level::Info; "a {} event", "log");
462d8ae3abSopenharmony_ci    (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({
472d8ae3abSopenharmony_ci        let lvl = $lvl;
482d8ae3abSopenharmony_ci        if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() {
492d8ae3abSopenharmony_ci            $crate::__private_api_log(
502d8ae3abSopenharmony_ci                __log_format_args!($($arg)+),
512d8ae3abSopenharmony_ci                lvl,
522d8ae3abSopenharmony_ci                &($target, __log_module_path!(), __log_file!(), __log_line!()),
532d8ae3abSopenharmony_ci                $crate::__private_api::Option::None,
542d8ae3abSopenharmony_ci            );
552d8ae3abSopenharmony_ci        }
562d8ae3abSopenharmony_ci    });
572d8ae3abSopenharmony_ci
582d8ae3abSopenharmony_ci    // log!(Level::Info, "a log event")
592d8ae3abSopenharmony_ci    ($lvl:expr, $($arg:tt)+) => (log!(target: __log_module_path!(), $lvl, $($arg)+));
602d8ae3abSopenharmony_ci}
612d8ae3abSopenharmony_ci
622d8ae3abSopenharmony_ci/// Logs a message at the error level.
632d8ae3abSopenharmony_ci///
642d8ae3abSopenharmony_ci/// # Examples
652d8ae3abSopenharmony_ci///
662d8ae3abSopenharmony_ci/// ```edition2018
672d8ae3abSopenharmony_ci/// use log::error;
682d8ae3abSopenharmony_ci///
692d8ae3abSopenharmony_ci/// # fn main() {
702d8ae3abSopenharmony_ci/// let (err_info, port) = ("No connection", 22);
712d8ae3abSopenharmony_ci///
722d8ae3abSopenharmony_ci/// error!("Error: {} on port {}", err_info, port);
732d8ae3abSopenharmony_ci/// error!(target: "app_events", "App Error: {}, Port: {}", err_info, 22);
742d8ae3abSopenharmony_ci/// # }
752d8ae3abSopenharmony_ci/// ```
762d8ae3abSopenharmony_ci#[macro_export(local_inner_macros)]
772d8ae3abSopenharmony_cimacro_rules! error {
782d8ae3abSopenharmony_ci    // error!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
792d8ae3abSopenharmony_ci    // error!(target: "my_target", "a {} event", "log")
802d8ae3abSopenharmony_ci    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Error, $($arg)+));
812d8ae3abSopenharmony_ci
822d8ae3abSopenharmony_ci    // error!("a {} event", "log")
832d8ae3abSopenharmony_ci    ($($arg:tt)+) => (log!($crate::Level::Error, $($arg)+))
842d8ae3abSopenharmony_ci}
852d8ae3abSopenharmony_ci
862d8ae3abSopenharmony_ci/// Logs a message at the warn level.
872d8ae3abSopenharmony_ci///
882d8ae3abSopenharmony_ci/// # Examples
892d8ae3abSopenharmony_ci///
902d8ae3abSopenharmony_ci/// ```edition2018
912d8ae3abSopenharmony_ci/// use log::warn;
922d8ae3abSopenharmony_ci///
932d8ae3abSopenharmony_ci/// # fn main() {
942d8ae3abSopenharmony_ci/// let warn_description = "Invalid Input";
952d8ae3abSopenharmony_ci///
962d8ae3abSopenharmony_ci/// warn!("Warning! {}!", warn_description);
972d8ae3abSopenharmony_ci/// warn!(target: "input_events", "App received warning: {}", warn_description);
982d8ae3abSopenharmony_ci/// # }
992d8ae3abSopenharmony_ci/// ```
1002d8ae3abSopenharmony_ci#[macro_export(local_inner_macros)]
1012d8ae3abSopenharmony_cimacro_rules! warn {
1022d8ae3abSopenharmony_ci    // warn!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
1032d8ae3abSopenharmony_ci    // warn!(target: "my_target", "a {} event", "log")
1042d8ae3abSopenharmony_ci    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Warn, $($arg)+));
1052d8ae3abSopenharmony_ci
1062d8ae3abSopenharmony_ci    // warn!("a {} event", "log")
1072d8ae3abSopenharmony_ci    ($($arg:tt)+) => (log!($crate::Level::Warn, $($arg)+))
1082d8ae3abSopenharmony_ci}
1092d8ae3abSopenharmony_ci
1102d8ae3abSopenharmony_ci/// Logs a message at the info level.
1112d8ae3abSopenharmony_ci///
1122d8ae3abSopenharmony_ci/// # Examples
1132d8ae3abSopenharmony_ci///
1142d8ae3abSopenharmony_ci/// ```edition2018
1152d8ae3abSopenharmony_ci/// use log::info;
1162d8ae3abSopenharmony_ci///
1172d8ae3abSopenharmony_ci/// # fn main() {
1182d8ae3abSopenharmony_ci/// # struct Connection { port: u32, speed: f32 }
1192d8ae3abSopenharmony_ci/// let conn_info = Connection { port: 40, speed: 3.20 };
1202d8ae3abSopenharmony_ci///
1212d8ae3abSopenharmony_ci/// info!("Connected to port {} at {} Mb/s", conn_info.port, conn_info.speed);
1222d8ae3abSopenharmony_ci/// info!(target: "connection_events", "Successfull connection, port: {}, speed: {}",
1232d8ae3abSopenharmony_ci///       conn_info.port, conn_info.speed);
1242d8ae3abSopenharmony_ci/// # }
1252d8ae3abSopenharmony_ci/// ```
1262d8ae3abSopenharmony_ci#[macro_export(local_inner_macros)]
1272d8ae3abSopenharmony_cimacro_rules! info {
1282d8ae3abSopenharmony_ci    // info!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
1292d8ae3abSopenharmony_ci    // info!(target: "my_target", "a {} event", "log")
1302d8ae3abSopenharmony_ci    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Info, $($arg)+));
1312d8ae3abSopenharmony_ci
1322d8ae3abSopenharmony_ci    // info!("a {} event", "log")
1332d8ae3abSopenharmony_ci    ($($arg:tt)+) => (log!($crate::Level::Info, $($arg)+))
1342d8ae3abSopenharmony_ci}
1352d8ae3abSopenharmony_ci
1362d8ae3abSopenharmony_ci/// Logs a message at the debug level.
1372d8ae3abSopenharmony_ci///
1382d8ae3abSopenharmony_ci/// # Examples
1392d8ae3abSopenharmony_ci///
1402d8ae3abSopenharmony_ci/// ```edition2018
1412d8ae3abSopenharmony_ci/// use log::debug;
1422d8ae3abSopenharmony_ci///
1432d8ae3abSopenharmony_ci/// # fn main() {
1442d8ae3abSopenharmony_ci/// # struct Position { x: f32, y: f32 }
1452d8ae3abSopenharmony_ci/// let pos = Position { x: 3.234, y: -1.223 };
1462d8ae3abSopenharmony_ci///
1472d8ae3abSopenharmony_ci/// debug!("New position: x: {}, y: {}", pos.x, pos.y);
1482d8ae3abSopenharmony_ci/// debug!(target: "app_events", "New position: x: {}, y: {}", pos.x, pos.y);
1492d8ae3abSopenharmony_ci/// # }
1502d8ae3abSopenharmony_ci/// ```
1512d8ae3abSopenharmony_ci#[macro_export(local_inner_macros)]
1522d8ae3abSopenharmony_cimacro_rules! debug {
1532d8ae3abSopenharmony_ci    // debug!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
1542d8ae3abSopenharmony_ci    // debug!(target: "my_target", "a {} event", "log")
1552d8ae3abSopenharmony_ci    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Debug, $($arg)+));
1562d8ae3abSopenharmony_ci
1572d8ae3abSopenharmony_ci    // debug!("a {} event", "log")
1582d8ae3abSopenharmony_ci    ($($arg:tt)+) => (log!($crate::Level::Debug, $($arg)+))
1592d8ae3abSopenharmony_ci}
1602d8ae3abSopenharmony_ci
1612d8ae3abSopenharmony_ci/// Logs a message at the trace level.
1622d8ae3abSopenharmony_ci///
1632d8ae3abSopenharmony_ci/// # Examples
1642d8ae3abSopenharmony_ci///
1652d8ae3abSopenharmony_ci/// ```edition2018
1662d8ae3abSopenharmony_ci/// use log::trace;
1672d8ae3abSopenharmony_ci///
1682d8ae3abSopenharmony_ci/// # fn main() {
1692d8ae3abSopenharmony_ci/// # struct Position { x: f32, y: f32 }
1702d8ae3abSopenharmony_ci/// let pos = Position { x: 3.234, y: -1.223 };
1712d8ae3abSopenharmony_ci///
1722d8ae3abSopenharmony_ci/// trace!("Position is: x: {}, y: {}", pos.x, pos.y);
1732d8ae3abSopenharmony_ci/// trace!(target: "app_events", "x is {} and y is {}",
1742d8ae3abSopenharmony_ci///        if pos.x >= 0.0 { "positive" } else { "negative" },
1752d8ae3abSopenharmony_ci///        if pos.y >= 0.0 { "positive" } else { "negative" });
1762d8ae3abSopenharmony_ci/// # }
1772d8ae3abSopenharmony_ci/// ```
1782d8ae3abSopenharmony_ci#[macro_export(local_inner_macros)]
1792d8ae3abSopenharmony_cimacro_rules! trace {
1802d8ae3abSopenharmony_ci    // trace!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
1812d8ae3abSopenharmony_ci    // trace!(target: "my_target", "a {} event", "log")
1822d8ae3abSopenharmony_ci    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Trace, $($arg)+));
1832d8ae3abSopenharmony_ci
1842d8ae3abSopenharmony_ci    // trace!("a {} event", "log")
1852d8ae3abSopenharmony_ci    ($($arg:tt)+) => (log!($crate::Level::Trace, $($arg)+))
1862d8ae3abSopenharmony_ci}
1872d8ae3abSopenharmony_ci
1882d8ae3abSopenharmony_ci/// Determines if a message logged at the specified level in that module will
1892d8ae3abSopenharmony_ci/// be logged.
1902d8ae3abSopenharmony_ci///
1912d8ae3abSopenharmony_ci/// This can be used to avoid expensive computation of log message arguments if
1922d8ae3abSopenharmony_ci/// the message would be ignored anyway.
1932d8ae3abSopenharmony_ci///
1942d8ae3abSopenharmony_ci/// # Examples
1952d8ae3abSopenharmony_ci///
1962d8ae3abSopenharmony_ci/// ```edition2018
1972d8ae3abSopenharmony_ci/// use log::Level::Debug;
1982d8ae3abSopenharmony_ci/// use log::{debug, log_enabled};
1992d8ae3abSopenharmony_ci///
2002d8ae3abSopenharmony_ci/// # fn foo() {
2012d8ae3abSopenharmony_ci/// if log_enabled!(Debug) {
2022d8ae3abSopenharmony_ci///     let data = expensive_call();
2032d8ae3abSopenharmony_ci///     debug!("expensive debug data: {} {}", data.x, data.y);
2042d8ae3abSopenharmony_ci/// }
2052d8ae3abSopenharmony_ci/// if log_enabled!(target: "Global", Debug) {
2062d8ae3abSopenharmony_ci///    let data = expensive_call();
2072d8ae3abSopenharmony_ci///    debug!(target: "Global", "expensive debug data: {} {}", data.x, data.y);
2082d8ae3abSopenharmony_ci/// }
2092d8ae3abSopenharmony_ci/// # }
2102d8ae3abSopenharmony_ci/// # struct Data { x: u32, y: u32 }
2112d8ae3abSopenharmony_ci/// # fn expensive_call() -> Data { Data { x: 0, y: 0 } }
2122d8ae3abSopenharmony_ci/// # fn main() {}
2132d8ae3abSopenharmony_ci/// ```
2142d8ae3abSopenharmony_ci#[macro_export(local_inner_macros)]
2152d8ae3abSopenharmony_cimacro_rules! log_enabled {
2162d8ae3abSopenharmony_ci    (target: $target:expr, $lvl:expr) => {{
2172d8ae3abSopenharmony_ci        let lvl = $lvl;
2182d8ae3abSopenharmony_ci        lvl <= $crate::STATIC_MAX_LEVEL
2192d8ae3abSopenharmony_ci            && lvl <= $crate::max_level()
2202d8ae3abSopenharmony_ci            && $crate::__private_api_enabled(lvl, $target)
2212d8ae3abSopenharmony_ci    }};
2222d8ae3abSopenharmony_ci    ($lvl:expr) => {
2232d8ae3abSopenharmony_ci        log_enabled!(target: __log_module_path!(), $lvl)
2242d8ae3abSopenharmony_ci    };
2252d8ae3abSopenharmony_ci}
2262d8ae3abSopenharmony_ci
2272d8ae3abSopenharmony_ci// The log macro above cannot invoke format_args directly because it uses
2282d8ae3abSopenharmony_ci// local_inner_macros. A format_args invocation there would resolve to
2292d8ae3abSopenharmony_ci// $crate::format_args which does not exist. Instead invoke format_args here
2302d8ae3abSopenharmony_ci// outside of local_inner_macros so that it resolves (probably) to
2312d8ae3abSopenharmony_ci// core::format_args or std::format_args. Same for the several macros that
2322d8ae3abSopenharmony_ci// follow.
2332d8ae3abSopenharmony_ci//
2342d8ae3abSopenharmony_ci// This is a workaround until we drop support for pre-1.30 compilers. At that
2352d8ae3abSopenharmony_ci// point we can remove use of local_inner_macros, use $crate:: when invoking
2362d8ae3abSopenharmony_ci// local macros, and invoke format_args directly.
2372d8ae3abSopenharmony_ci#[doc(hidden)]
2382d8ae3abSopenharmony_ci#[macro_export]
2392d8ae3abSopenharmony_cimacro_rules! __log_format_args {
2402d8ae3abSopenharmony_ci    ($($args:tt)*) => {
2412d8ae3abSopenharmony_ci        format_args!($($args)*)
2422d8ae3abSopenharmony_ci    };
2432d8ae3abSopenharmony_ci}
2442d8ae3abSopenharmony_ci
2452d8ae3abSopenharmony_ci#[doc(hidden)]
2462d8ae3abSopenharmony_ci#[macro_export]
2472d8ae3abSopenharmony_cimacro_rules! __log_module_path {
2482d8ae3abSopenharmony_ci    () => {
2492d8ae3abSopenharmony_ci        module_path!()
2502d8ae3abSopenharmony_ci    };
2512d8ae3abSopenharmony_ci}
2522d8ae3abSopenharmony_ci
2532d8ae3abSopenharmony_ci#[doc(hidden)]
2542d8ae3abSopenharmony_ci#[macro_export]
2552d8ae3abSopenharmony_cimacro_rules! __log_file {
2562d8ae3abSopenharmony_ci    () => {
2572d8ae3abSopenharmony_ci        file!()
2582d8ae3abSopenharmony_ci    };
2592d8ae3abSopenharmony_ci}
2602d8ae3abSopenharmony_ci
2612d8ae3abSopenharmony_ci#[doc(hidden)]
2622d8ae3abSopenharmony_ci#[macro_export]
2632d8ae3abSopenharmony_cimacro_rules! __log_line {
2642d8ae3abSopenharmony_ci    () => {
2652d8ae3abSopenharmony_ci        line!()
2662d8ae3abSopenharmony_ci    };
2672d8ae3abSopenharmony_ci}
2682d8ae3abSopenharmony_ci
2692d8ae3abSopenharmony_ci#[doc(hidden)]
2702d8ae3abSopenharmony_ci#[macro_export]
2712d8ae3abSopenharmony_cimacro_rules! __log_key {
2722d8ae3abSopenharmony_ci    // key1 = 42
2732d8ae3abSopenharmony_ci    ($($args:ident)*) => {
2742d8ae3abSopenharmony_ci        stringify!($($args)*)
2752d8ae3abSopenharmony_ci    };
2762d8ae3abSopenharmony_ci    // "key1" = 42
2772d8ae3abSopenharmony_ci    ($($args:expr)*) => {
2782d8ae3abSopenharmony_ci        $($args)*
2792d8ae3abSopenharmony_ci    };
2802d8ae3abSopenharmony_ci}
281