xref: /aosp_15_r20/external/pigweed/pw_log/rust/pw_log.rs (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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 dependences 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;
55     pub use pw_log_backend::{pw_log_backend, pw_logf_backend};
56 }
57 
58 /// Emit a log message using `core::fmt` format string semantics.
59 ///
60 /// `log` takes a [`LogLevel`], a `core::fmt` style format string, and necessary
61 /// arguments to that string and emits a log message to the logging backend.
62 ///
63 /// ```
64 /// use pw_log::{log, LogLevel};
65 ///
66 /// log!(LogLevel::Info, "Log fact: A {} log has a Janka hardness of {} lbf.",
67 ///      "Spruce Pine" as &str, 700 as i32);
68 /// ```
69 #[macro_export]
70 macro_rules! log {
71   ($log_level:expr, $format_string:literal) => {{
72     use $crate::__private as __pw_log_crate;
73     $crate::__private::pw_log_backend!($log_level, $format_string)
74   }};
75 
76   ($log_level:expr, $format_string:literal, $($args:expr),*) => {{
77     use $crate::__private as __pw_log_crate;
78     $crate::__private::pw_log_backend!($log_level, $format_string, $($args),*)
79   }};
80 }
81 
82 /// Emit a log message using `printf` format string semantics.
83 ///
84 /// `logf` takes a [`LogLevel`], a `printf` style format string, and necessary
85 /// arguments to that string and emits a log message to the logging backend.
86 ///
87 /// ```
88 /// use pw_log::{logf, LogLevel};
89 ///
90 /// logf!(LogLevel::Info, "Log fact: A %s log has a Janka hardness of %d lbf.",
91 ///     "Spruce Pine", 700);
92 /// ```
93 #[macro_export]
94 macro_rules! logf {
95   ($log_level:expr, $format_string:literal) => {{
96     use $crate::__private as __pw_log_crate;
97     $crate::__private::pw_logf_backend!($log_level, $format_string)
98   }};
99 
100   ($log_level:expr, $format_string:literal, $($args:expr),*) => {{
101     use $crate::__private as __pw_log_crate;
102     $crate::__private::pw_logf_backend!($log_level, $format_string, $($args),*)
103   }};
104 }
105 
106 /// Deprecated alias for [`logf!`].
107 #[macro_export]
108 macro_rules! pw_logf {
109   ($($args:expr),*) => {{
110     logf!($($args),*)
111   }}
112 }
113 
114 /// Emit a debug level log message using `core:fmt` format string semantics.
115 ///
116 /// ```
117 /// use pw_log::debug;
118 ///
119 /// debug!("Log Fact: The American toy Lincoln Logs were inspired by the {} in {}.",
120 ///     "Imperial Hotel" as &str, "Tokyo" as &str);
121 /// ```
122 #[macro_export]
123 macro_rules! debug {
124   ($($args:expr),*) => {{
125     use $crate::__private as __pw_log_crate;
126     __pw_log_crate::log!(__pw_log_crate::LogLevel::Debug, $($args),*)
127   }};
128 }
129 
130 /// Emit a debug level log message using `printf` format string semantics.
131 ///
132 /// ```
133 /// use pw_log::debugf;
134 ///
135 /// debugf!("Log Fact: The American toy Lincoln Logs were inspired by the %s in %s.",
136 ///     "Imperial Hotel", "Tokyo");
137 /// ```
138 #[macro_export]
139 macro_rules! debugf {
140   ($($args:expr),*) => {{
141     use $crate::__private as __pw_log_crate;
142     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Debug, $($args),*)
143   }};
144 }
145 
146 /// Deprecated alias for [`debugf!`].
147 #[macro_export]
148 macro_rules! pw_log_debugf {
149   ($($args:expr),*) => {{
150     debugf!($($args),*)
151   }}
152 }
153 
154 /// Emit an info level log message using `core:fmt` format string semantics.
155 ///
156 /// ```
157 /// use pw_log::info;
158 ///
159 /// info!(
160 ///     "Log Fact: The American president Abraham Lincoln (born {:x}) once lived in a log cabin.",
161 ///     0x1809 as u32);
162 /// ```
163 #[macro_export]
164 macro_rules! info {
165   ($($args:expr),*) => {{
166     use $crate::__private as __pw_log_crate;
167     __pw_log_crate::log!(__pw_log_crate::LogLevel::Info, $($args),*)
168   }};
169 }
170 
171 /// Emit an info level log message using `printf` format string semantics.
172 ///
173 /// ```
174 /// use pw_log::infof;
175 ///
176 /// infof!(
177 ///     "Log Fact: The American president Abraham Lincoln (born %x) once lived in a log cabin.",
178 /// 0x1809);
179 /// ```
180 #[macro_export]
181 macro_rules! infof {
182   ($($args:expr),*) => {{
183     use $crate::__private as __pw_log_crate;
184     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Info, $($args),*)
185   }};
186 }
187 
188 /// Deprecated alias for [`infof!`].
189 #[macro_export]
190 macro_rules! pw_log_infof {
191   ($($args:expr),*) => {{
192     infof!($($args),*)
193   }}
194 }
195 
196 /// Emit a warn level log message using `core::fmt` format string semantics.
197 ///
198 /// ```
199 /// use pw_log::warn;
200 ///
201 /// warn!(
202 ///     "Log Fact: Made from a log, an {} year old dugout canoe is the oldest discovered boat in {}.",
203 ///     8000 as i32, "Africa" as &str);
204 /// ```
205 #[macro_export]
206 macro_rules! warn {
207   ($($args:expr),*) => {{
208     use $crate::__private as __pw_log_crate;
209     __pw_log_crate::log!(__pw_log_crate::LogLevel::Warn, $($args),*)
210   }};
211 }
212 
213 /// Emit a warn level log message using `printf` format string semantics.
214 ///
215 /// ```
216 /// use pw_log::warnf;
217 ///
218 /// warnf!(
219 ///     "Log Fact: Made from a log, an %d year old dugout canoe is the oldest discovered boat in %s.",
220 ///     8000, "Africa");
221 /// ```
222 #[macro_export]
223 macro_rules! warnf {
224   ($($args:expr),*) => {{
225     use $crate::__private as __pw_log_crate;
226     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Warn, $($args),*)
227   }};
228 }
229 
230 /// Deprecated alias for [`warnf!`].
231 #[macro_export]
232 macro_rules! pw_log_warnf {
233   ($($args:expr),*) => {{
234     warnf!($($args),*)
235   }}
236 }
237 
238 /// Emit an error level log message using `core::fmt` format string semantics.
239 ///
240 /// ```
241 /// use pw_log::error;
242 ///
243 /// error!(
244 ///     "Log Fact: Before saws were invented, the {} was used prepare logs for use.",
245 ///     "adze" as &str);
246 /// ```
247 #[macro_export]
248 macro_rules! error {
249   ($($args:expr),*) => {{
250     use $crate::__private as __pw_log_crate;
251     __pw_log_crate::log!(__pw_log_crate::LogLevel::Error, $($args),*)
252   }};
253 }
254 
255 /// Emit an error level log message using `printf` format string semantics.
256 ///
257 /// ```
258 /// use pw_log::errorf;
259 ///
260 /// errorf!(
261 ///     "Log Fact: Before saws were invented, the %s was used prepare logs for use.",
262 ///     "adze");
263 /// ```
264 #[macro_export]
265 macro_rules! errorf {
266   ($($args:expr),*) => {{
267     use $crate::__private as __pw_log_crate;
268     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Error, $($args),*)
269   }};
270 }
271 
272 /// Deprecated alias for [`errorf!`].
273 #[macro_export]
274 macro_rules! pw_log_errorf {
275   ($($args:expr),*) => {{
276     errorf!($($args),*)
277   }}
278 }
279 
280 /// Emit a critical level log message using `core::fmt` format string semantics.
281 ///
282 /// ```
283 /// use pw_log::critical;
284 ///
285 /// critical!(
286 ///     "Log Fact: Until the {}th century, all ships' masts were made from a single log.",
287 ///     19 as u32);
288 /// ```
289 #[macro_export]
290 macro_rules! critical {
291   ($($args:expr),*) => {{
292     use $crate::__private as __pw_log_crate;
293     __pw_log_crate::log!(__pw_log_crate::LogLevel::Critical, $($args),*)
294   }};
295 }
296 
297 /// Emit a critical level log message using `printf` format string semantics.
298 ///
299 /// ```
300 /// use pw_log::{criticalf, LogLevel};
301 ///
302 /// criticalf!(
303 ///     "Log Fact: Until the %dth century, all ships' masts were made from a single log.",
304 ///     19);
305 /// ```
306 #[macro_export]
307 macro_rules! criticalf {
308   ($($args:expr),*) => {{
309     use $crate::__private as __pw_log_crate;
310     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Critical, $($args),*)
311   }};
312 }
313 
314 /// Deprecated alias for [`criticalf!`].
315 #[macro_export]
316 macro_rules! pw_log_criticalf {
317   ($($args:expr),*) => {{
318     criticalf!($($args),*)
319   }}
320 }
321 
322 /// Emit a fatal level log message using `core::fmt` format string semantics.
323 ///
324 /// *Note*: `fatal` only emits a log message and does not cause a `panic!()`
325 ///
326 /// ```
327 /// use pw_log::fatal;
328 ///
329 /// fatal!("Log Fact: All out of log facts! Timber!");
330 /// ```
331 #[macro_export]
332 macro_rules! fatal {
333   ($($args:expr),*) => {{
334     use $crate::__private as __pw_log_crate;
335     __pw_log_crate::log!(__pw_log_crate::LogLevel::Fatal, $($args),*)
336   }};
337 }
338 
339 /// Emit a fatal level log message using `printf` format string semantics.
340 ///
341 /// *Note*: `fatalf` only emits a log message and does not cause a `panic!()`
342 ///
343 /// ```
344 /// use pw_log::{fatalf, LogLevel};
345 ///
346 /// fatalf!("Log Fact: All out of log facts! Timber!");
347 /// ```
348 #[macro_export]
349 macro_rules! fatalf {
350   ($($args:expr),*) => {{
351     use $crate::__private as __pw_log_crate;
352     __pw_log_crate::logf!(__pw_log_crate::LogLevel::Fatal, $($args),*)
353   }};
354 }
355 
356 /// Deprecated alias for [`fatalf!`].
357 #[macro_export]
358 macro_rules! pw_log_fatalf {
359   ($($args:expr),*) => {{
360     fatalf!($($args),*)
361   }}
362 }
363 
364 #[cfg(test)]
365 mod tests {
366     // TODO(b/311262163): Add infrastructure for testing behavior of `pw_log` API.
367     // The syntax of that API is verified through doctests.
368 }
369