wide_log/lib.rs
1//! # wide-log
2//!
3//! A high-speed wide-event logging system for Rust. A single structured event
4//! accumulates fields throughout a request/task lifecycle and is emitted as
5//! one JSON line on completion.
6//!
7//! ## Quick Start
8//!
9//! The [`wide_log!`] macro takes a JSON object literal and generates the key
10//! enum, `Key` trait impl, thread-local storage, guard builder, `current()`
11//! accessor, `scope()` / `scope_default()` async functions (behind the
12//! `tokio` feature), `WideLogLayer` tower middleware (behind the `tokio`
13//! feature), and all logging macros (`wl_set!`, `wl_inc!`, `info!`, etc.) in
14//! one invocation.
15//!
16//! ```rust,ignore
17//! use wide_log::wide_log;
18//!
19//! wide_log!({
20//! "service": {
21//! "name": null,
22//! "version": "1.0.0",
23//! },
24//! "requests": counter!,
25//! });
26//!
27//! fn main() {
28//! tracing_subscriber::fmt().init();
29//! let _guard = WideLogGuard::builder().build();
30//! wl_set!("service.name", "example-service");
31//! wl_inc!("requests");
32//! info!("request received");
33//! // _guard drops → duration.total_ms set, timestamp set,
34//! // event emitted as JSON.
35//! }
36//! ```
37//!
38//! ## Auto-Added Keys
39//!
40//! - **`"log"`** — log entries from `info!()`, `warn!()`, etc. Handled
41//! internally; never declared by the user.
42//! - **`"duration"`** — elapsed time in ms. Auto-added as
43//! `"duration": { "total_ms": duration! }` if not declared.
44//! - **`"event"`** — event metadata. Auto-added as
45//! `"event": { "timestamp": null, "id": null }` if not declared.
46//! The `timestamp` is set to an RFC 3339 string on drop. The `id` is
47//! set to a ULID string (or UUIDv4 with the `uuid` feature) on `build()`.
48//!
49//! ## Customizable Key Strings
50//!
51//! All 8 built-in key strings can be renamed using an optional bracketed
52//! override list before the JSON object:
53//!
54//! ```rust,ignore
55//! wide_log!([
56//! Event.Id => "correlation_id",
57//! Log.Level => "severity",
58//! ], {
59//! "service": { "name": null },
60//! "requests": counter!,
61//! });
62//! ```
63//!
64//! See the README for the full list of override paths.
65//!
66//! ## Builder Pattern
67//!
68//! Use `WideLogGuard::builder()` to construct a guard. The builder allows
69//! specifying a custom timezone, ID generator, and emit function:
70//!
71//! ```rust,ignore
72//! // Default: UTC timezone, ULID ID, tracing emit
73//! let _guard = WideLogGuard::builder().build();
74//!
75//! // Custom timezone
76//! use chrono_tz::Tz;
77//! let _guard = WideLogGuard::builder()
78//! .with_timezone(Tz::America__New_York)
79//! .build();
80//!
81//! // Custom ID generator
82//! let _guard = WideLogGuard::builder()
83//! .with_id(|| "my-custom-id".to_string())
84//! .build();
85//!
86//! // UUIDv4 ID (requires `uuid` feature)
87//! let _guard = WideLogGuard::builder()
88//! .with_uuid()
89//! .build();
90//!
91//! // Custom emit function
92//! let _guard = WideLogGuard::builder()
93//! .with_emit(|ev| { println!("{}", ev.to_json().unwrap()); })
94//! .build();
95//! ```
96//!
97//! ## `info!` Shadowing
98//!
99//! The generated `info!`, `warn!`, `error!`, `debug!`, `trace!` macros shadow
100//! `tracing::info!` etc. when both are in scope. To call the real tracing
101//! macros, use the fully qualified path: `::tracing::info!(...)`.
102//!
103//! ## Features
104//!
105//! - `tokio` — enables async support: `scope()`, `scope_default()`,
106//! `WideLogLayer` tower middleware, and `tokio::task_local!` storage.
107//! - `uuid` — enables `WideLogGuardBuilder::with_uuid()` for UUIDv4 ID
108//! generation instead of the default ULID.
109
110pub(crate) mod context;
111pub(crate) mod error;
112pub(crate) mod guard;
113pub(crate) mod key;
114pub(crate) mod log;
115pub(crate) mod value;
116pub(crate) mod wide_event;
117
118#[cfg(feature = "tokio")]
119pub(crate) mod middleware;
120
121pub use error::Error;
122pub use guard::ScopedGuard;
123pub use key::Key;
124pub use value::Value;
125pub use wide_event::WideEvent;
126
127pub use context::ContextCell;
128
129/// The `wide_log!` proc-macro. See the [crate-level documentation](crate)
130/// for syntax and usage details.
131///
132/// Takes a JSON object literal as its only parameter. The JSON structure
133/// defines all keys, their nesting/paths, default values, and which keys
134/// are counters or durations. The macro generates:
135///
136/// - The `EventKey` enum (`#[repr(u8)]`, one variant per unique JSON key)
137/// - The `Key` trait impl (`as_str`, `MAX_KEYS`, `as_index`,
138/// `DURATION_PATH`, `TIMESTAMP_PATH`, `ID_PATH`)
139/// - `__wl_resolve_path` — compile-time path resolution function
140/// - Thread-local storage (`CURRENT_EVENT: ContextCell<WideEvent<EventKey>>`)
141/// - `default_emit` — serializes via `sonic_rs` and emits via `::tracing::info!`
142/// - `WideLogGuardBuilder` — builder for constructing guards with timezone,
143/// ID generator, and emit function
144/// - `WideLogGuard` — guard type (constructed via `builder().build()`)
145/// - `current()` — returns the innermost active event
146/// - `scope()` / `scope_default()` (behind `tokio` feature)
147/// - `WideLogLayer` tower middleware (behind `tokio` feature)
148/// - All logging macros: `wl_set!`, `wl_inc!`, `wl_dec!`, `wl_add!`,
149/// `wl_null!`, `info!`, `warn!`, `error!`, `debug!`, `trace!`
150///
151/// # Value Markers
152///
153/// | Marker | Meaning |
154/// |---|---|
155/// | `duration!` | Duration leaf; set to elapsed ms on drop |
156/// | `counter!` | Incrementable counter; init to 0 (absent) |
157/// | `null` | No default value; set via `wl_set!` |
158/// | `"literal"` | String default; set on guard creation |
159/// | `123` | Numeric default; set on guard creation |
160/// | `true`/`false` | Boolean default; set on guard creation |
161///
162/// # Duration Auto-Add Rules
163///
164/// If no `"duration"` key is declared, the macro adds
165/// `"duration": { "total_ms": duration! }` automatically. See the README for
166/// the full duration resolution table.
167///
168/// # Event Auto-Add Rules
169///
170/// If no `"event"` key is declared, the macro adds
171/// `"event": { "timestamp": null, "id": null }` automatically.
172/// The `timestamp` is set to an RFC 3339 string on drop.
173/// The `id` is set to a ULID string (or UUIDv4 with the `uuid` feature)
174/// on `build()`.
175pub use wide_log_macros::wide_log;
176
177#[cfg(feature = "tokio")]
178pub mod __re_exports {
179 pub use tokio;
180 pub use tower;
181}
182
183pub mod __re_exports_core {
184 pub use chrono;
185 pub use chrono_tz;
186 pub use tracing;
187 pub use ulid;
188}
189
190#[cfg(feature = "uuid")]
191pub mod __re_exports_uuid {
192 pub use uuid;
193}