Merge pull request #673 from rust-lang/feat/logger-by-ref

Pass global logger by value, supplied logger by ref
This commit is contained in:
Ashley Mannix 2025-03-24 06:19:31 +10:00 committed by GitHub
commit ea6f54d395
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 209 additions and 63 deletions

View File

@ -35,11 +35,7 @@ impl<'a> KVs<'a> for () {
// Log implementation. // Log implementation.
/// The global logger proxy. /// The global logger proxy.
/// #[derive(Debug)]
/// This zero-sized type implements the [`Log`] trait by forwarding calls
/// to the logger registered with the `set_boxed_logger` or `set_logger`
/// methods if there is one, or a nop logger as default.
#[derive(Copy, Clone, Default, Debug)]
pub struct GlobalLogger; pub struct GlobalLogger;
impl Log for GlobalLogger { impl Log for GlobalLogger {
@ -56,6 +52,7 @@ impl Log for GlobalLogger {
} }
} }
// Split from `log` to reduce generics and code size
fn log_impl<L: Log>( fn log_impl<L: Log>(
logger: L, logger: L,
args: Arguments, args: Arguments,
@ -85,7 +82,7 @@ fn log_impl<L: Log>(
} }
pub fn log<'a, K, L>( pub fn log<'a, K, L>(
logger: &L, logger: L,
args: Arguments, args: Arguments,
level: Level, level: Level,
target_module_path_and_loc: &(&str, &'static str, &'static Location), target_module_path_and_loc: &(&str, &'static str, &'static Location),

View File

@ -58,24 +58,75 @@
/// ///
/// let my_logger = MyLogger {}; /// let my_logger = MyLogger {};
/// log!( /// log!(
/// logger: &my_logger, /// logger: my_logger,
/// Level::Error, /// Level::Error,
/// "Received errors: {}, {}", /// "Received errors: {}, {}",
/// data.0, data.1 /// data.0, data.1
/// ); /// );
/// ```
///
/// The `logger` argument accepts a value that implements the `Log` trait. The value
/// will be borrowed within the macro.
///
/// Note that the global level set via Cargo features, or through `set_max_level` will
/// still apply, even when a custom logger is supplied with the `logger` argument.
#[macro_export] #[macro_export]
#[clippy::format_args] #[clippy::format_args]
macro_rules! log { macro_rules! log {
// log!(logger: my_logger, target: "my_target", Level::Info, "a {} event", "log");
(logger: $logger:expr, target: $target:expr, $lvl:expr, $($arg:tt)+) => ({
$crate::__log!(
logger: $crate::__log_logger!($logger),
target: $target,
$lvl,
$($arg)+
)
});
// log!(logger: my_logger, Level::Info, "a log event")
(logger: $logger:expr, $lvl:expr, $($arg:tt)+) => ({
$crate::__log!(
logger: $crate::__log_logger!($logger),
target: $crate::__private_api::module_path!(),
$lvl,
$($arg)+
)
});
// log!(target: "my_target", Level::Info, "a log event")
(target: $target:expr, $lvl:expr, $($arg:tt)+) => ({
$crate::__log!(
logger: $crate::__log_logger!(__log_global_logger),
target: $target,
$lvl,
$($arg)+
)
});
// log!(Level::Info, "a log event")
($lvl:expr, $($arg:tt)+) => ({
$crate::__log!(
logger: $crate::__log_logger!(__log_global_logger),
target: $crate::__private_api::module_path!(),
$lvl,
$($arg)+
)
});
}
#[doc(hidden)]
#[macro_export]
macro_rules! __log {
// log!(logger: my_logger, target: "my_target", Level::Info, key1:? = 42, key2 = true; "a {} event", "log"); // log!(logger: my_logger, target: "my_target", Level::Info, key1:? = 42, key2 = true; "a {} event", "log");
(logger: $logger:expr, target: $target:expr, $lvl:expr, $($key:tt $(:$capture:tt)? $(= $value:expr)?),+; $($arg:tt)+) => ({ (logger: $logger:expr, target: $target:expr, $lvl:expr, $($key:tt $(:$capture:tt)? $(= $value:expr)?),+; $($arg:tt)+) => ({
let lvl = $lvl; let lvl = $lvl;
if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() { if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() {
$crate::__private_api::log::<&_, _>( $crate::__private_api::log(
&($logger), $logger,
$crate::__private_api::format_args!($($arg)+), $crate::__private_api::format_args!($($arg)+),
lvl, lvl,
&($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()), &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
&[$(($crate::__log_key!($key), $crate::__log_value!($key $(:$capture)* = $($value)*))),+] &[$(($crate::__log_key!($key), $crate::__log_value!($key $(:$capture)* = $($value)*))),+] as &[_],
); );
} }
}); });
@ -85,7 +136,7 @@ macro_rules! log {
let lvl = $lvl; let lvl = $lvl;
if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() { if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() {
$crate::__private_api::log( $crate::__private_api::log(
&($logger), $logger,
$crate::__private_api::format_args!($($arg)+), $crate::__private_api::format_args!($($arg)+),
lvl, lvl,
&($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()), &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
@ -93,21 +144,6 @@ macro_rules! log {
); );
} }
}); });
// log!(logger: my_logger, Level::Info, "a log event")
(logger: $logger:expr, $lvl:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, target: $crate::__private_api::module_path!(), $lvl, $($arg)+)
});
// log!(target: "my_target", Level::Info, "a log event")
(target: $target:expr, $lvl:expr, $($arg:tt)+) => ({
$crate::log!(logger: $crate::__private_api::GlobalLogger, target: $target, $lvl, $($arg)+)
});
// log!(Level::Info, "a log event")
($lvl:expr, $($arg:tt)+) => ({
$crate::log!(target: $crate::__private_api::module_path!(), $lvl, $($arg)+)
});
} }
/// Logs a message at the error level. /// Logs a message at the error level.
@ -130,13 +166,13 @@ macro_rules! error {
// error!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // error!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
// error!(logger: my_logger, target: "my_target", "a {} event", "log") // error!(logger: my_logger, target: "my_target", "a {} event", "log")
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({ (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, target: $target, $crate::Level::Error, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Error, $($arg)+)
}); });
// error!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log") // error!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log")
// error!(logger: my_logger, "a {} event", "log") // error!(logger: my_logger, "a {} event", "log")
(logger: $logger:expr, $($arg:tt)+) => ({ (logger: $logger:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, $crate::Level::Error, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Error, $($arg)+)
}); });
// error!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // error!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
@ -169,13 +205,13 @@ macro_rules! warn {
// warn!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // warn!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
// warn!(logger: my_logger, target: "my_target", "a {} event", "log") // warn!(logger: my_logger, target: "my_target", "a {} event", "log")
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({ (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, target: $target, $crate::Level::Warn, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Warn, $($arg)+)
}); });
// warn!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log") // warn!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log")
// warn!(logger: my_logger, "a {} event", "log") // warn!(logger: my_logger, "a {} event", "log")
(logger: $logger:expr, $($arg:tt)+) => ({ (logger: $logger:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, $crate::Level::Warn, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Warn, $($arg)+)
}); });
// warn!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // warn!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
@ -217,13 +253,13 @@ macro_rules! info {
// info!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // info!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
// info!(logger: my_logger, target: "my_target", "a {} event", "log") // info!(logger: my_logger, target: "my_target", "a {} event", "log")
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({ (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, target: $target, $crate::Level::Info, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Info, $($arg)+)
}); });
// info!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log") // info!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log")
// info!(logger: my_logger, "a {} event", "log") // info!(logger: my_logger, "a {} event", "log")
(logger: $logger:expr, $($arg:tt)+) => ({ (logger: $logger:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, $crate::Level::Info, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Info, $($arg)+)
}); });
// info!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // info!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
@ -257,13 +293,13 @@ macro_rules! debug {
// debug!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // debug!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
// debug!(logger: my_logger, target: "my_target", "a {} event", "log") // debug!(logger: my_logger, target: "my_target", "a {} event", "log")
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({ (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, target: $target, $crate::Level::Debug, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Debug, $($arg)+)
}); });
// debug!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log") // debug!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log")
// debug!(logger: my_logger, "a {} event", "log") // debug!(logger: my_logger, "a {} event", "log")
(logger: $logger:expr, $($arg:tt)+) => ({ (logger: $logger:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, $crate::Level::Debug, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Debug, $($arg)+)
}); });
// debug!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // debug!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
@ -301,13 +337,13 @@ macro_rules! trace {
// trace!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // trace!(logger: my_logger, target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
// trace!(logger: my_logger, target: "my_target", "a {} event", "log") // trace!(logger: my_logger, target: "my_target", "a {} event", "log")
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({ (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, target: $target, $crate::Level::Trace, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Trace, $($arg)+)
}); });
// trace!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log") // trace!(logger: my_logger, key1 = 42, key2 = true; "a {} event", "log")
// trace!(logger: my_logger, "a {} event", "log") // trace!(logger: my_logger, "a {} event", "log")
(logger: $logger:expr, $($arg:tt)+) => ({ (logger: $logger:expr, $($arg:tt)+) => ({
$crate::log!(logger: $logger, $crate::Level::Trace, $($arg)+) $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Trace, $($arg)+)
}); });
// trace!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") // trace!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
@ -349,26 +385,55 @@ macro_rules! trace {
/// debug!(target: "Global", "expensive debug data: {} {}", data.x, data.y); /// debug!(target: "Global", "expensive debug data: {} {}", data.x, data.y);
/// } /// }
/// ``` /// ```
///
/// This macro accepts the same `target` and `logger` arguments as [`macro@log`].
#[macro_export] #[macro_export]
macro_rules! log_enabled { macro_rules! log_enabled {
// log_enabled!(logger: my_logger, target: "my_target", Level::Info)
(logger: $logger:expr, target: $target:expr, $lvl:expr) => ({ (logger: $logger:expr, target: $target:expr, $lvl:expr) => ({
$crate::__log_enabled!(logger: $crate::__log_logger!($logger), target: $target, $lvl)
});
// log_enabled!(logger: my_logger, Level::Info)
(logger: $logger:expr, $lvl:expr) => ({
$crate::__log_enabled!(logger: $crate::__log_logger!($logger), target: $crate::__private_api::module_path!(), $lvl)
});
// log_enabled!(target: "my_target", Level::Info)
(target: $target:expr, $lvl:expr) => ({
$crate::__log_enabled!(logger: $crate::__log_logger!(__log_global_logger), target: $target, $lvl)
});
// log_enabled!(Level::Info)
($lvl:expr) => ({
$crate::__log_enabled!(logger: $crate::__log_logger!(__log_global_logger), target: $crate::__private_api::module_path!(), $lvl)
});
}
#[doc(hidden)]
#[macro_export]
macro_rules! __log_enabled {
// log_enabled!(logger: my_logger, target: "my_target", Level::Info)
(logger: $logger:expr, target: $target:expr, $lvl:expr) => {{
let lvl = $lvl; let lvl = $lvl;
lvl <= $crate::STATIC_MAX_LEVEL lvl <= $crate::STATIC_MAX_LEVEL
&& lvl <= $crate::max_level() && lvl <= $crate::max_level()
&& $crate::__private_api::enabled($logger, lvl, $target) && $crate::__private_api::enabled($logger, lvl, $target)
}); }};
}
(logger: $logger:expr, $lvl:expr) => ({ // Determine the logger to use, and whether to take it by-value or by reference
$crate::log_enabled!(logger: $logger, target: $crate::__private_api::module_path!(), $lvl)
});
(target: $target:expr, $lvl:expr) => ({ #[doc(hidden)]
$crate::log_enabled!(logger: $crate::__private_api::GlobalLogger, target: $target, $lvl) #[macro_export]
}); macro_rules! __log_logger {
(__log_global_logger) => {{
$crate::__private_api::GlobalLogger
}};
($lvl:expr) => ({ ($logger:expr) => {{
$crate::log_enabled!(target: $crate::__private_api::module_path!(), $lvl) &($logger)
}); }};
} }
// These macros use a pattern of #[cfg]s to produce nicer error // These macros use a pattern of #[cfg]s to produce nicer error

View File

@ -3,14 +3,6 @@
use log::{debug, error, info, trace, warn, Level, LevelFilter, Log, Metadata, Record}; use log::{debug, error, info, trace, warn, Level, LevelFilter, Log, Metadata, Record};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
#[cfg(feature = "std")]
use log::set_boxed_logger;
#[cfg(not(feature = "std"))]
fn set_boxed_logger(logger: Box<dyn Log>) -> Result<(), log::SetLoggerError> {
log::set_logger(Box::leak(logger))
}
struct State { struct State {
last_log_level: Mutex<Option<Level>>, last_log_level: Mutex<Option<Level>>,
last_log_location: Mutex<Option<u32>>, last_log_location: Mutex<Option<u32>>,

View File

@ -10,6 +10,7 @@ macro_rules! all_log_macros {
}); });
} }
// Not `Copy`
struct Logger; struct Logger;
impl Log for Logger { impl Log for Logger {
@ -22,6 +23,8 @@ impl Log for Logger {
#[test] #[test]
fn no_args() { fn no_args() {
let logger = Logger;
for lvl in log::Level::iter() { for lvl in log::Level::iter() {
log!(lvl, "hello"); log!(lvl, "hello");
log!(lvl, "hello",); log!(lvl, "hello",);
@ -29,8 +32,11 @@ fn no_args() {
log!(target: "my_target", lvl, "hello"); log!(target: "my_target", lvl, "hello");
log!(target: "my_target", lvl, "hello",); log!(target: "my_target", lvl, "hello",);
log!(lvl, "hello"); log!(logger: logger, lvl, "hello");
log!(lvl, "hello",); log!(logger: logger, lvl, "hello",);
log!(logger: logger, target: "my_target", lvl, "hello");
log!(logger: logger, target: "my_target", lvl, "hello",);
} }
all_log_macros!("hello"); all_log_macros!("hello");
@ -39,10 +45,11 @@ fn no_args() {
all_log_macros!(target: "my_target", "hello"); all_log_macros!(target: "my_target", "hello");
all_log_macros!(target: "my_target", "hello",); all_log_macros!(target: "my_target", "hello",);
all_log_macros!(logger: Logger, "hello"); all_log_macros!(logger: logger, "hello");
all_log_macros!(logger: Logger, "hello",); all_log_macros!(logger: logger, "hello",);
all_log_macros!(logger: Logger, target: "my_target", "hello");
all_log_macros!(logger: Logger, target: "my_target", "hello",); all_log_macros!(logger: logger, target: "my_target", "hello");
all_log_macros!(logger: logger, target: "my_target", "hello",);
} }
#[test] #[test]
@ -63,6 +70,14 @@ fn anonymous_args() {
all_log_macros!(target: "my_target", "hello {}", "world"); all_log_macros!(target: "my_target", "hello {}", "world");
all_log_macros!(target: "my_target", "hello {}", "world",); all_log_macros!(target: "my_target", "hello {}", "world",);
let logger = Logger;
all_log_macros!(logger: logger, "hello {}", "world");
all_log_macros!(logger: logger, "hello {}", "world",);
all_log_macros!(logger: logger, target: "my_target", "hello {}", "world");
all_log_macros!(logger: logger, target: "my_target", "hello {}", "world",);
} }
#[test] #[test]
@ -83,6 +98,14 @@ fn named_args() {
all_log_macros!(target: "my_target", "hello {world}", world = "world"); all_log_macros!(target: "my_target", "hello {world}", world = "world");
all_log_macros!(target: "my_target", "hello {world}", world = "world",); all_log_macros!(target: "my_target", "hello {world}", world = "world",);
let logger = Logger;
all_log_macros!(logger: logger, "hello {world}", world = "world");
all_log_macros!(logger: logger, "hello {world}", world = "world",);
all_log_macros!(logger: logger, target: "my_target", "hello {world}", world = "world");
all_log_macros!(logger: logger, target: "my_target", "hello {world}", world = "world",);
} }
#[test] #[test]
@ -105,81 +128,136 @@ fn inlined_args() {
all_log_macros!(target: "my_target", "hello {world}"); all_log_macros!(target: "my_target", "hello {world}");
all_log_macros!(target: "my_target", "hello {world}",); all_log_macros!(target: "my_target", "hello {world}",);
let logger = Logger;
all_log_macros!(logger: logger, "hello {world}");
all_log_macros!(logger: logger, "hello {world}",);
all_log_macros!(logger: logger, target: "my_target", "hello {world}");
all_log_macros!(logger: logger, target: "my_target", "hello {world}",);
} }
#[test] #[test]
fn enabled() { fn enabled() {
let logger = Logger;
for lvl in log::Level::iter() { for lvl in log::Level::iter() {
let _enabled = log_enabled!(lvl);
let _enabled = log_enabled!(target: "my_target", lvl); let _enabled = log_enabled!(target: "my_target", lvl);
let _enabled = log_enabled!(logger: logger, target: "my_target", lvl);
let _enabled = log_enabled!(logger: logger, lvl);
} }
} }
#[test] #[test]
fn expr() { fn expr() {
let logger = Logger;
for lvl in log::Level::iter() { for lvl in log::Level::iter() {
log!(lvl, "hello"); log!(lvl, "hello");
log!(logger: logger, lvl, "hello");
} }
} }
#[test] #[test]
#[cfg(feature = "kv")] #[cfg(feature = "kv")]
fn kv_no_args() { fn kv_no_args() {
let logger = Logger;
for lvl in log::Level::iter() { for lvl in log::Level::iter() {
log!(target: "my_target", lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello"); log!(target: "my_target", lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
log!(lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello"); log!(lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
log!(logger: logger, target: "my_target", lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
log!(logger: logger, lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
} }
all_log_macros!(logger: Logger, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
all_log_macros!(logger: Logger, target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
all_log_macros!(target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello"); all_log_macros!(target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
all_log_macros!(target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello"); all_log_macros!(target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello"); all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
all_log_macros!(logger: logger, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
all_log_macros!(logger: logger, target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
} }
#[test] #[test]
#[cfg(feature = "kv")] #[cfg(feature = "kv")]
fn kv_expr_args() { fn kv_expr_args() {
let logger = Logger;
for lvl in log::Level::iter() { for lvl in log::Level::iter() {
log!(target: "my_target", lvl, cat_math = { let mut x = 0; x += 1; x + 1 }; "hello"); log!(target: "my_target", lvl, cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
log!(lvl, target = "my_target", cat_math = { let mut x = 0; x += 1; x + 1 }; "hello"); log!(lvl, target = "my_target", cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
log!(lvl, cat_math = { let mut x = 0; x += 1; x + 1 }; "hello"); log!(lvl, cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
log!(logger: logger, target: "my_target", lvl, cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
log!(logger: logger, lvl, target = "my_target", cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
log!(logger: logger, lvl, cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
} }
all_log_macros!(target: "my_target", cat_math = { let mut x = 0; x += 1; x + 1 }; "hello"); all_log_macros!(target: "my_target", cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
all_log_macros!(target = "my_target", cat_math = { let mut x = 0; x += 1; x + 1 }; "hello"); all_log_macros!(target = "my_target", cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
all_log_macros!(cat_math = { let mut x = 0; x += 1; x + 1 }; "hello"); all_log_macros!(cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
all_log_macros!(logger: logger, target: "my_target", cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
all_log_macros!(logger: logger, target = "my_target", cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
all_log_macros!(logger: logger, cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
} }
#[test] #[test]
#[cfg(feature = "kv")] #[cfg(feature = "kv")]
fn kv_anonymous_args() { fn kv_anonymous_args() {
let logger = Logger;
for lvl in log::Level::iter() { for lvl in log::Level::iter() {
log!(target: "my_target", lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world"); log!(target: "my_target", lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
log!(lvl, target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world"); log!(lvl, target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
log!(lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world"); log!(lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
log!(logger: logger, target: "my_target", lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
log!(logger: logger, lvl, target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
log!(logger: logger, lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
} }
all_log_macros!(target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world"); all_log_macros!(target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
all_log_macros!(target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world"); all_log_macros!(target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world"); all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
all_log_macros!(logger: logger, target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
all_log_macros!(logger: logger, target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
all_log_macros!(logger: logger, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
} }
#[test] #[test]
#[cfg(feature = "kv")] #[cfg(feature = "kv")]
fn kv_named_args() { fn kv_named_args() {
let logger = Logger;
for lvl in log::Level::iter() { for lvl in log::Level::iter() {
log!(target: "my_target", lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world"); log!(target: "my_target", lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
log!(lvl, target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world"); log!(lvl, target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
log!(lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world"); log!(lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
log!(logger: logger, target: "my_target", lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
log!(logger: logger, lvl, target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
log!(logger: logger, lvl, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
} }
all_log_macros!(target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world"); all_log_macros!(target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
all_log_macros!(target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world"); all_log_macros!(target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world"); all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
all_log_macros!(logger: logger, target: "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
all_log_macros!(logger: logger, target = "my_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
all_log_macros!(logger: logger, cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
} }
#[test] #[test]
@ -323,6 +401,20 @@ fn kv_serde() {
); );
} }
#[test]
fn logger_short_lived() {
all_log_macros!(logger: Logger, "hello");
all_log_macros!(logger: &Logger, "hello");
}
#[test]
fn logger_expr() {
all_log_macros!(logger: {
let logger = Logger;
logger
}, "hello");
}
/// Some and None (from Option) are used in the macros. /// Some and None (from Option) are used in the macros.
#[derive(Debug)] #[derive(Debug)]
enum Type { enum Type {