Skip to main content

captains_log/
macros.rs

1#[macro_export]
2macro_rules! do_log_filter {
3    (target: $target:expr, $log_filter:expr, $lvl:expr, $($arg:tt)+) => ({
4        {
5            use captains_log::filter::Filter;
6            if $lvl <= log::STATIC_MAX_LEVEL && $lvl <= log::max_level() && $log_filter.is_enabled($lvl) {
7                $log_filter._private_api_log(
8                    std::format_args!($($arg)+),
9                    $lvl,
10                    &($target, std::module_path!(), std::file!(), std::line!()),
11                );
12            }
13        }
14    });
15    ($log_filter:expr, $lvl:expr, $($arg:tt)+) => (do_log_filter!(target: std::module_path!(), $log_filter, $lvl, $($arg)+))
16}
17#[allow(unused_imports)]
18pub(super) use do_log_filter;
19
20/// Similar to [error!()](log::error!()), but the first argument is [LogFilter](crate::filter::LogFilter) or
21/// [KeyFilter](crate::filter::KeyFilter).
22#[macro_export]
23macro_rules! logger_error {
24    ($log_filter:expr, $($arg:tt)+) => (
25        do_log_filter!($log_filter, log::Level::Error, $($arg)+);
26    )
27}
28#[allow(unused_imports)]
29pub(super) use logger_error;
30
31/// Similar to [warn!()](log::warn!()), but the first argument is [LogFilter](crate::filter::LogFilter) or
32/// [KeyFilter](crate::filter::KeyFilter).
33#[macro_export]
34macro_rules! logger_warn {
35    ($log_filter:expr, $($arg:tt)+) => (
36        do_log_filter!($log_filter, log::Level::Warn, $($arg)+);
37    )
38}
39#[allow(unused_imports)]
40pub(super) use logger_warn;
41
42/// Similar to [info!()](log::info!()), but the first argument is [LogFilter](crate::filter::LogFilter) or
43/// [KeyFilter](crate::filter::KeyFilter).
44#[macro_export]
45macro_rules! logger_info {
46    ($log_filter:expr, $($arg:tt)+) => (
47        do_log_filter!($log_filter, log::Level::Info, $($arg)+);
48    )
49}
50#[allow(unused_imports)]
51pub(super) use logger_info;
52
53/// Similar to [debug!()](log::debug!()), but the first argument is [LogFilter](crate::filter::LogFilter) or
54/// [KeyFilter](crate::filter::KeyFilter)
55#[macro_export]
56macro_rules! logger_debug {
57    ($log_filter:expr, $($arg:tt)+) => (
58        do_log_filter!($log_filter, log::Level::Debug, $($arg)+);
59    )
60}
61#[allow(unused_imports)]
62pub(super) use logger_debug;
63
64/// Similar to [trace!()](log::trace!()), but the first argument is [LogFilter](crate::filter::LogFilter) or
65/// [KeyFilter](crate::filter::KeyFilter)
66#[macro_export]
67macro_rules! logger_trace {
68    ($log_filter:expr, $($arg:tt)+) => (
69        do_log_filter!($log_filter, log::Level::Trace, $($arg)+);
70    )
71}
72#[allow(unused_imports)]
73pub(super) use logger_trace;
74
75/// On debug build, will log with log_filter and panic when condition not met. Skip the check on
76/// release build.
77///
78/// The first argument is [LogFilter](crate::filter::LogFilter) or [KeyFilter](crate::filter::KeyFilter), the rest arguments are like [core::debug_assert!()].
79///
80/// # Examples:
81///
82/// ``` rust
83/// use captains_log::*;
84/// let logger = filter::KeyFilter::new("req_id", format!("{:016x}", 123).to_string());
85/// let started = true;
86/// logger_debug_assert!(logger, started);
87/// logger_debug_assert!(logger, started, "job must have been started");
88/// ```
89#[macro_export]
90macro_rules! logger_debug_assert {
91    ($log_filter:expr, $($arg:tt)*) => (if std::cfg!(debug_assertions) { $crate::logger_assert!($log_filter, $($arg)*); });
92}
93#[allow(unused_imports)]
94pub(super) use logger_debug_assert;
95
96/// On debug build, will log with log_filter and panic when condition not met. Skip the check on
97/// release build.
98///
99/// The first argument is [LogFilter](crate::filter::LogFilter) or [KeyFilter](crate::filter::KeyFilter), the rest arguments are like [core::debug_assert_eq!()].
100///
101/// # Examples:
102///
103/// ``` rust
104/// use captains_log::*;
105/// let logger = filter::KeyFilter::new("req_id", format!("{:016x}", 123).to_string());
106/// logger_debug_assert_eq!(logger, 1, 1);
107/// logger_debug_assert_eq!(logger, 1, 1, "impossible things happened: {}", "haha");
108/// ```
109#[macro_export]
110macro_rules! logger_debug_assert_eq {
111    ($log_filter:expr, $($arg:tt)*) => (if std::cfg!(debug_assertions) { $crate::logger_assert_eq!($log_filter, $($arg)*); })
112}
113#[allow(unused_imports)]
114pub(super) use logger_debug_assert_eq;
115
116/// Will log with log_filter and panic when condition not met.
117///
118/// The first argument is [LogFilter](crate::filter::LogFilter) or [KeyFilter](crate::filter::KeyFilter), the rest arguments are like [core::assert!()].
119///
120/// # Examples:
121///
122/// ``` rust
123/// use captains_log::*;
124/// let logger = filter::KeyFilter::new("req_id", format!("{:016x}", 123).to_string());
125/// let user_id = Some(111);
126/// logger_assert!(logger, user_id.is_some());
127/// logger_assert!(logger, user_id.is_some(), "user must login");
128/// ```
129#[macro_export]
130macro_rules! logger_assert {
131    ($log_filter:expr, $cond:expr) => ({
132        if !$cond {
133            do_log_filter!(
134                $log_filter,
135                log::Level::Error,
136                "assertion failed: {:?}",
137                $cond
138            );
139            std::panic!(r#"assertion failed: {:?}"#, $cond);
140        }
141    });
142    ($log_filter:expr, $cond:expr,) => ({
143        $crate::logger_assert!($log_filter, $cond);
144    });
145    ($log_filter:expr, $cond:expr, $($arg:tt)+) => ({
146        if !$cond {
147            do_log_filter!(
148                $log_filter,
149                log::Level::Error,
150                "assertion failed: {}",
151                std::format_args!($($arg)+)
152            );
153            std::panic!(r#"{}"#, std::format_args!($($arg)+));
154        }
155    });
156}
157#[allow(unused_imports)]
158pub(super) use logger_assert;
159
160/// Will log with log_filter and panic when condition not met.
161///
162/// The first argument is [LogFilter](crate::filter::LogFilter) or [KeyFilter](crate::filter::KeyFilter), the rest arguments are like [core::assert_eq!()].
163///
164/// # Examples:
165///
166/// ``` rust
167/// use captains_log::*;
168/// let logger = filter::KeyFilter::new("req_id", format!("{:016x}", 123).to_string());
169/// logger_assert_eq!(logger, 1, 1);
170/// logger_assert_eq!(logger, 1, 1, "impossible things happened");
171/// ```
172#[macro_export]
173macro_rules! logger_assert_eq {
174    ($log_filter:expr, $left:expr, $right:expr) => ({
175        match (&$left, &$right) {
176            (left_val, right_val) => {
177                if !(*left_val == *right_val) {
178                    do_log_filter!($log_filter, log::Level::Error, "assertion failed! \
179                    expected: (`left == right`) actual: (`{:?}` != `{:?}`)", &*left_val, &*right_val);
180                    std::panic!(r#"assertion failed: `(left == right)`
181  left: `{:?}`,
182 right: `{:?}`"#, &*left_val, &*right_val);
183                }
184            }
185        }
186    });
187    ($log_filter:expr, $left:expr, $right:expr,) => ({
188        $crate::logger_assert_eq!($log_filter, $left, $right);
189    });
190    ($log_filter:expr, $left:expr, $right:expr, $($arg:tt)+) => ({
191        match (&($left), &($right)) {
192            (left_val, right_val) => {
193                if !(*left_val == *right_val) {
194                    do_log_filter!($log_filter, log::Level::Error, "assertion failed! \
195                    expected: `(left == right)` actual: (`{:?}` != `{:?}`)", &*left_val, &*right_val);
196                    std::panic!(r#"assertion failed: `(left == right)`
197  left: `{:?}`,
198 right: `{:?}`: {}"#, &*left_val, &*right_val,
199                           std::format_args!($($arg)+));
200                }
201            }
202        }
203    });
204}
205#[allow(unused_imports)]
206pub(super) use logger_assert_eq;
207
208/// On Debug build, will log and panic when condition not met. Skip the check on
209/// release build.
210///
211/// The arguments are like [core::debug_assert!()].
212///
213/// # Examples:
214///
215/// ``` rust
216/// use captains_log::*;
217/// let user_id = Some(111);
218/// log_debug_assert!(user_id.is_some());
219/// log_debug_assert!(user_id.is_some(), "user must login");
220/// ```
221#[macro_export]
222macro_rules! log_debug_assert {
223    ($($arg:tt)*) => (if std::cfg!(debug_assertions) { $crate::log_assert!($($arg)*); });
224}
225#[allow(unused_imports)]
226pub(super) use log_debug_assert;
227
228/// On Debug build, will log and panic when condition not met. Skip the check on
229/// release build.
230///
231/// The arguments are like [core::debug_assert_eq!()].
232///
233/// # Examples:
234///
235/// ``` rust
236/// use captains_log::*;
237/// log_debug_assert_eq!(1, 1);
238/// log_debug_assert_eq!(1, 1, "impossible things happened");
239/// ```
240#[macro_export]
241macro_rules! log_debug_assert_eq {
242    ($($arg:tt)*) => (if std::cfg!(debug_assertions) { $crate::log_assert_eq!($($arg)*); })
243}
244#[allow(unused_imports)]
245pub(super) use log_debug_assert_eq;
246
247/// Will log and panic when condition not met.
248///
249/// The arguments are like [core::assert!()].
250///
251/// # Examples:
252///
253/// ``` rust
254/// use captains_log::*;
255/// let user_id = Some(111);
256/// log_assert!(user_id.is_some());
257/// log_assert!(user_id.is_some(), "user must login");
258/// ```
259#[macro_export]
260macro_rules! log_assert {
261    ($cond:expr) => ({
262        if !$cond {
263            log::error!(
264                "assertion failed: {:?}",
265                $cond
266            );
267            std::panic!(r#"assertion failed: {:?}"#, $cond);
268        }
269    });
270    ($cond:expr,) => ({
271        $crate::log_assert!($log_filter, $cond);
272    });
273    ($cond:expr, $($arg:tt)+) => ({
274        if !$cond {
275            log::error!(
276                "assertion failed: {}",
277                std::format_args!($($arg)+)
278            );
279            std::panic!(r#"{}"#, std::format_args!($($arg)+));
280        }
281    });
282}
283#[allow(unused_imports)]
284pub(super) use log_assert;
285
286/// Will log and panic when condition not met.
287///
288/// The arguments are like [core::assert_eq!()].
289///
290/// # Examples:
291///
292/// ``` rust
293/// use captains_log::*;
294/// log_assert_eq!(1, 1);
295/// log_assert_eq!(1, 1, "impossible things happened");
296/// ```
297#[macro_export]
298macro_rules! log_assert_eq {
299    ($left:expr, $right:expr) => ({
300        match (&$left, &$right) {
301            (left_val, right_val) => {
302                if !(*left_val == *right_val) {
303                    log::error!("assertion failed! \
304                    expected: (`left == right`) actual: (`{:?}` != `{:?}`)", &*left_val, &*right_val);
305                    std::panic!(r#"assertion failed: `(left == right)`
306  left: `{:?}`,
307 right: `{:?}`"#, &*left_val, &*right_val);
308                }
309            }
310        }
311    });
312    ($left:expr, $right:expr,) => ({
313        $crate::log_assert_eq!($left, $right);
314    });
315    ($left:expr, $right:expr, $($arg:tt)+) => ({
316        match (&($left), &($right)) {
317            (left_val, right_val) => {
318                if !(*left_val == *right_val) {
319                    log::error!( "assertion failed! \
320                    expected: `(left == right)` actual: (`{:?}` != `{:?}`)", &*left_val, &*right_val);
321                    std::panic!(r#"assertion failed: `(left == right)`
322  left: `{:?}`,
323 right: `{:?}`: {}"#, &*left_val, &*right_val,
324                           std::format_args!($($arg)+));
325                }
326            }
327        }
328    });
329}
330
331#[allow(unused_imports)]
332pub(super) use log_assert_eq;
333
334/// log and println to stdout.
335///
336/// The usage is similar to [std::println!()]
337#[macro_export]
338macro_rules! log_println {
339    ($($arg:tt)+) => {
340        std::println!($($arg)+);
341        log::info!($($arg)+);
342    }
343}
344#[allow(unused_imports)]
345pub(super) use log_println;
346
347/// log and println to stderr.
348///
349/// The usage is similar to [std::eprintln!()]
350#[macro_export]
351macro_rules! log_eprintln {
352    ($($arg:tt)+) => {
353        std::eprintln!($($arg)+);
354        log::info!($($arg)+);
355    }
356}
357#[allow(unused_imports)]
358pub(super) use log_eprintln;