• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 //! `pw_log` is an extensible logging system that can delegate to
16 //! pre-existing logging APIs without upstream changes.
17 //!
18 //! Clients of `pw_log` simply import and use the logging API, and
19 //! log invocations will be handled by the provided logging backend.
20 //!
21 //! This flexibility is accomplished using Pigweed's
22 //! [facade pattern](https://pigweed.dev/docs/facades.html),
23 //! which uses build-system redirection to forward log invocations to the
24 //! configured backend implementation.
25 //!
26 //! ```
27 //! use pw_log::{log, info, LogLevel};
28 //!
29 //! log!(LogLevel::Info, "Thank you for signing up for Log Facts!");
30 //! info!("Log Fact: Logs can be either {}, {}, or {} sawn.",
31 //!   "flat" as &str, "quarter" as &str, "rift" as &str);
32 //! ```
33 //!
34 //! Today `printf` style format strings are well supported with Rust
35 //! [`core::fmt`]/`println!()` style strings partially supported
36 //! ([b/311232607](https://issues.pigweed.dev/issues/311232607)).
37 //!
38 //! Currently, when using a `stable` toolchain, "untyped" arguments (i.e.
39 //! `{}` style) need to be in the form of an as-cast.  Users with nightly
40 //! toolchains can enable the `nightly_tait` feature to remove this restriction.
41 //!
42 //! TODO: <pwbug.dev/311266298> - Document `pw_log`'s backend API.
43 //!
44 //! TODO: <pwbug.dev/311232605> - Document how to configure facade backends.
45 #![cfg_attr(not(feature = "std"), no_std)]
46 #![deny(missing_docs)]
47 
48 pub use pw_log_backend_api::LogLevel;
49 
50 // Re-export dependencies of `pw_log` macros to be accessed via `$crate::__private`.
51 #[doc(hidden)]
52 pub mod __private {
53     pub use crate::*;
54     pub use pw_log_backend::{pw_log_backend, pw_logf_backend};
55 }
56 
57 /// Emit a log message using `core::fmt` format string semantics.
58 ///
59 /// `log` takes a [`LogLevel`], a `core::fmt` style format string, and necessary
60 /// arguments to that string and emits a log message to the logging backend.
61 ///
62 /// ```
63 /// use pw_log::{log, LogLevel};
64 ///
65 /// log!(LogLevel::Info, "Log fact: A {} log has a Janka hardness of {} lbf.",
66 ///      "Spruce Pine" as &str, 700 as i32);
67 /// ```
68 #[macro_export]
69 macro_rules! log {
70   ($log_level:expr, $format_string:literal) => {{
71     use $crate::__private as __pw_log_crate;
72     $crate::__private::pw_log_backend!($log_level, $format_string)
73   }};
74 
75   ($log_level:expr, $format_string:literal, $($args:expr),*) => {{
76     use $crate::__private as __pw_log_crate;
77     $crate::__private::pw_log_backend!($log_level, $format_string, $($args),*)
78   }};
79 }
80 
81 /// Emit a log message using `printf` format string semantics.
82 ///
83 /// `logf` takes a [`LogLevel`], a `printf` style format string, and necessary
84 /// arguments to that string and emits a log message to the logging backend.
85 ///
86 /// ```
87 /// use pw_log::{logf, LogLevel};
88 ///
89 /// logf!(LogLevel::Info, "Log fact: A %s log has a Janka hardness of %d lbf.",
90 ///     "Spruce Pine", 700);
91 /// ```
92 #[macro_export]
93 macro_rules! logf {
94   ($log_level:expr, $format_string:literal) => {{
95     use $crate::__private as __pw_log_crate;
96     $crate::__private::pw_logf_backend!($log_level, $format_string)
97   }};
98 
99   ($log_level:expr, $format_string:literal, $($args:expr),*) => {{
100     use $crate::__private as __pw_log_crate;
101     $crate::__private::pw_logf_backend!($log_level, $format_string, $($args),*)
102   }};
103 }
104 
105 /// Deprecated alias for [`logf!`].
106 #[macro_export]
107 macro_rules! pw_logf {
108   ($($args:expr),*) => {{
109     logf!($($args),*)
110   }}
111 }
112 
113 /// Emit a debug level log message using `core:fmt` format string semantics.
114 ///
115 /// ```
116 /// use pw_log::debug;
117 ///
118 /// debug!("Log Fact: The American toy Lincoln Logs were inspired by the {} in {}.",
119 ///     "Imperial Hotel" as &str, "Tokyo" as &str);
120 /// ```
121 #[macro_export]
122 macro_rules! debug {
123   ($($args:expr),*) => {{
124     use $crate::__private as __pw_log_crate;
125     __pw_log_crate::log!(__pw_log_crate::LogLevel::Debug, $($args),*)
126   }};
127 }
128 
129 /// Emit a debug level log message using `printf` format string semantics.
130 ///
131 /// ```
132 /// use pw_log::debugf;
133 ///
134 /// debugf!("Log Fact: The American toy Lincoln Logs were inspired by the %s in %s.",
135 ///     "Imperial Hotel", "Tokyo");
136 /// ```
137 #[macro_export]
138 macro_rules! debugf {
139   ($($args:expr),*) => {{
140     use $crate::__private as __pw_log_crate;
141     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Debug, $($args),*)
142   }};
143 }
144 
145 /// Deprecated alias for [`debugf!`].
146 #[macro_export]
147 macro_rules! pw_log_debugf {
148   ($($args:expr),*) => {{
149     debugf!($($args),*)
150   }}
151 }
152 
153 /// Emit an info level log message using `core:fmt` format string semantics.
154 ///
155 /// ```
156 /// use pw_log::info;
157 ///
158 /// info!(
159 ///     "Log Fact: The American president Abraham Lincoln (born {:x}) once lived in a log cabin.",
160 ///     0x1809 as u32);
161 /// ```
162 #[macro_export]
163 macro_rules! info {
164   ($($args:expr),*) => {{
165     use $crate::__private as __pw_log_crate;
166     __pw_log_crate::log!(__pw_log_crate::LogLevel::Info, $($args),*)
167   }};
168 }
169 
170 /// Emit an info level log message using `printf` format string semantics.
171 ///
172 /// ```
173 /// use pw_log::infof;
174 ///
175 /// infof!(
176 ///     "Log Fact: The American president Abraham Lincoln (born %x) once lived in a log cabin.",
177 /// 0x1809);
178 /// ```
179 #[macro_export]
180 macro_rules! infof {
181   ($($args:expr),*) => {{
182     use $crate::__private as __pw_log_crate;
183     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Info, $($args),*)
184   }};
185 }
186 
187 /// Deprecated alias for [`infof!`].
188 #[macro_export]
189 macro_rules! pw_log_infof {
190   ($($args:expr),*) => {{
191     infof!($($args),*)
192   }}
193 }
194 
195 /// Emit a warn level log message using `core::fmt` format string semantics.
196 ///
197 /// ```
198 /// use pw_log::warn;
199 ///
200 /// warn!(
201 ///     "Log Fact: Made from a log, an {} year old dugout canoe is the oldest discovered boat in {}.",
202 ///     8000 as i32, "Africa" as &str);
203 /// ```
204 #[macro_export]
205 macro_rules! warn {
206   ($($args:expr),*) => {{
207     use $crate::__private as __pw_log_crate;
208     __pw_log_crate::log!(__pw_log_crate::LogLevel::Warn, $($args),*)
209   }};
210 }
211 
212 /// Emit a warn level log message using `printf` format string semantics.
213 ///
214 /// ```
215 /// use pw_log::warnf;
216 ///
217 /// warnf!(
218 ///     "Log Fact: Made from a log, an %d year old dugout canoe is the oldest discovered boat in %s.",
219 ///     8000, "Africa");
220 /// ```
221 #[macro_export]
222 macro_rules! warnf {
223   ($($args:expr),*) => {{
224     use $crate::__private as __pw_log_crate;
225     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Warn, $($args),*)
226   }};
227 }
228 
229 /// Deprecated alias for [`warnf!`].
230 #[macro_export]
231 macro_rules! pw_log_warnf {
232   ($($args:expr),*) => {{
233     warnf!($($args),*)
234   }}
235 }
236 
237 /// Emit an error level log message using `core::fmt` format string semantics.
238 ///
239 /// ```
240 /// use pw_log::error;
241 ///
242 /// error!(
243 ///     "Log Fact: Before saws were invented, the {} was used prepare logs for use.",
244 ///     "adze" as &str);
245 /// ```
246 #[macro_export]
247 macro_rules! error {
248   ($($args:expr),*) => {{
249     use $crate::__private as __pw_log_crate;
250     __pw_log_crate::log!(__pw_log_crate::LogLevel::Error, $($args),*)
251   }};
252 }
253 
254 /// Emit an error level log message using `printf` format string semantics.
255 ///
256 /// ```
257 /// use pw_log::errorf;
258 ///
259 /// errorf!(
260 ///     "Log Fact: Before saws were invented, the %s was used prepare logs for use.",
261 ///     "adze");
262 /// ```
263 #[macro_export]
264 macro_rules! errorf {
265   ($($args:expr),*) => {{
266     use $crate::__private as __pw_log_crate;
267     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Error, $($args),*)
268   }};
269 }
270 
271 /// Deprecated alias for [`errorf!`].
272 #[macro_export]
273 macro_rules! pw_log_errorf {
274   ($($args:expr),*) => {{
275     errorf!($($args),*)
276   }}
277 }
278 
279 /// Emit a critical level log message using `core::fmt` format string semantics.
280 ///
281 /// ```
282 /// use pw_log::critical;
283 ///
284 /// critical!(
285 ///     "Log Fact: Until the {}th century, all ships' masts were made from a single log.",
286 ///     19 as u32);
287 /// ```
288 #[macro_export]
289 macro_rules! critical {
290   ($($args:expr),*) => {{
291     use $crate::__private as __pw_log_crate;
292     __pw_log_crate::log!(__pw_log_crate::LogLevel::Critical, $($args),*)
293   }};
294 }
295 
296 /// Emit a critical level log message using `printf` format string semantics.
297 ///
298 /// ```
299 /// use pw_log::criticalf;
300 ///
301 /// criticalf!(
302 ///     "Log Fact: Until the %dth century, all ships' masts were made from a single log.",
303 ///     19);
304 /// ```
305 #[macro_export]
306 macro_rules! criticalf {
307   ($($args:expr),*) => {{
308     use $crate::__private as __pw_log_crate;
309     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Critical, $($args),*)
310   }};
311 }
312 
313 /// Deprecated alias for [`criticalf!`].
314 #[macro_export]
315 macro_rules! pw_log_criticalf {
316   ($($args:expr),*) => {{
317     criticalf!($($args),*)
318   }}
319 }
320 
321 /// Emit a fatal level log message using `core::fmt` format string semantics.
322 ///
323 /// *Note*: `fatal` only emits a log message and does not cause a `panic!()`
324 ///
325 /// ```
326 /// use pw_log::fatal;
327 ///
328 /// fatal!("Log Fact: All out of log facts! Timber!");
329 /// ```
330 #[macro_export]
331 macro_rules! fatal {
332   ($($args:expr),*) => {{
333     use $crate::__private as __pw_log_crate;
334     __pw_log_crate::log!(__pw_log_crate::LogLevel::Fatal, $($args),*)
335   }};
336 }
337 
338 /// Emit a fatal level log message using `printf` format string semantics.
339 ///
340 /// *Note*: `fatalf` only emits a log message and does not cause a `panic!()`
341 ///
342 /// ```
343 /// use pw_log::fatalf;
344 ///
345 /// fatalf!("Log Fact: All out of log facts! Timber!");
346 /// ```
347 #[macro_export]
348 macro_rules! fatalf {
349   ($($args:expr),*) => {{
350     use $crate::__private as __pw_log_crate;
351     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Fatal, $($args),*)
352   }};
353 }
354 
355 /// Deprecated alias for [`fatalf!`].
356 #[macro_export]
357 macro_rules! pw_log_fatalf {
358   ($($args:expr),*) => {{
359     fatalf!($($args),*)
360   }}
361 }
362 
363 #[cfg(test)]
364 mod tests {
365     // TODO(b/311262163): Add infrastructure for testing behavior of `pw_log` API.
366     // The syntax of that API is verified through doctests.
367 }
368