xref: /third_party/rust/crates/log/src/macros.rs (revision 2d8ae3ab)
1// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11/// The standard logging macro.
12///
13/// This macro will generically log with the specified `Level` and `format!`
14/// based argument list.
15///
16/// # Examples
17///
18/// ```edition2018
19/// use log::{log, Level};
20///
21/// # fn main() {
22/// let data = (42, "Forty-two");
23/// let private_data = "private";
24///
25/// log!(Level::Error, "Received errors: {}, {}", data.0, data.1);
26/// log!(target: "app_events", Level::Warn, "App warning: {}, {}, {}",
27///     data.0, data.1, private_data);
28/// # }
29/// ```
30#[macro_export(local_inner_macros)]
31macro_rules! log {
32    // log!(target: "my_target", Level::Info; key1 = 42, key2 = true; "a {} event", "log");
33    (target: $target:expr, $lvl:expr, $($key:tt = $value:expr),+; $($arg:tt)+) => ({
34        let lvl = $lvl;
35        if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() {
36            $crate::__private_api_log(
37                __log_format_args!($($arg)+),
38                lvl,
39                &($target, __log_module_path!(), __log_file!(), __log_line!()),
40                $crate::__private_api::Option::Some(&[$((__log_key!($key), &$value)),+])
41            );
42        }
43    });
44
45    // log!(target: "my_target", Level::Info; "a {} event", "log");
46    (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({
47        let lvl = $lvl;
48        if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() {
49            $crate::__private_api_log(
50                __log_format_args!($($arg)+),
51                lvl,
52                &($target, __log_module_path!(), __log_file!(), __log_line!()),
53                $crate::__private_api::Option::None,
54            );
55        }
56    });
57
58    // log!(Level::Info, "a log event")
59    ($lvl:expr, $($arg:tt)+) => (log!(target: __log_module_path!(), $lvl, $($arg)+));
60}
61
62/// Logs a message at the error level.
63///
64/// # Examples
65///
66/// ```edition2018
67/// use log::error;
68///
69/// # fn main() {
70/// let (err_info, port) = ("No connection", 22);
71///
72/// error!("Error: {} on port {}", err_info, port);
73/// error!(target: "app_events", "App Error: {}, Port: {}", err_info, 22);
74/// # }
75/// ```
76#[macro_export(local_inner_macros)]
77macro_rules! error {
78    // error!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
79    // error!(target: "my_target", "a {} event", "log")
80    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Error, $($arg)+));
81
82    // error!("a {} event", "log")
83    ($($arg:tt)+) => (log!($crate::Level::Error, $($arg)+))
84}
85
86/// Logs a message at the warn level.
87///
88/// # Examples
89///
90/// ```edition2018
91/// use log::warn;
92///
93/// # fn main() {
94/// let warn_description = "Invalid Input";
95///
96/// warn!("Warning! {}!", warn_description);
97/// warn!(target: "input_events", "App received warning: {}", warn_description);
98/// # }
99/// ```
100#[macro_export(local_inner_macros)]
101macro_rules! warn {
102    // warn!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
103    // warn!(target: "my_target", "a {} event", "log")
104    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Warn, $($arg)+));
105
106    // warn!("a {} event", "log")
107    ($($arg:tt)+) => (log!($crate::Level::Warn, $($arg)+))
108}
109
110/// Logs a message at the info level.
111///
112/// # Examples
113///
114/// ```edition2018
115/// use log::info;
116///
117/// # fn main() {
118/// # struct Connection { port: u32, speed: f32 }
119/// let conn_info = Connection { port: 40, speed: 3.20 };
120///
121/// info!("Connected to port {} at {} Mb/s", conn_info.port, conn_info.speed);
122/// info!(target: "connection_events", "Successfull connection, port: {}, speed: {}",
123///       conn_info.port, conn_info.speed);
124/// # }
125/// ```
126#[macro_export(local_inner_macros)]
127macro_rules! info {
128    // info!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
129    // info!(target: "my_target", "a {} event", "log")
130    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Info, $($arg)+));
131
132    // info!("a {} event", "log")
133    ($($arg:tt)+) => (log!($crate::Level::Info, $($arg)+))
134}
135
136/// Logs a message at the debug level.
137///
138/// # Examples
139///
140/// ```edition2018
141/// use log::debug;
142///
143/// # fn main() {
144/// # struct Position { x: f32, y: f32 }
145/// let pos = Position { x: 3.234, y: -1.223 };
146///
147/// debug!("New position: x: {}, y: {}", pos.x, pos.y);
148/// debug!(target: "app_events", "New position: x: {}, y: {}", pos.x, pos.y);
149/// # }
150/// ```
151#[macro_export(local_inner_macros)]
152macro_rules! debug {
153    // debug!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
154    // debug!(target: "my_target", "a {} event", "log")
155    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Debug, $($arg)+));
156
157    // debug!("a {} event", "log")
158    ($($arg:tt)+) => (log!($crate::Level::Debug, $($arg)+))
159}
160
161/// Logs a message at the trace level.
162///
163/// # Examples
164///
165/// ```edition2018
166/// use log::trace;
167///
168/// # fn main() {
169/// # struct Position { x: f32, y: f32 }
170/// let pos = Position { x: 3.234, y: -1.223 };
171///
172/// trace!("Position is: x: {}, y: {}", pos.x, pos.y);
173/// trace!(target: "app_events", "x is {} and y is {}",
174///        if pos.x >= 0.0 { "positive" } else { "negative" },
175///        if pos.y >= 0.0 { "positive" } else { "negative" });
176/// # }
177/// ```
178#[macro_export(local_inner_macros)]
179macro_rules! trace {
180    // trace!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log")
181    // trace!(target: "my_target", "a {} event", "log")
182    (target: $target:expr, $($arg:tt)+) => (log!(target: $target, $crate::Level::Trace, $($arg)+));
183
184    // trace!("a {} event", "log")
185    ($($arg:tt)+) => (log!($crate::Level::Trace, $($arg)+))
186}
187
188/// Determines if a message logged at the specified level in that module will
189/// be logged.
190///
191/// This can be used to avoid expensive computation of log message arguments if
192/// the message would be ignored anyway.
193///
194/// # Examples
195///
196/// ```edition2018
197/// use log::Level::Debug;
198/// use log::{debug, log_enabled};
199///
200/// # fn foo() {
201/// if log_enabled!(Debug) {
202///     let data = expensive_call();
203///     debug!("expensive debug data: {} {}", data.x, data.y);
204/// }
205/// if log_enabled!(target: "Global", Debug) {
206///    let data = expensive_call();
207///    debug!(target: "Global", "expensive debug data: {} {}", data.x, data.y);
208/// }
209/// # }
210/// # struct Data { x: u32, y: u32 }
211/// # fn expensive_call() -> Data { Data { x: 0, y: 0 } }
212/// # fn main() {}
213/// ```
214#[macro_export(local_inner_macros)]
215macro_rules! log_enabled {
216    (target: $target:expr, $lvl:expr) => {{
217        let lvl = $lvl;
218        lvl <= $crate::STATIC_MAX_LEVEL
219            && lvl <= $crate::max_level()
220            && $crate::__private_api_enabled(lvl, $target)
221    }};
222    ($lvl:expr) => {
223        log_enabled!(target: __log_module_path!(), $lvl)
224    };
225}
226
227// The log macro above cannot invoke format_args directly because it uses
228// local_inner_macros. A format_args invocation there would resolve to
229// $crate::format_args which does not exist. Instead invoke format_args here
230// outside of local_inner_macros so that it resolves (probably) to
231// core::format_args or std::format_args. Same for the several macros that
232// follow.
233//
234// This is a workaround until we drop support for pre-1.30 compilers. At that
235// point we can remove use of local_inner_macros, use $crate:: when invoking
236// local macros, and invoke format_args directly.
237#[doc(hidden)]
238#[macro_export]
239macro_rules! __log_format_args {
240    ($($args:tt)*) => {
241        format_args!($($args)*)
242    };
243}
244
245#[doc(hidden)]
246#[macro_export]
247macro_rules! __log_module_path {
248    () => {
249        module_path!()
250    };
251}
252
253#[doc(hidden)]
254#[macro_export]
255macro_rules! __log_file {
256    () => {
257        file!()
258    };
259}
260
261#[doc(hidden)]
262#[macro_export]
263macro_rules! __log_line {
264    () => {
265        line!()
266    };
267}
268
269#[doc(hidden)]
270#[macro_export]
271macro_rules! __log_key {
272    // key1 = 42
273    ($($args:ident)*) => {
274        stringify!($($args)*)
275    };
276    // "key1" = 42
277    ($($args:expr)*) => {
278        $($args)*
279    };
280}
281