// Copyright 2014-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. | |
/// The standard logging macro. | |
/// | |
/// This macro will generically log with the specified `Level` and `format!` | |
/// based argument list. | |
/// | |
/// # Examples | |
/// | |
/// ```edition2018 | |
/// use log::{log, Level}; | |
/// | |
/// # fn main() { | |
/// let data = (42, "Forty-two"); | |
/// let private_data = "private"; | |
/// | |
/// log!(Level::Error, "Received errors: {}, {}", data.0, data.1); | |
/// log!(target: "app_events", Level::Warn, "App warning: {}, {}, {}", | |
/// data.0, data.1, private_data); | |
/// # } | |
/// ``` | |
#[macro_export(local_inner_macros)] | |
macro_rules! log { | |
// log!(target: "my_target", Level::Info; key1 = 42, key2 = true; "a {} event", "log"); | |
(target: $target:expr, $lvl:expr, $($key:tt = $value:expr),+; $($arg:tt)+) => ({ | |
let lvl = $lvl; | |
if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() { | |
$crate::__private_api_log( | |
__log_format_args!($($arg)+), | |
lvl, | |
&($target, __log_module_path!(), __log_file!(), __log_line!()), | |
$crate::__private_api::Option::Some(&[$((__log_key!($key), &$value)),+]) | |
); | |
} | |
}); | |
// log!(target: "my_target", Level::Info; "a {} event", "log"); | |
(target: $target:expr, $lvl:expr, $($arg:tt)+) => ({ | |
let lvl = $lvl; | |
if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() { | |
$crate::__private_api_log( | |
__log_format_args!($($arg)+), | |
lvl, | |
&($target, __log_module_path!(), __log_file!(), __log_line!()), | |
$crate::__private_api::Option::None, | |
); | |
} | |
}); | |
// log!(Level::Info, "a log event") | |
($lvl:expr, $($arg:tt)+) => (log!(target: __log_module_path!(), $lvl, $($arg)+)); | |
} | |
/// Logs a message at the error level. | |
/// | |
/// # Examples | |
/// | |
/// ```edition2018 | |
/// use log::error; | |
/// | |
/// # fn main() { | |
/// let (err_info, port) = ("No connection", 22); | |
/// | |
/// error!("Error: {} on port {}", err_info, port); | |
/// error!(target: "app_events", "App Error: {}, Port: {}", err_info, 22); | |
/// # } | |
/// ``` | |
#[macro_export(local_inner_macros)] | |
macro_rules! error { | |
// error!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") | |
// error!(target: "my_target", "a {} event", "log") | |
(target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Error, $($arg)+)); | |
// error!("a {} event", "log") | |
($($arg:tt)+) => (log!($crate::Level::Error, $($arg)+)) | |
} | |
/// Logs a message at the warn level. | |
/// | |
/// # Examples | |
/// | |
/// ```edition2018 | |
/// use log::warn; | |
/// | |
/// # fn main() { | |
/// let warn_description = "Invalid Input"; | |
/// | |
/// warn!("Warning! {}!", warn_description); | |
/// warn!(target: "input_events", "App received warning: {}", warn_description); | |
/// # } | |
/// ``` | |
#[macro_export(local_inner_macros)] | |
macro_rules! warn { | |
// warn!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") | |
// warn!(target: "my_target", "a {} event", "log") | |
(target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Warn, $($arg)+)); | |
// warn!("a {} event", "log") | |
($($arg:tt)+) => (log!($crate::Level::Warn, $($arg)+)) | |
} | |
/// Logs a message at the info level. | |
/// | |
/// # Examples | |
/// | |
/// ```edition2018 | |
/// use log::info; | |
/// | |
/// # fn main() { | |
/// # struct Connection { port: u32, speed: f32 } | |
/// let conn_info = Connection { port: 40, speed: 3.20 }; | |
/// | |
/// info!("Connected to port {} at {} Mb/s", conn_info.port, conn_info.speed); | |
/// info!(target: "connection_events", "Successfull connection, port: {}, speed: {}", | |
/// conn_info.port, conn_info.speed); | |
/// # } | |
/// ``` | |
#[macro_export(local_inner_macros)] | |
macro_rules! info { | |
// info!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") | |
// info!(target: "my_target", "a {} event", "log") | |
(target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Info, $($arg)+)); | |
// info!("a {} event", "log") | |
($($arg:tt)+) => (log!($crate::Level::Info, $($arg)+)) | |
} | |
/// Logs a message at the debug level. | |
/// | |
/// # Examples | |
/// | |
/// ```edition2018 | |
/// use log::debug; | |
/// | |
/// # fn main() { | |
/// # struct Position { x: f32, y: f32 } | |
/// let pos = Position { x: 3.234, y: -1.223 }; | |
/// | |
/// debug!("New position: x: {}, y: {}", pos.x, pos.y); | |
/// debug!(target: "app_events", "New position: x: {}, y: {}", pos.x, pos.y); | |
/// # } | |
/// ``` | |
#[macro_export(local_inner_macros)] | |
macro_rules! debug { | |
// debug!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") | |
// debug!(target: "my_target", "a {} event", "log") | |
(target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Debug, $($arg)+)); | |
// debug!("a {} event", "log") | |
($($arg:tt)+) => (log!($crate::Level::Debug, $($arg)+)) | |
} | |
/// Logs a message at the trace level. | |
/// | |
/// # Examples | |
/// | |
/// ```edition2018 | |
/// use log::trace; | |
/// | |
/// # fn main() { | |
/// # struct Position { x: f32, y: f32 } | |
/// let pos = Position { x: 3.234, y: -1.223 }; | |
/// | |
/// trace!("Position is: x: {}, y: {}", pos.x, pos.y); | |
/// trace!(target: "app_events", "x is {} and y is {}", | |
/// if pos.x >= 0.0 { "positive" } else { "negative" }, | |
/// if pos.y >= 0.0 { "positive" } else { "negative" }); | |
/// # } | |
/// ``` | |
#[macro_export(local_inner_macros)] | |
macro_rules! trace { | |
// trace!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") | |
// trace!(target: "my_target", "a {} event", "log") | |
(target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Trace, $($arg)+)); | |
// trace!("a {} event", "log") | |
($($arg:tt)+) => (log!($crate::Level::Trace, $($arg)+)) | |
} | |
/// Determines if a message logged at the specified level in that module will | |
/// be logged. | |
/// | |
/// This can be used to avoid expensive computation of log message arguments if | |
/// the message would be ignored anyway. | |
/// | |
/// # Examples | |
/// | |
/// ```edition2018 | |
/// use log::Level::Debug; | |
/// use log::{debug, log_enabled}; | |
/// | |
/// # fn foo() { | |
/// if log_enabled!(Debug) { | |
/// let data = expensive_call(); | |
/// debug!("expensive debug data: {} {}", data.x, data.y); | |
/// } | |
/// if log_enabled!(target: "Global", Debug) { | |
/// let data = expensive_call(); | |
/// debug!(target: "Global", "expensive debug data: {} {}", data.x, data.y); | |
/// } | |
/// # } | |
/// # struct Data { x: u32, y: u32 } | |
/// # fn expensive_call() -> Data { Data { x: 0, y: 0 } } | |
/// # fn main() {} | |
/// ``` | |
#[macro_export(local_inner_macros)] | |
macro_rules! log_enabled { | |
(target: $target:expr, $lvl:expr) => {{ | |
let lvl = $lvl; | |
lvl <= $crate::STATIC_MAX_LEVEL | |
&& lvl <= $crate::max_level() | |
&& $crate::__private_api_enabled(lvl, $target) | |
}}; | |
($lvl:expr) => { | |
log_enabled!(target: __log_module_path!(), $lvl) | |
}; | |
} | |
// The log macro above cannot invoke format_args directly because it uses | |
// local_inner_macros. A format_args invocation there would resolve to | |
// $crate::format_args which does not exist. Instead invoke format_args here | |
// outside of local_inner_macros so that it resolves (probably) to | |
// core::format_args or std::format_args. Same for the several macros that | |
// follow. | |
// | |
// This is a workaround until we drop support for pre-1.30 compilers. At that | |
// point we can remove use of local_inner_macros, use $crate:: when invoking | |
// local macros, and invoke format_args directly. | |
#[doc(hidden)] | |
#[macro_export] | |
macro_rules! __log_format_args { | |
($($args:tt)*) => { | |
format_args!($($args)*) | |
}; | |
} | |
#[doc(hidden)] | |
#[macro_export] | |
macro_rules! __log_module_path { | |
() => { | |
module_path!() | |
}; | |
} | |
#[doc(hidden)] | |
#[macro_export] | |
macro_rules! __log_file { | |
() => { | |
file!() | |
}; | |
} | |
#[doc(hidden)] | |
#[macro_export] | |
macro_rules! __log_line { | |
() => { | |
line!() | |
}; | |
} | |
#[doc(hidden)] | |
#[macro_export] | |
macro_rules! __log_key { | |
// key1 = 42 | |
($($args:ident)*) => { | |
stringify!($($args)*) | |
}; | |
// "key1" = 42 | |
($($args:expr)*) => { | |
$($args)* | |
}; | |
} |