Skip to content

Commit

Permalink
Add kv as an optional parameter to logging macros
Browse files Browse the repository at this point in the history
  • Loading branch information
SpriteOvO committed Nov 24, 2024
1 parent e0bca88 commit 846e917
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 5 deletions.
11 changes: 9 additions & 2 deletions spdlog/src/kv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ use value_bag::{OwnedValueBag, ValueBag};

use crate::helper::ConcreteCow;

#[derive(Debug, Clone)]
enum KeyInner<'a> {
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum KeyInner<'a> {
Str(&'a str),
StaticStr(&'static str),
}

// TODO: PartialEq
#[derive(Debug, Clone)]
pub struct Key<'a>(KeyInner<'a>);

impl<'a> Key<'a> {
#[doc(hidden)]
pub fn __from_static_str(key: &'static str) -> Self {
Key(KeyInner::StaticStr(key))
}
Expand All @@ -29,6 +31,11 @@ impl<'a> Key<'a> {
};
KeyOwned(inner)
}

#[cfg(test)]
pub(crate) fn inner(&self) -> KeyInner<'a> {
self.0.clone()
}
}

#[derive(Debug, Clone)]
Expand Down
230 changes: 227 additions & 3 deletions spdlog/src/log_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@
/// [`Level`]: crate::Level
#[macro_export]
macro_rules! log {
(logger: $logger:expr, $level:expr, $($arg:tt)+) => ({
(logger: $logger:expr, kv: $kv:tt, $level:expr, $($arg:tt)+) => ({
let logger = &$logger;
const LEVEL: $crate::Level = $level;
const SHOULD_LOG: bool = $crate::STATIC_LEVEL_FILTER.__test_const(LEVEL);
if SHOULD_LOG && logger.should_log(LEVEL) {
$crate::__log(logger, LEVEL, $crate::source_location_current!(), &[], format_args!($($arg)+));
$crate::__log(logger, LEVEL, $crate::source_location_current!(), $crate::__kv!($kv), format_args!($($arg)+));
}
});
($level:expr, $($arg:tt)+) => ($crate::log!(logger: $crate::default_logger(), $level, $($arg)+))
(logger: $logger:expr, $level:expr, $($arg:tt)+) => ($crate::log!(logger: $logger, kv: {}, $level, $($arg)+));
(kv: $kv:tt, $level:expr, $($arg:tt)+) => ($crate::log!(logger: $crate::default_logger(), kv: $kv, $level, $($arg)+));
($level:expr, $($arg:tt)+) => ($crate::log!(logger: $crate::default_logger(), kv: {}, $level, $($arg)+));
}

/// Logs a message at the critical level.
Expand All @@ -50,9 +52,15 @@ macro_rules! log {
/// ```
#[macro_export]
macro_rules! critical {
(logger: $logger:expr, kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(logger: $logger, kv: $kv, $crate::Level::Critical, $($arg)+)
);
(logger: $logger:expr, $($arg:tt)+) => (
$crate::log!(logger: $logger, $crate::Level::Critical, $($arg)+)
);
(kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(kv: $kv, $crate::Level::Critical, $($arg)+)
);
($($arg:tt)+) => (
$crate::log!($crate::Level::Critical, $($arg)+)
)
Expand All @@ -76,9 +84,15 @@ macro_rules! critical {
/// ```
#[macro_export]
macro_rules! error {
(logger: $logger:expr, kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(logger: $logger, kv: $kv, $crate::Level::Error, $($arg)+)
);
(logger: $logger:expr, $($arg:tt)+) => (
$crate::log!(logger: $logger, $crate::Level::Error, $($arg)+)
);
(kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(kv: $kv, $crate::Level::Error, $($arg)+)
);
($($arg:tt)+) => (
$crate::log!($crate::Level::Error, $($arg)+)
)
Expand All @@ -102,9 +116,15 @@ macro_rules! error {
/// ```
#[macro_export]
macro_rules! warn {
(logger: $logger:expr, kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(logger: $logger, kv: $kv, $crate::Level::Warn, $($arg)+)
);
(logger: $logger:expr, $($arg:tt)+) => (
$crate::log!(logger: $logger, $crate::Level::Warn, $($arg)+)
);
(kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(kv: $kv, $crate::Level::Warn, $($arg)+)
);
($($arg:tt)+) => (
$crate::log!($crate::Level::Warn, $($arg)+)
)
Expand All @@ -129,9 +149,15 @@ macro_rules! warn {
/// ```
#[macro_export]
macro_rules! info {
(logger: $logger:expr, kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(logger: $logger, kv: $kv, $crate::Level::Info, $($arg)+)
);
(logger: $logger:expr, $($arg:tt)+) => (
$crate::log!(logger: $logger, $crate::Level::Info, $($arg)+)
);
(kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(kv: $kv, $crate::Level::Info, $($arg)+)
);
($($arg:tt)+) => (
$crate::log!($crate::Level::Info, $($arg)+)
)
Expand All @@ -156,9 +182,15 @@ macro_rules! info {
/// ```
#[macro_export]
macro_rules! debug {
(logger: $logger:expr, kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(logger: $logger, kv: $kv, $crate::Level::Debug, $($arg)+)
);
(logger: $logger:expr, $($arg:tt)+) => (
$crate::log!(logger: $logger, $crate::Level::Debug, $($arg)+)
);
(kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(kv: $kv, $crate::Level::Debug, $($arg)+)
);
($($arg:tt)+) => (
$crate::log!($crate::Level::Debug, $($arg)+)
)
Expand All @@ -185,10 +217,202 @@ macro_rules! debug {
/// ```
#[macro_export]
macro_rules! trace {
(logger: $logger:expr, kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(logger: $logger, kv: $kv, $crate::Level::Trace, $($arg)+)
);
(logger: $logger:expr, $($arg:tt)+) => (
$crate::log!(logger: $logger, $crate::Level::Trace, $($arg)+)
);
(kv: $kv:tt, $($arg:tt)+) => (
$crate::log!(kv: $kv, $crate::Level::Trace, $($arg)+)
);
($($arg:tt)+) => (
$crate::log!($crate::Level::Trace, $($arg)+)
)
}

#[doc(hidden)]
#[macro_export]
macro_rules! __kv {
({}) => (&[]);
({ $( $k:ident = $v:expr ),+ $(,)? }) => {
&[$(($crate::kv::Key::__from_static_str(stringify!($k)), $v.into())),+]
};
}

#[cfg(test)]
mod tests {
use std::sync::Arc;

use crate::{kv::KeyInner, prelude::*, test_utils::*};

#[test]
fn syntax_and_records() {
let test_sink = Arc::new(TestSink::new());
let test = Arc::new(build_test_logger(|b| {
b.sink(test_sink.clone()).level_filter(LevelFilter::All)
}));

log!(logger: test, Level::Info, "logger");
log!(logger: test, kv: {}, Level::Error, "logger, kv(0)");
log!(logger: test, kv: { k1 = 114 }, Level::Warn, "logger, kv(1)");
log!(logger: test, kv: { k1 = 114, k2 = 514 }, Level::Critical, "logger, kv(2)");
critical!(logger: test, "critical: logger");
critical!(logger: test, kv: {}, "critical: logger, kv(0)");
critical!(logger: test, kv: { k1 = 114 }, "critical: logger, kv(1)");
critical!(logger: test, kv: { k1 = 114, k2 = 514 }, "critical: logger, kv(2)");
error!(logger: test, "error: logger");
error!(logger: test, kv: {}, "error: logger, kv(0)");
error!(logger: test, kv: { k1 = 114 }, "error: logger, kv(1)");
error!(logger: test, kv: { k1 = 114, k2 = 514 }, "error: logger, kv(2)");
warn!(logger: test, "warn: logger");
warn!(logger: test, kv: {}, "warn: logger, kv(0)");
warn!(logger: test, kv: { k1 = 114 }, "warn: logger, kv(1)");
warn!(logger: test, kv: { k1 = 114, k2 = 514 }, "warn: logger, kv(2)");
info!(logger: test, "info: logger");
info!(logger: test, kv: {}, "info: logger, kv(0)");
info!(logger: test, kv: { k1 = 114 }, "info: logger, kv(1)");
info!(logger: test, kv: { k1 = 114, k2 = 514 }, "info: logger, kv(2)");
debug!(logger: test, "debug: logger");
debug!(logger: test, kv: {}, "debug: logger, kv(0)");
debug!(logger: test, kv: { k1 = 114 }, "debug: logger, kv(1)");
debug!(logger: test, kv: { k1 = 114, k2 = 514 }, "debug: logger, kv(2)");
trace!(logger: test, "trace: logger");
trace!(logger: test, kv: {}, "trace: logger, kv(0)");
trace!(logger: test, kv: { k1 = 114 }, "trace: logger, kv(1)");
trace!(logger: test, kv: { k1 = 114, k2 = 514 }, "trace: logger, kv(2)");

let records = test_sink.records();
let check = records
.iter()
.map(|record| {
(
record
.key_values()
.into_iter()
.map(|(k, v)| (k.inner(), v.to_i64().unwrap()))
.collect::<Vec<_>>(),
record.level(),
record.payload(),
)
})
.collect::<Vec<_>>();

assert_eq!(
check,
vec![
(vec![], Level::Info, "logger"),
(vec![], Level::Error, "logger, kv(0)"),
(
vec![(KeyInner::StaticStr("k1"), 114)],
Level::Warn,
"logger, kv(1)"
),
(
vec![
(KeyInner::StaticStr("k1"), 114),
(KeyInner::StaticStr("k2"), 514)
],
Level::Critical,
"logger, kv(2)"
),
//
(vec![], Level::Critical, "critical: logger"),
(vec![], Level::Critical, "critical: logger, kv(0)"),
(
vec![(KeyInner::StaticStr("k1"), 114)],
Level::Critical,
"critical: logger, kv(1)"
),
(
vec![
(KeyInner::StaticStr("k1"), 114),
(KeyInner::StaticStr("k2"), 514)
],
Level::Critical,
"critical: logger, kv(2)"
),
//
(vec![], Level::Error, "error: logger"),
(vec![], Level::Error, "error: logger, kv(0)"),
(
vec![(KeyInner::StaticStr("k1"), 114)],
Level::Error,
"error: logger, kv(1)"
),
(
vec![
(KeyInner::StaticStr("k1"), 114),
(KeyInner::StaticStr("k2"), 514)
],
Level::Error,
"error: logger, kv(2)"
),
//
(vec![], Level::Warn, "warn: logger"),
(vec![], Level::Warn, "warn: logger, kv(0)"),
(
vec![(KeyInner::StaticStr("k1"), 114)],
Level::Warn,
"warn: logger, kv(1)"
),
(
vec![
(KeyInner::StaticStr("k1"), 114),
(KeyInner::StaticStr("k2"), 514)
],
Level::Warn,
"warn: logger, kv(2)"
),
//
(vec![], Level::Info, "info: logger"),
(vec![], Level::Info, "info: logger, kv(0)"),
(
vec![(KeyInner::StaticStr("k1"), 114)],
Level::Info,
"info: logger, kv(1)"
),
(
vec![
(KeyInner::StaticStr("k1"), 114),
(KeyInner::StaticStr("k2"), 514)
],
Level::Info,
"info: logger, kv(2)"
),
//
(vec![], Level::Debug, "debug: logger"),
(vec![], Level::Debug, "debug: logger, kv(0)"),
(
vec![(KeyInner::StaticStr("k1"), 114)],
Level::Debug,
"debug: logger, kv(1)"
),
(
vec![
(KeyInner::StaticStr("k1"), 114),
(KeyInner::StaticStr("k2"), 514)
],
Level::Debug,
"debug: logger, kv(2)"
),
//
(vec![], Level::Trace, "trace: logger"),
(vec![], Level::Trace, "trace: logger, kv(0)"),
(
vec![(KeyInner::StaticStr("k1"), 114)],
Level::Trace,
"trace: logger, kv(1)"
),
(
vec![
(KeyInner::StaticStr("k1"), 114),
(KeyInner::StaticStr("k2"), 514)
],
Level::Trace,
"trace: logger, kv(2)"
),
]
);
}
}

0 comments on commit 846e917

Please sign in to comment.