281 lines
8.5 KiB
Rust
281 lines
8.5 KiB
Rust
// 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)*
|
|
};
|
|
}
|