captains_log/
macros.rs

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