Skip to main content

log_io/
macros.rs

1//! Convenience macros.
2//!
3//! Each macro takes a [`crate::Logger`] expression and produces a log
4//! call. Fields use a `key = expr` syntax; the expression must produce
5//! a value convertible to [`crate::Value`].
6//!
7//! All macros capture the caller's source location ([`file!`],
8//! [`line!`]) and module path ([`module_path!`]) and attach them to
9//! the record's [`crate::Metadata`].
10//!
11//! # Example
12//!
13//! ```
14//! use log_io::{Level, Logger};
15//!
16//! let logger = Logger::builder()
17//!     .level(Level::Info)
18//!     .no_timestamps()
19//!     .no_context()
20//!     .with_sink(log_io::sink::NullSink::new())
21//!     .build();
22//!
23//! log_io::info!(logger, "request handled", port = 8080_u32, ok = true);
24//! ```
25
26/// Emit a log record at the given level.
27///
28/// The first argument is a `Logger` (by reference or by value). The
29/// second is the level. The third is the message string. Any number
30/// of `key = expr` pairs may follow.
31#[macro_export]
32macro_rules! log_at {
33    ($logger:expr, $level:expr, $msg:expr $(,)?) => {{
34        let __logger = &$logger;
35        let __level: $crate::Level = $level;
36        if __logger.enabled(::core::module_path!(), __level) {
37            let __fields: [$crate::Field<'_>; 0] = [];
38            let __metadata = $crate::Metadata::new(__level, ::core::module_path!())
39                .with_location(::core::file!(), ::core::line!());
40            let _ = __logger.try_emit(__metadata, $msg, &__fields);
41        }
42    }};
43    ($logger:expr, $level:expr, $msg:expr, $($key:ident = $value:expr),+ $(,)?) => {{
44        let __logger = &$logger;
45        let __level: $crate::Level = $level;
46        if __logger.enabled(::core::module_path!(), __level) {
47            let __fields = [
48                $(
49                    $crate::Field::new(stringify!($key), $crate::Value::from($value)),
50                )+
51            ];
52            let __metadata = $crate::Metadata::new(__level, ::core::module_path!())
53                .with_location(::core::file!(), ::core::line!());
54            let _ = __logger.try_emit(__metadata, $msg, &__fields);
55        }
56    }};
57}
58
59/// Emit a [`crate::Level::Trace`] record.
60#[macro_export]
61macro_rules! trace {
62    ($logger:expr, $($rest:tt)*) => {
63        $crate::log_at!($logger, $crate::Level::Trace, $($rest)*)
64    };
65}
66
67/// Emit a [`crate::Level::Debug`] record.
68#[macro_export]
69macro_rules! debug {
70    ($logger:expr, $($rest:tt)*) => {
71        $crate::log_at!($logger, $crate::Level::Debug, $($rest)*)
72    };
73}
74
75/// Emit a [`crate::Level::Info`] record.
76#[macro_export]
77macro_rules! info {
78    ($logger:expr, $($rest:tt)*) => {
79        $crate::log_at!($logger, $crate::Level::Info, $($rest)*)
80    };
81}
82
83/// Emit a [`crate::Level::Warn`] record.
84///
85/// Despite the name colliding with the `warn` attribute, this macro
86/// works in expression position the same way `log::warn!` does in the
87/// upstream `log` crate.
88#[macro_export]
89macro_rules! warn {
90    ($logger:expr, $($rest:tt)*) => {
91        $crate::log_at!($logger, $crate::Level::Warn, $($rest)*)
92    };
93}
94
95/// Emit a [`crate::Level::Error`] record.
96#[macro_export]
97macro_rules! error {
98    ($logger:expr, $($rest:tt)*) => {
99        $crate::log_at!($logger, $crate::Level::Error, $($rest)*)
100    };
101}