veecle_telemetry/log.rs
1//! Structured logging functionality with multiple severity levels.
2//!
3//! This module provides the core logging infrastructure for the telemetry system.
4//! It supports structured logging with key-value attributes and automatically
5//! correlates log messages with active spans when available.
6//!
7//! # Severity Levels
8//!
9//! The logging system supports multiple severity levels:
10//! - [`Severity::Trace`] - Very detailed debugging information
11//! - [`Severity::Debug`] - Detailed debugging information
12//! - [`Severity::Info`] - General informational messages
13//! - [`Severity::Warn`] - Warning messages for potential issues
14//! - [`Severity::Error`] - Error messages for serious problems
15//! - [`Severity::Fatal`] - Fatal error messages for critical failures
16//!
17//! # Examples
18//!
19//! ```rust
20//! veecle_telemetry::info!("Operation completed", {
21//! "duration_ms" = 150,
22//! "success" = true
23//! });
24//! ```
25
26use crate::KeyValue;
27#[cfg(feature = "enable")]
28use crate::collector::get_collector;
29use crate::protocol::Severity;
30#[cfg(feature = "enable")]
31use crate::protocol::{LogMessage, attribute_list_from_slice};
32#[cfg(feature = "enable")]
33use crate::time::now;
34
35/// Logs a message with the specified severity level and attributes.
36///
37/// Prefer using the macros.
38///
39/// This function creates a log message with the given severity, body text, and
40/// key-value attributes.
41/// If there is an active span context, the log message
42/// will automatically be correlated with the trace and span IDs.
43///
44/// # Arguments
45///
46/// * `severity` - The severity level of the log message
47/// * `body` - The main message text
48/// * `attributes` - Key-value pairs providing additional context
49///
50/// # Examples
51///
52/// ```rust
53/// use veecle_telemetry::log::log;
54/// use veecle_telemetry::protocol::Severity;
55/// use veecle_telemetry::{KeyValue, Value, span};
56///
57/// // Simple log message
58/// log(Severity::Info, "Server started", &[]);
59///
60/// // Log with attributes
61/// log(Severity::Warn, "High memory usage", &[
62/// KeyValue::new("memory_usage_percent", 85),
63/// KeyValue::new("available_mb", 512),
64/// ]);
65///
66/// // Log within a span context
67/// let span = span!("request_handler");
68/// let _guard = span.entered();
69/// log(Severity::Error, "Request failed", &[KeyValue::new("error_code", 500)]);
70/// ```
71///
72/// # Conditional Compilation
73///
74/// When the `enable` feature is disabled, this function compiles to a no-op
75/// and has zero runtime overhead.
76#[doc(hidden)]
77pub fn log(severity: Severity, body: &'static str, attributes: &'_ [KeyValue<'static>]) {
78 #[cfg(not(feature = "enable"))]
79 {
80 let _ = (severity, body, attributes);
81 }
82
83 #[cfg(feature = "enable")]
84 {
85 let span_id = crate::SpanContext::current().map(|context| context.span_id);
86
87 let log_message = LogMessage {
88 time_unix_nano: now().as_nanos(),
89 severity,
90 body: body.into(),
91 attributes: attribute_list_from_slice(attributes),
92 span_id,
93 };
94
95 get_collector().log_message(log_message);
96 }
97}