sentry_core/
logger.rs

1//! Macros for Sentry [structured logging](https://docs.sentry.io/product/explore/logs/).
2
3// Helper macro to capture a log at the given level. Should not be used directly.
4#[doc(hidden)]
5#[macro_export]
6macro_rules! logger_log {
7    // Simple message
8    ($level:expr, $msg:literal) => {{
9        let log = $crate::protocol::Log {
10            level: $level,
11            body: $msg.to_owned(),
12            trace_id: None,
13            timestamp: ::std::time::SystemTime::now(),
14            severity_number: None,
15            attributes: $crate::protocol::Map::new(),
16        };
17        $crate::Hub::current().capture_log(log)
18    }};
19
20    // Message with format string and args
21    ($level:expr, $fmt:literal, $($arg:expr),+) => {{
22        let mut attributes = $crate::protocol::Map::new();
23
24        attributes.insert(
25            "sentry.message.template".to_owned(),
26            $crate::protocol::LogAttribute($crate::protocol::Value::from($fmt))
27        );
28        let mut i = 0;
29        $(
30            attributes.insert(
31                format!("sentry.message.parameter.{}", i),
32                $crate::protocol::LogAttribute($crate::protocol::Value::from($arg))
33            );
34            i += 1;
35        )*
36        let _ = i; // avoid triggering the `unused_assignments` lint
37
38        let log = $crate::protocol::Log {
39            level: $level,
40            body: format!($fmt, $($arg),*),
41            trace_id: None,
42            timestamp: ::std::time::SystemTime::now(),
43            severity_number: None,
44            attributes,
45        };
46        $crate::Hub::current().capture_log(log)
47    }};
48
49    // Attributes entrypoint
50    ($level:expr, $($rest:tt)+) => {{
51        let mut attributes = $crate::protocol::Map::new();
52        $crate::logger_log!(@internal attributes, $level, $($rest)+)
53    }};
54
55    // Attributes base case: no more attributes, simple message
56    (@internal $attrs:ident, $level:expr, $msg:literal) => {{
57        let log = $crate::protocol::Log {
58            level: $level,
59            body: $msg.to_owned(),
60            trace_id: None,
61            timestamp: ::std::time::SystemTime::now(),
62            severity_number: None,
63            #[allow(clippy::redundant_field_names)]
64            attributes: $attrs,
65        };
66        $crate::Hub::current().capture_log(log)
67    }};
68
69    // Attributes base case: no more attributes, message with format string and args
70    (@internal $attrs:ident, $level:expr, $fmt:literal, $($arg:expr),+) => {{
71        $attrs.insert(
72            "sentry.message.template".to_owned(),
73            $crate::protocol::LogAttribute($crate::protocol::Value::from($fmt))
74        );
75        let mut i = 0;
76        $(
77            $attrs.insert(
78                format!("sentry.message.parameter.{}", i),
79                $crate::protocol::LogAttribute($crate::protocol::Value::from($arg))
80            );
81            i += 1;
82        )*
83        let _ = i; // avoid triggering the `unused_assignments` lint
84
85        let log = $crate::protocol::Log {
86            level: $level,
87            body: format!($fmt, $($arg),*),
88            trace_id: None,
89            timestamp: ::std::time::SystemTime::now(),
90            severity_number: None,
91            #[allow(clippy::redundant_field_names)]
92            attributes: $attrs,
93        };
94        $crate::Hub::current().capture_log(log)
95    }};
96
97    // Attributes recursive case
98    (@internal $attrs:ident, $level:expr, $($key:ident).+ = $value:expr, $($rest:tt)+) => {{
99        $attrs.insert(
100            stringify!($($key).+).to_owned(),
101            $crate::protocol::LogAttribute($crate::protocol::Value::from($value))
102        );
103        $crate::logger_log!(@internal $attrs, $level, $($rest)+)
104    }};
105}
106
107/// Captures a log at the trace level, with the given message and attributes.
108///
109/// To attach attributes to a log, pass them with the `key = value` syntax before the message.
110/// The message can be a simple string or a format string with its arguments.
111///
112/// The supported attribute keys are all valid Rust identifiers with up to 8 dots.
113/// Using dots will nest multiple attributes under their common prefix in the UI.
114///
115/// The supported attribute values are simple types, such as string, numbers, and boolean.
116///
117/// # Examples
118///
119/// ```
120/// use sentry::logger_trace;
121///
122/// // Simple message
123/// logger_trace!("Hello world");
124///
125/// // Message with format args
126/// logger_trace!("Value is {}", 42);
127///
128/// // Message with format args and attributes
129/// logger_trace!(
130///     error_code = 500,
131///     user.id = "12345",
132///     user.email = "test@test.com",
133///     success = false,
134///     "Error occurred: {}",
135///     "bad input"
136/// );
137/// ```
138#[macro_export]
139macro_rules! logger_trace {
140    ($($arg:tt)+) => {
141        $crate::logger_log!($crate::protocol::LogLevel::Trace, $($arg)+)
142    };
143}
144
145/// Captures a log at the debug level, with the given message and attributes.
146///
147/// To attach attributes to a log, pass them with the `key = value` syntax before the message.
148/// The message can be a simple string or a format string with its arguments.
149///
150/// The supported attribute keys are all valid Rust identifiers with up to 8 dots.
151/// Using dots will nest multiple attributes under their common prefix in the UI.
152///
153/// The supported attribute values are simple types, such as string, numbers, and boolean.
154///
155/// # Examples
156///
157/// ```
158/// use sentry::logger_debug;
159///
160/// // Simple message
161/// logger_debug!("Hello world");
162///
163/// // Message with format args
164/// logger_debug!("Value is {}", 42);
165///
166/// // Message with format args and attributes
167/// logger_debug!(
168///     error_code = 500,
169///     user.id = "12345",
170///     user.email = "test@test.com",
171///     success = false,
172///     "Error occurred: {}",
173///     "bad input"
174/// );
175/// ```
176#[macro_export]
177macro_rules! logger_debug {
178    ($($arg:tt)+) => {
179        $crate::logger_log!($crate::protocol::LogLevel::Debug, $($arg)+)
180    };
181}
182
183/// Captures a log at the info level, with the given message and attributes.
184///
185/// To attach attributes to a log, pass them with the `key = value` syntax before the message.
186/// The message can be a simple string or a format string with its arguments.
187///
188/// The supported attribute keys are all valid Rust identifiers with up to 8 dots.
189/// Using dots will nest multiple attributes under their common prefix in the UI.
190///
191/// The supported attribute values are simple types, such as string, numbers, and boolean.
192///
193/// # Examples
194///
195/// ```
196/// use sentry::logger_info;
197///
198/// // Simple message
199/// logger_info!("Hello world");
200///
201/// // Message with format args
202/// logger_info!("Value is {}", 42);
203///
204/// // Message with format args and attributes
205/// logger_info!(
206///     error_code = 500,
207///     user.id = "12345",
208///     user.email = "test@test.com",
209///     success = false,
210///     "Error occurred: {}",
211///     "bad input"
212/// );
213/// ```
214#[macro_export]
215macro_rules! logger_info {
216    ($($arg:tt)+) => {
217        $crate::logger_log!($crate::protocol::LogLevel::Info, $($arg)+)
218    };
219}
220
221/// Captures a log at the warn level, with the given message and attributes.
222///
223/// To attach attributes to a log, pass them with the `key = value` syntax before the message.
224/// The message can be a simple string or a format string with its arguments.
225///
226/// The supported attribute keys are all valid Rust identifiers with up to 8 dots.
227/// Using dots will nest multiple attributes under their common prefix in the UI.
228///
229/// The supported attribute values are simple types, such as string, numbers, and boolean.
230///
231/// # Examples
232///
233/// ```
234/// use sentry::logger_warn;
235///
236/// // Simple message
237/// logger_warn!("Hello world");
238///
239/// // Message with format args
240/// logger_warn!("Value is {}", 42);
241///
242/// // Message with format args and attributes
243/// logger_warn!(
244///     error_code = 500,
245///     user.id = "12345",
246///     user.email = "test@test.com",
247///     success = false,
248///     "Error occurred: {}",
249///     "bad input"
250/// );
251/// ```
252#[macro_export]
253macro_rules! logger_warn {
254    ($($arg:tt)+) => {
255        $crate::logger_log!($crate::protocol::LogLevel::Warn, $($arg)+)
256    };
257}
258
259/// Captures a log at the error level, with the given message and attributes.
260///
261/// To attach attributes to a log, pass them with the `key = value` syntax before the message.
262/// The message can be a simple string or a format string with its arguments.
263///
264/// The supported attribute keys are all valid Rust identifiers with up to 8 dots.
265/// Using dots will nest multiple attributes under their common prefix in the UI.
266///
267/// The supported attribute values are simple types, such as string, numbers, and boolean.
268///
269/// # Examples
270///
271/// ```
272/// use sentry::logger_error;
273///
274/// // Simple message
275/// logger_error!("Hello world");
276///
277/// // Message with format args
278/// logger_error!("Value is {}", 42);
279///
280/// // Message with format args and attributes
281/// logger_error!(
282///     error_code = 500,
283///     user.id = "12345",
284///     user.email = "test@test.com",
285///     success = false,
286///     "Error occurred: {}",
287///     "bad input"
288/// );
289/// ```
290#[macro_export]
291macro_rules! logger_error {
292    ($($arg:tt)+) => {
293        $crate::logger_log!($crate::protocol::LogLevel::Error, $($arg)+)
294    };
295}
296
297/// Captures a log at the fatal level, with the given message and attributes.
298///
299/// To attach attributes to a log, pass them with the `key = value` syntax before the message.
300/// The message can be a simple string or a format string with its arguments.
301///
302/// The supported attribute keys are all valid Rust identifiers with up to 8 dots.
303/// Using dots will nest multiple attributes under their common prefix in the UI.
304///
305/// The supported attribute values are simple types, such as string, numbers, and boolean.
306///
307/// # Examples
308///
309/// ```
310/// use sentry::logger_fatal;
311///
312/// // Simple message
313/// logger_fatal!("Hello world");
314///
315/// // Message with format args
316/// logger_fatal!("Value is {}", 42);
317///
318/// // Message with format args and attributes
319/// logger_fatal!(
320///     error_code = 500,
321///     user.id = "12345",
322///     user.email = "test@test.com",
323///     success = false,
324///     "Error occurred: {}",
325///     "bad input"
326/// );
327/// ```
328#[macro_export]
329macro_rules! logger_fatal {
330    ($($arg:tt)+) => {
331        $crate::logger_log!($crate::protocol::LogLevel::Fatal, $($arg)+)
332    };
333}