veecle_telemetry/macros.rs
1/// Creates a new span.
2///
3/// A span represents a unit of work or operation that has a beginning and end.
4/// It can contain attributes that provide additional context about the operation.
5///
6/// # Examples
7///
8/// ```rust
9/// use veecle_telemetry::span;
10///
11/// let span = span!("database_query");
12/// ```
13///
14/// ```rust
15/// use veecle_telemetry::span;
16///
17/// let user_id = 123;
18/// let table_name = "users";
19/// let span =
20/// span!("database_query", user_id, table = table_name, "operation" = "select");
21/// ```
22#[macro_export]
23macro_rules! span {
24 ($name:literal $(, $($attributes:tt)*)?) => {
25 $crate::Span::new($name, $crate::attributes!($($($attributes)*)?))
26 };
27}
28
29/// Adds an event to the current span.
30///
31/// Events are timestamped occurrences that happen during the execution of a span.
32/// They can include additional context through attributes.
33///
34/// # Examples
35///
36/// Add a simple event:
37/// ```rust
38/// use veecle_telemetry::event;
39///
40/// event!("cache_miss");
41/// ```
42///
43/// Add an event with attributes:
44/// ```rust
45/// use veecle_telemetry::event;
46///
47/// let key = "user:123";
48/// let cache_type = "redis";
49/// event!("cache_miss", key = key, cache_type = cache_type, "retry_count" = 3);
50/// ```
51#[macro_export]
52macro_rules! event {
53 ($name:literal $(, $($attributes:tt)*)?) => {
54 $crate::CurrentSpan::add_event($name, $crate::attributes!($($($attributes)*)?))
55 };
56}
57
58/// Logs a message with the specified severity level.
59///
60/// This is the base logging macro that other severity-specific macros build upon.
61/// It allows you to specify the severity level and optional attributes.
62///
63/// # Examples
64///
65/// Log a simple message:
66/// ```rust
67/// use veecle_telemetry::log;
68/// use veecle_telemetry::protocol::base::Severity;
69///
70/// log!(Severity::Info, "Application started");
71/// ```
72///
73/// Log a message with attributes:
74/// ```rust
75/// use veecle_telemetry::log;
76/// use veecle_telemetry::protocol::base::Severity;
77///
78/// let port = 8080;
79/// let version = "1.0.0";
80/// log!(Severity::Info, "Server listening", port = port, version = version, "protocol" = "HTTP");
81/// ```
82#[macro_export]
83macro_rules! log {
84 ($severity:expr, $body:literal $(, $($attributes:tt)*)?) => {
85 $crate::log::log($severity, $body, $crate::attributes!($($($attributes)*)?))
86 };
87}
88
89/// Logs a trace-level message.
90///
91/// Trace messages are used for very detailed debugging information,
92/// typically only enabled during development or deep troubleshooting.
93///
94/// # Examples
95///
96/// Simple trace message:
97/// ```rust
98/// use veecle_telemetry::trace;
99///
100/// trace!("Entering function");
101/// ```
102///
103/// Trace message with context:
104/// ```rust
105/// use veecle_telemetry::trace;
106///
107/// let function_name = "process_request";
108/// let request_id = "req-123";
109/// trace!("Function entry", function = function_name, request_id = request_id);
110/// ```
111#[macro_export]
112macro_rules! trace {
113 ($($args:tt)*) => {
114 $crate::log!($crate::protocol::base::Severity::Trace, $($args)*);
115 };
116}
117
118/// Logs a debug-level message.
119///
120/// Debug messages provide detailed information about the program's execution,
121/// useful for diagnosing issues during development and testing.
122///
123/// # Examples
124///
125/// Simple debug message:
126/// ```rust
127/// use veecle_telemetry::debug;
128///
129/// debug!("Processing user request");
130/// ```
131///
132/// Debug message with variables:
133/// ```rust
134/// use veecle_telemetry::debug;
135///
136/// let user_id = 456;
137/// let action = "login";
138/// debug!("User action processed", user_id = user_id, action = action, "success" = true);
139/// ```
140#[macro_export]
141macro_rules! debug {
142 ($($args:tt)*) => {
143 $crate::log!($crate::protocol::base::Severity::Debug, $($args)*);
144 };
145}
146
147/// Logs an info-level message.
148///
149/// Info messages provide general information about the program's execution,
150/// suitable for normal operational logging.
151///
152/// # Examples
153///
154/// Simple info message:
155/// ```rust
156/// use veecle_telemetry::info;
157///
158/// info!("Service started successfully");
159/// ```
160///
161/// Info message with metadata:
162/// ```rust
163/// use veecle_telemetry::info;
164///
165/// let service_name = "web-server";
166/// let version = "2.1.0";
167/// info!(
168/// "Service initialization complete",
169/// service = service_name,
170/// version = version,
171/// "startup_time_ms" = 1250
172/// );
173/// ```
174#[macro_export]
175macro_rules! info {
176 ($($args:tt)*) => {
177 $crate::log!($crate::protocol::base::Severity::Info, $($args)*);
178 };
179}
180
181/// Logs a warning-level message.
182///
183/// Warning messages indicate potential issues or unusual conditions
184/// that don't prevent the program from continuing but should be noted.
185///
186/// # Examples
187///
188/// Simple warning message:
189/// ```rust
190/// use veecle_telemetry::warn;
191///
192/// warn!("Rate limit approaching");
193/// ```
194///
195/// Warning with context:
196/// ```rust
197/// use veecle_telemetry::warn;
198///
199/// let current_requests = 950;
200/// let limit = 1000;
201/// warn!(
202/// "High request rate detected",
203/// current_requests = current_requests,
204/// limit = limit,
205/// "utilization_percent" = 95
206/// );
207/// ```
208#[macro_export]
209macro_rules! warn {
210 ($($args:tt)*) => {
211 $crate::log!($crate::protocol::base::Severity::Warn, $($args)*);
212 };
213}
214
215/// Logs an error-level message.
216///
217/// Error messages indicate serious problems that have occurred
218/// but allow the program to continue running.
219///
220/// # Examples
221///
222/// Simple error message:
223/// ```rust
224/// use veecle_telemetry::error;
225///
226/// error!("Database connection failed");
227/// ```
228///
229/// Error with details:
230/// ```rust
231/// use veecle_telemetry::error;
232///
233/// let db_host = "localhost:5432";
234/// let error_code = 1001;
235/// error!(
236/// "Database operation failed",
237/// host = db_host,
238/// error_code = error_code,
239/// "retry_attempted" = true
240/// );
241/// ```
242#[macro_export]
243macro_rules! error {
244 ($($args:tt)*) => {
245 $crate::log!($crate::protocol::base::Severity::Error, $($args)*);
246 };
247}
248
249/// Logs a fatal-level message.
250///
251/// Fatal messages indicate critical errors that will likely cause
252/// the program to terminate or become unusable.
253///
254/// # Examples
255///
256/// Simple fatal message:
257/// ```rust
258/// use veecle_telemetry::fatal;
259///
260/// fatal!("Critical system failure");
261/// ```
262///
263/// Fatal error with context:
264/// ```rust
265/// use veecle_telemetry::fatal;
266///
267/// let component = "memory_allocator";
268/// let error_type = "out_of_memory";
269/// fatal!(
270/// "System component failure",
271/// component = component,
272/// error_type = error_type,
273/// "available_memory_mb" = 0
274/// );
275/// ```
276#[macro_export]
277macro_rules! fatal {
278 ($($args:tt)*) => {
279 $crate::log!($crate::protocol::base::Severity::Fatal, $($args)*);
280 };
281}
282
283/// Constructs a slice of `KeyValue` attributes.
284///
285/// This macro is primarily used when manually constructing spans.
286///
287/// # Syntax
288///
289/// The macro supports several attribute formats:
290/// - `identifier = value` - Uses the identifier as the key name
291/// - `"literal" = value` - Uses the literal string as the key name
292/// - `identifier` - Uses the identifier as both key and value
293/// - `field.subfield` - Simple dot notation for field access
294///
295/// # Examples
296///
297/// Basic usage with mixed attribute types:
298/// ```rust
299/// use veecle_telemetry::attributes;
300///
301/// let user_id = 123;
302/// let service_name = "auth-service";
303/// let attrs = attributes!(user_id = user_id, "service" = service_name, "version" = "1.0.0");
304/// ```
305///
306/// Using identifiers as both key and value:
307/// ```rust
308/// use veecle_telemetry::attributes;
309///
310/// let database = "postgresql";
311/// let timeout = 30;
312/// let attrs = attributes!(
313/// database, // equivalent to database = database
314/// timeout = timeout,
315/// "connection_pool" = "primary"
316/// );
317/// ```
318///
319/// Span construction with attributes:
320/// ```rust
321/// use veecle_telemetry::{Span, attributes};
322///
323/// let operation = "user_login";
324/// let user_id = 456;
325/// let span = Span::new(
326/// "authentication",
327/// attributes!(operation = operation, user_id = user_id, "security_level" = "high"),
328/// );
329/// ```
330///
331/// Empty attributes:
332/// ```rust
333/// use veecle_telemetry::attributes;
334/// use veecle_telemetry::protocol::transient::KeyValue;
335///
336/// let attrs: &[KeyValue<'_>] = attributes!(); // Creates an empty slice
337/// ```
338#[macro_export]
339macro_rules! attributes {
340 ({ $($kvs:tt)* }) => {
341 $crate::attributes_inner!(@ { }, { $($kvs)* })
342 };
343 ($($kvs:tt)*) => {
344 $crate::attributes_inner!(@ { }, { $($kvs)* })
345 };
346}
347
348/// The actual implementation of `attributes!`, separated out to avoid accidentally recursing into
349/// the `$($tt)*` case from the inner cases.
350#[doc(hidden)]
351#[macro_export]
352macro_rules! attributes_inner {
353 // Base case, remaining tokens is empty.
354 (@ { $($val:expr,)* }, { } ) => {
355 &[ $($val,)* ]
356 };
357
358 // Recursive cases, take one key-value pair, add it to the output, and recurse on the remaining
359 // tokens.
360 (@ { $($out:expr,)* }, { $($key:ident).+ $(, $($rest:tt)*)? }) => {
361 $crate::attributes_inner!(
362 @ { $($out,)* $crate::attribute!($($key).+), },
363 { $($($rest)*)? }
364 )
365 };
366 (@ { $($out:expr,)* }, { $key:ident = $value:expr $(, $($rest:tt)*)? }) => {
367 $crate::attributes_inner!(
368 @ { $($out,)* $crate::attribute!($key = $value), },
369 { $($($rest)*)? }
370 )
371 };
372 (@ { $($out:expr,)* }, { $key:literal = $value:expr $(, $($rest:tt)*)? }) => {
373 $crate::attributes_inner!(
374 @ { $($out,)* $crate::attribute!($key = $value), },
375 { $($($rest)*)? }
376 )
377 };
378}
379
380/// Constructs a single attribute `KeyValue` pair.
381#[macro_export]
382macro_rules! attribute {
383 ($($key:ident)+ = $value:expr) => {
384 $crate::protocol::transient::KeyValue::new(::core::stringify!($($key).+), &$value)
385 };
386 ($key:literal = $value:expr) => {
387 $crate::protocol::transient::KeyValue::new($key, &$value)
388 };
389 ($($key:ident)+) => {
390 $crate::protocol::transient::KeyValue::new(::core::stringify!($($key).+), &$($key).+)
391 };
392}