common_telemetry/
macros.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/// The standard logging macro.
16#[macro_export]
17macro_rules! log {
18    // log!(target: "my_target", Level::INFO, "a {} event", "log");
19    (target: $target:expr, $lvl:expr, $($arg:tt)+) => {{
20        $crate::tracing::event!(target: $target, $lvl, $($arg)+)
21    }};
22
23    // log!(Level::INFO, "a log event")
24    ($lvl:expr, $($arg:tt)+) => {{
25        $crate::tracing::event!($lvl, $($arg)+)
26    }};
27}
28
29/// Logs a message at the error level.
30#[macro_export]
31macro_rules! error {
32    // error!(target: "my_target", "a {} event", "log")
33    (target: $target:expr, $($arg:tt)+) => ({
34        $crate::log!(target: $target, $crate::tracing::Level::ERROR, $($arg)+)
35    });
36
37    // error!(e; target: "my_target", "a {} event", "log")
38    ($e:expr; target: $target:expr, $($arg:tt)+) => ({
39        $crate::log!(
40            target: $target,
41            $crate::tracing::Level::ERROR,
42            err = ?$e,
43            $($arg)+
44        )
45    });
46
47    // error!(%e; target: "my_target", "a {} event", "log")
48    (%$e:expr; target: $target:expr, $($arg:tt)+) => ({
49        $crate::log!(
50            target: $target,
51            $crate::tracing::Level::ERROR,
52            err = %$e,
53            $($arg)+
54        )
55    });
56
57    // error!(e; "a {} event", "log")
58    ($e:expr; $($arg:tt)+) => ({
59        $crate::log!(
60            $crate::tracing::Level::ERROR,
61            err = ?$e,
62            $($arg)+
63        )
64    });
65
66    // error!(%e; "a {} event", "log")
67    (%$e:expr; $($arg:tt)+) => ({
68        $crate::log!(
69            $crate::tracing::Level::ERROR,
70            err = %$e,
71            $($arg)+
72        )
73    });
74
75    // error!("a {} event", "log")
76    ($($arg:tt)+) => ({
77        $crate::log!($crate::tracing::Level::ERROR, $($arg)+)
78    });
79}
80
81/// Logs a message at the warn level.
82#[macro_export]
83macro_rules! warn {
84    // warn!(target: "my_target", "a {} event", "log")
85    (target: $target:expr, $($arg:tt)+) => {
86        $crate::log!(target: $target, $crate::tracing::Level::WARN, $($arg)+)
87    };
88
89    // warn!(e; "a {} event", "log")
90    ($e:expr; $($arg:tt)+) => ({
91        $crate::log!(
92            $crate::tracing::Level::WARN,
93            err = ?$e,
94            $($arg)+
95        )
96    });
97
98    // warn!(%e; "a {} event", "log")
99    (%$e:expr; $($arg:tt)+) => ({
100        $crate::log!(
101            $crate::tracing::Level::WARN,
102            err = %$e,
103            $($arg)+
104        )
105    });
106
107    // warn!("a {} event", "log")
108    ($($arg:tt)+) => {
109        $crate::log!($crate::tracing::Level::WARN, $($arg)+)
110    };
111}
112
113/// Logs a message at the info level.
114#[macro_export]
115macro_rules! info {
116    // info!(target: "my_target", "a {} event", "log")
117    (target: $target:expr, $($arg:tt)+) => {
118        $crate::log!(target: $target, $crate::tracing::Level::INFO, $($arg)+)
119    };
120
121    // info!("a {} event", "log")
122    ($($arg:tt)+) => {
123        $crate::log!($crate::tracing::Level::INFO, $($arg)+)
124    };
125}
126
127/// Logs a message at the debug level.
128#[macro_export]
129macro_rules! debug {
130    // debug!(target: "my_target", "a {} event", "log")
131    (target: $target:expr, $($arg:tt)+) => {
132        $crate::log!(target: $target, $crate::tracing::Level::DEBUG, $($arg)+)
133    };
134
135    // debug!("a {} event", "log")
136    ($($arg:tt)+) => {
137        $crate::log!($crate::tracing::Level::DEBUG, $($arg)+)
138    };
139}
140
141/// Logs a message at the trace level.
142#[macro_export]
143macro_rules! trace {
144    // trace!(target: "my_target", "a {} event", "log")
145    (target: $target:expr, $($arg:tt)+) => {
146        $crate::log!(target: $target, $crate::tracing::Level::TRACE, $($arg)+)
147    };
148
149    // trace!("a {} event", "log")
150    ($($arg:tt)+) => {
151        $crate::log!($crate::tracing::Level::TRACE, $($arg)+)
152    };
153}
154
155#[macro_export]
156macro_rules! slow {
157    (target: $target:expr, $($arg:tt)+) => {
158        $crate::log!(target: $target, slow = true, $crate::tracing::Level::INFO, $($arg)+)
159    };
160
161    ($($arg:tt)+) => {
162        $crate::log!($crate::tracing::Level::INFO, slow = true, $($arg)+)
163    };
164}
165
166#[cfg(test)]
167mod tests {
168    use common_error::mock::MockError;
169    use common_error::status_code::StatusCode;
170    use tracing::Level;
171
172    macro_rules! all_log_macros {
173        ($($arg:tt)*) => {
174            trace!($($arg)*);
175            debug!($($arg)*);
176            info!($($arg)*);
177            warn!($($arg)*);
178            error!($($arg)*);
179        };
180    }
181
182    #[test]
183    fn test_log_args() {
184        log!(target: "my_target", Level::TRACE, "foo");
185        log!(target: "my_target", Level::DEBUG, "foo",);
186
187        log!(target: "my_target", Level::INFO, "foo: {}", 3);
188        log!(target: "my_target", Level::WARN, "foo: {}", 3,);
189
190        log!(target: "my_target", Level::ERROR, "hello {world}", world = "world");
191        log!(target: "my_target", Level::DEBUG, "hello {world}", world = "world",);
192
193        all_log_macros!(target: "my_target", "foo");
194        all_log_macros!(target: "my_target", "foo",);
195
196        all_log_macros!(target: "my_target", "foo: {}", 3);
197        all_log_macros!(target: "my_target", "foo: {}", 3,);
198
199        all_log_macros!(target: "my_target", "hello {world}", world = "world");
200        all_log_macros!(target: "my_target", "hello {world}", world = "world",);
201    }
202
203    #[test]
204    fn test_log_no_target() {
205        log!(Level::DEBUG, "foo");
206        log!(Level::DEBUG, "foo: {}", 3);
207
208        all_log_macros!("foo");
209        all_log_macros!("foo: {}", 3);
210    }
211
212    #[test]
213    fn test_log_ref_scope_args() {
214        let bar = 35;
215        let world = "world";
216        log!(target: "my_target", Level::DEBUG, "bar: {bar}");
217        log!(target: "my_target", Level::DEBUG, "bar: {bar}, hello {}", world);
218        log!(target: "my_target", Level::DEBUG, "bar: {bar}, hello {world}",);
219
220        all_log_macros!(target: "my_target", "bar: {bar}");
221        all_log_macros!(target: "my_target", "bar: {bar}, hello {}", world);
222        all_log_macros!(target: "my_target", "bar: {bar}, hello {world}",);
223    }
224
225    #[test]
226    fn test_log_error() {
227        crate::init_default_ut_logging();
228
229        let err = MockError::new(StatusCode::Unknown);
230        let err_ref = &err;
231        let err_ref2 = &err_ref;
232
233        error!(target: "my_target", "hello {}", "world");
234        // Supports both owned and reference type.
235        error!(err; target: "my_target", "hello {}", "world");
236        error!(%err; target: "my_target", "hello {}", "world");
237        error!(err_ref; target: "my_target", "hello {}", "world");
238        error!(err_ref2; "hello {}", "world");
239        error!(%err_ref2; "hello {}", "world");
240        error!("hello {}", "world");
241
242        let root_err = MockError::with_source(err);
243        error!(root_err; "Error with source hello {}", "world");
244    }
245}