Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow macros to be more consistent with kvs #476

Merged
merged 10 commits into from
Jan 17, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ sval = { version = "=1.0.0-alpha.5", optional = true, default-features = false }
value-bag = { version = "=1.0.0-alpha.8", optional = true, default-features = false }

[dev-dependencies]
rustversion = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_test = "1.0"
sval = { version = "=1.0.0-alpha.5", features = ["derive"] }
Expand Down
29 changes: 27 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ This version is explicitly tested in CI and may be bumped in any release as need

## Usage

## In libraries
### In libraries

Libraries should link only to the `log` crate, and use the provided macros to
log whatever information will be useful to downstream consumers:
Expand Down Expand Up @@ -55,7 +55,7 @@ pub fn shave_the_yak(yak: &mut Yak) {
}
```

## In executables
### In executables

In order to produce log output, executables have to use a logger implementation compatible with the facade.
There are many available implementations to choose from, here are some of the most popular ones:
Expand Down Expand Up @@ -87,3 +87,28 @@ function to do this. Any log messages generated before the logger is
initialized will be ignored.

The executable itself may use the `log` crate to log as well.

## Structured logging

If you enable the `kv_unstable` feature, you can associate structured data with your log records:

```rust
use log::{info, trace, warn, as_serde, as_error};

pub fn shave_the_yak(yak: &mut Yak) {
trace!(target = "yak_events"; yak = as_serde!(yak); "Commencing yak shaving");

loop {
match find_a_razor() {
Ok(razor) => {
info!(razor = razor; "Razor located");
yak.shave(razor);
break;
}
Err(err) => {
warn!(err = as_error!(err); "Unable to locate a razor, retrying");
}
}
}
}
```
43 changes: 43 additions & 0 deletions src/kv/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,49 @@ impl<'v> ToValue for Value<'v> {
}
}

/// Get a value from a type implementing `std::fmt::Debug`.
#[macro_export]
macro_rules! as_debug {
($capture:expr) => {
$crate::kv::Value::from_debug(&$capture)
};
}

/// Get a value from a type implementing `std::fmt::Display`.
#[macro_export]
macro_rules! as_display {
($capture:expr) => {
$crate::kv::Value::from_display(&$capture)
};
}

/// Get a value from an error.
#[cfg(feature = "kv_unstable_std")]
#[macro_export]
macro_rules! as_error {
($capture:expr) => {
$crate::kv::Value::from_dyn_error(&$capture)
};
}

#[cfg(feature = "kv_unstable_serde")]
/// Get a value from a type implementing `serde::Serialize`.
#[macro_export]
macro_rules! as_serde {
($capture:expr) => {
$crate::kv::Value::from_serde(&$capture)
};
}

/// Get a value from a type implementing `sval::value::Value`.
#[cfg(feature = "kv_unstable_sval")]
#[macro_export]
macro_rules! as_sval {
($capture:expr) => {
$crate::kv::Value::from_sval(&$capture)
};
}

/// A value in a structured key-value pair.
///
/// # Capturing values
Expand Down
40 changes: 38 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
//! though that default may be overridden. Logger implementations typically use
//! the target to filter requests based on some user configuration.
//!
//! # Use
//! # Usage
//!
//! The basic use of the log crate is through the five logging macros: [`error!`],
//! [`warn!`], [`info!`], [`debug!`] and [`trace!`]
Expand Down Expand Up @@ -55,7 +55,7 @@
//! use log::{info, warn};
//!
//! pub fn shave_the_yak(yak: &mut Yak) {
//! info!(target: "yak_events", "Commencing yak shaving for {:?}", yak);
//! info!(target = "yak_events"; "Commencing yak shaving for {:?}", yak);
//!
//! loop {
//! match find_a_razor() {
Expand Down Expand Up @@ -86,6 +86,42 @@
//!
//! The logging system may only be initialized once.
//!
//! ## Structured logging
//!
//! If you enable the `kv_unstable` feature you can associate structured values
//! with your log records. If we take the example from before, we can include
//! some additional context besides what's in the formatted message:
//!
//! ```edition2018
//! # #[macro_use] extern crate serde;
//! # #[derive(Debug, Serialize)] pub struct Yak(String);
//! # impl Yak { fn shave(&mut self, _: u32) {} }
//! # fn find_a_razor() -> Result<u32, std::io::Error> { Ok(1) }
//! # #[cfg(feature = "kv_unstable_serde")]
//! # fn main() {
//! use log::{info, warn, as_serde, as_error};
//!
//! pub fn shave_the_yak(yak: &mut Yak) {
//! info!(target = "yak_events"; yak = as_serde!(yak); "Commencing yak shaving");
//!
//! loop {
//! match find_a_razor() {
//! Ok(razor) => {
//! info!(razor = razor; "Razor located");
//! yak.shave(razor);
//! break;
//! }
//! Err(err) => {
//! warn!(err = as_error!(err); "Unable to locate a razor, retrying");
//! }
//! }
//! }
//! }
//! # }
//! # #[cfg(not(feature = "kv_unstable_serde"))]
//! # fn main() {}
//! ```
//!
//! # Available logging implementations
//!
//! In order to produce log output executables have to use
Expand Down
106 changes: 69 additions & 37 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,21 @@
/// ```
#[macro_export(local_inner_macros)]
macro_rules! log {
(target: $target:expr, $lvl:expr, $($key:ident = $value:expr),* ; $fmt:expr, $($arg:tt)+) => ({
// log!(target = "my_target", Level::Info; key1 = 42, key2 = true; "a {} event", "log");
(target = $target:expr, $lvl:expr; $($key:ident = $value:expr),+; $($arg:tt)+) => ({
let lvl = $lvl;
if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() {
$crate::__private_api_log(
__log_format_args!($fmt, $($arg)+),
__log_format_args!($($arg)+),
lvl,
&($target, __log_module_path!(), __log_file!(), __log_line!()),
Some(&[$((__log_stringify!($key), &$value)),*])
Some(&[$((__log_stringify!($key), &$value)),+])
);
}
});
(target: $target:expr, $lvl:expr, $($arg:tt)+) => ({

// 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(
Expand All @@ -51,7 +54,18 @@ macro_rules! log {
);
}
});
($lvl:expr, $($arg:tt)+) => (log!(target: __log_module_path!(), $lvl, $($arg)+))

// log!(target: "my_target", Level::Info, "a log event")
(target: $target:expr, $lvl:expr, $($arg:tt)+) => (log!(target = $target, $lvl; $($arg)+));

// log!(target = "my_target", Level::Info; "a log event")
(target = $target:expr, $lvl:expr; $($arg:tt)+) => (log!(target = $target, $lvl; $($arg)+));

// log!(Level::Info, "a log event")
($lvl:expr, $($arg:tt)+) => (log!(target = __log_module_path!(), $lvl; $($arg)+));

// log!(Level::Info; "a log event")
($lvl:expr; $($arg:tt)+) => (log!(target = __log_module_path!(), $lvl; $($arg)+))
}

/// Logs a message at the error level.
Expand All @@ -70,12 +84,15 @@ macro_rules! log {
/// ```
#[macro_export(local_inner_macros)]
macro_rules! error {
(target: $target:expr, $($arg:tt)+) => (
log!(target: $target, $crate::Level::Error, $($arg)+)
);
($($arg:tt)+) => (
log!($crate::Level::Error, $($arg)+)
)
// 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!(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.
Expand All @@ -94,12 +111,15 @@ macro_rules! error {
/// ```
#[macro_export(local_inner_macros)]
macro_rules! warn {
(target: $target:expr, $($arg:tt)+) => (
log!(target: $target, $crate::Level::Warn, $($arg)+)
);
($($arg:tt)+) => (
log!($crate::Level::Warn, $($arg)+)
)
// 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!(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.
Expand All @@ -120,12 +140,15 @@ macro_rules! warn {
/// ```
#[macro_export(local_inner_macros)]
macro_rules! info {
(target: $target:expr, $($arg:tt)+) => (
log!(target: $target, $crate::Level::Info, $($arg)+)
);
($($arg:tt)+) => (
log!($crate::Level::Info, $($arg)+)
)
// 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!(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.
Expand All @@ -145,12 +168,15 @@ macro_rules! info {
/// ```
#[macro_export(local_inner_macros)]
macro_rules! debug {
(target: $target:expr, $($arg:tt)+) => (
log!(target: $target, $crate::Level::Debug, $($arg)+)
);
($($arg:tt)+) => (
log!($crate::Level::Debug, $($arg)+)
)
// 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!(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.
Expand All @@ -172,12 +198,15 @@ macro_rules! debug {
/// ```
#[macro_export(local_inner_macros)]
macro_rules! trace {
(target: $target:expr, $($arg:tt)+) => (
log!(target: $target, $crate::Level::Trace, $($arg)+)
);
($($arg:tt)+) => (
log!($crate::Level::Trace, $($arg)+)
)
// 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!(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
Expand Down Expand Up @@ -208,14 +237,17 @@ macro_rules! trace {
/// ```
#[macro_export(local_inner_macros)]
macro_rules! log_enabled {
(target: $target:expr, $lvl:expr) => {{
(target = $target:expr, $lvl:expr) => {{
let lvl = $lvl;
lvl <= $crate::STATIC_MAX_LEVEL
&& lvl <= $crate::max_level()
&& $crate::__private_api_enabled(lvl, $target)
}};
(target: $target:expr, $lvl:expr) => {
log_enabled!(target = $target, $lvl)
};
($lvl:expr) => {
log_enabled!(target: __log_module_path!(), $lvl)
log_enabled!(target = __log_module_path!(), $lvl)
};
}

Expand Down
3 changes: 3 additions & 0 deletions tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ std = ["log/std"]

[dependencies.log]
path = ".."

[dev-dependencies.rustversion]
version = "1.0"
Loading