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", "Successful 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