flipperzero/furi/log/mod.rs
1//! Furi Logging system.
2
3pub(crate) mod metadata;
4
5pub use metadata::{Level, LevelFilter};
6
7/// The standard logging macro.
8///
9/// This macro will generically log with the specified `Level` and `format!` based
10/// argument list.
11///
12/// # Examples
13///
14/// ```
15/// use flipperzero::{log, furi::log::Level};
16///
17/// # fn main() {
18/// let error_code = 42;
19///
20/// log!(Level::ERROR, "Failed to handle the florp: {}", error_code);
21/// log!(target: "events", Level::INFO, "Finished the documentation!");
22/// # }
23/// ```
24#[macro_export]
25macro_rules! log {
26 (target: $target:expr, $lvl:expr, $msg:expr $(, $arg:expr)*) => ({
27 // The `uwrite!` macro expects `ufmt` in scope
28 use $crate::__macro_support::ufmt;
29
30 if $lvl <= $crate::furi::log::LevelFilter::current() {
31 const TARGET: *const ::core::ffi::c_char =
32 match ::core::ffi::CStr::from_bytes_with_nul(
33 ::core::concat!($target, "\0").as_bytes(),
34 ) {
35 Ok(cstr) => cstr.as_ptr(),
36 Err(_error) => panic!("target contains NULs"),
37 };
38
39 let mut buf = $crate::__macro_support::FuriString::new();
40 $crate::__macro_support::ufmt::uwrite!(&mut buf, $msg $(, $arg)*)
41 .expect("can append to FuriString");
42 // don't pass raw expression to the internal `unsafe` block
43 let lvl = $crate::__macro_support::__level_to_furi($lvl);
44 let buf = buf.as_c_ptr();
45 unsafe {
46 $crate::__macro_support::__sys::furi_log_print_format(lvl, TARGET, buf);
47 };
48 }
49 });
50
51 ($lvl:expr, $msg:expr $(, $arg:expr)*) => (
52 $crate::log!(target: module_path!(), $lvl, $msg $(, $arg)*)
53 );
54}
55
56/// Logs a message at the error level.
57///
58/// # Examples
59///
60/// ```
61/// use flipperzero::error;
62///
63/// # fn main() {
64/// let error_code = 42;
65/// let name = "Flipper";
66///
67/// error!("Failed to handle the florp: {}", error_code);
68/// error!(target: "events", "Missed birthday party for {}", name);
69/// # }
70/// ```
71#[macro_export]
72macro_rules! error {
73 (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
74 $crate::log!(target: $target, $crate::furi::log::Level::ERROR, $msg $(, $arg)*)
75 );
76
77 ($msg:expr $(, $arg:expr)*) => (
78 $crate::log!($crate::furi::log::Level::ERROR, $msg $(, $arg)*)
79 );
80}
81
82/// Logs a message at the warn level.
83///
84/// # Examples
85///
86/// ```
87/// use flipperzero::warn;
88///
89/// # fn main() {
90/// let name = "Flipper";
91///
92/// warn!("Event almost started!");
93/// warn!(target: "events", "About to miss the birthday party for {}", name);
94/// # }
95/// ```
96#[macro_export]
97macro_rules! warn {
98 (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
99 $crate::log!(target: $target, $crate::furi::log::Level::WARN, $msg $(, $arg)*)
100 );
101
102 ($msg:expr $(, $arg:expr)*) => (
103 $crate::log!($crate::furi::log::Level::WARN, $msg $(, $arg)*)
104 );
105}
106
107/// Logs a message at the info level.
108///
109/// # Examples
110///
111/// ```
112/// use flipperzero::info;
113///
114/// # fn main() {
115/// let name = "Flipper";
116///
117/// info!("It's {}'s birthday today!", name);
118/// info!(target: "events", "Birthday party today: {}", name);
119/// # }
120/// ```
121#[macro_export]
122macro_rules! info {
123 (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
124 $crate::log!(target: $target, $crate::furi::log::Level::INFO, $msg $(, $arg)*)
125 );
126
127 ($msg:expr $(, $arg:expr)*) => (
128 $crate::log!($crate::furi::log::Level::INFO, $msg $(, $arg)*)
129 );
130}
131
132/// Logs a message at the debug level.
133///
134/// # Examples
135///
136/// ```
137/// use flipperzero::debug;
138///
139/// # fn main() {
140/// let name = "Flipper";
141///
142/// debug!("Creating {} event", 1);
143/// debug!(target: "events", "New event created: birthday party for {}", name);
144/// # }
145/// ```
146#[macro_export]
147macro_rules! debug {
148 (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
149 $crate::log!(target: $target, $crate::furi::log::Level::DEBUG, $msg $(, $arg)*)
150 );
151
152 ($msg:expr $(, $arg:expr)*) => (
153 $crate::log!($crate::furi::log::Level::DEBUG, $msg $(, $arg)*)
154 );
155}
156
157/// Logs a message at the trace level.
158///
159/// # Examples
160///
161/// ```
162/// use flipperzero::trace;
163///
164/// # fn main() {
165/// let name = "Flipper";
166///
167/// trace!("About to show how the target field works");
168/// trace!(target: "events", "Scanning for events involving {}", name);
169/// # }
170/// ```
171#[macro_export]
172macro_rules! trace {
173 (target: $target:expr, $msg:expr $(, $arg:expr)*) => (
174 $crate::log!(target: $target, $crate::furi::log::Level::TRACE, $msg $(, $arg)*)
175 );
176
177 ($msg:expr $(, $arg:expr)*) => (
178 $crate::log!($crate::furi::log::Level::TRACE, $msg $(, $arg)*)
179 );
180}