Expand description
High-performance structured binary logging for Rust applications.
kvlog provides macros for emitting structured log messages with key-value pairs, optimized for high throughput and fast compile times. Log messages are encoded in a compact binary format with nanosecond-resolution timestamps.
§Log Messages
Each log message contains:
- A nanosecond-resolution timestamp
- An optional fixed string message
- A target (Rust module path)
- A series of key-value pairs
- Optional span information for distributed tracing
§Log Levels
debug!: Development-only logging, requires thedebugfeature flaginfo!: Provides useful context about application statewarn!: Something bad happened but it was expectederror!: Something bad happened unexpectedly, typically requires intervention
§Examples
Basic logging with key-value pairs:
// Simple message
kvlog::info!("Request completed");
// With key-value pairs (shorthand: `status` is equivalent to `status = status`)
kvlog::info!("Request completed", status, object_id);Using format specifiers:
// %expr uses Display formatting
kvlog::error!("Failed to connect", %err);
// ?expr uses Debug formatting
kvlog::warn!("Unexpected config", ?config);Conditional fields:
kvlog::info!(
"Response sent",
if let Some(len) = response_length { length = len }
);Conditional logging with an environment guard:
static AUDIO_LOGS: kvlog::EnvGuard =
kvlog::EnvGuard::new("APP_AUDIO_LOGS");
kvlog::info!(AUDIO_LOGS; "Audio initialized", codec = "opus");§Spans
kvlog supports building trees of spans for distributed tracing. Unlike other tracing systems, logs are emitted immediately with correlation IDs that track parent-child relationships.
§Basic Span Usage
use kvlog::SpanID;
let span = SpanID::next();
kvlog::info!("Starting operation", span.start = span);
kvlog::info!("Processing", span.current = span);
kvlog::info!("Operation complete", span.end = span);§Nested Spans
Use span.parent = Some(parent_id) to create hierarchical span trees:
use kvlog::SpanID;
let request_span = SpanID::next();
kvlog::info!("Request received", span.start = request_span);
// Create a child span for database work
let db_span = SpanID::next();
kvlog::info!("Querying database", span.start = db_span, span.parent = Some(request_span));
kvlog::info!("Query complete", span.end = db_span);
kvlog::info!("Request complete", span.end = request_span);§Span Guards
Use SpanID::enter to set a thread-local span context. This is useful
when calling functions that should inherit the current span:
use kvlog::SpanID;
fn process_item() {
// This log automatically includes the current span context
kvlog::info!("Processing item");
}
let span = SpanID::next();
let _guard = span.enter(); // Set span as current
kvlog::info!("Starting work", span.start = span);
process_item(); // Logs here inherit the span
kvlog::info!("Work complete", span.end = span);
// Guard dropped, previous span context restored§Default Test Logger
When no collector is explicitly initialized, kvlog automatically emits logs
to stdout in a human-readable format. Colors are enabled when stdout is a
terminal or FORCE_COLOR=1 is set. This works seamlessly with Rust’s test
runner, use cargo test -- --nocapture to see log output:
#[test]
fn my_test() {
// No setup needed - logs are automatically printed to stdout
kvlog::info!("Test starting", test_id = 42);
// ... test logic ...
}This zero-configuration behavior is ideal for development and debugging.
Set KVLOG=0 to discard records from this implicit default logger. Explicitly
initialized collectors are unaffected.
§Collector Setup
For production use, initialize a log collector to capture and output logs with better performance and output control:
let _guard = kvlog::spawn_collector_from_env(Some("my-service"), false);
kvlog::info!("Application started");
// Guard must be held for the duration of loggingRe-exports§
pub use collector::LogBuffer;pub use encoding::BStr;pub use encoding::Encode;pub use encoding::SpanInfo;pub use encoding::ValueEncoder;
Modules§
Macros§
Structs§
- Entered
Span - Guard that restores the previous span context when dropped.
- EnvGuard
- Lazily enables logging based on an environment variable.
- Mutex
- Mutex wrapper that logs warnings when held for too long in debug builds.
- Mutex
Guard - lock guard returned by
Mutex::lock. - SpanID
- Unique identifier for correlating related log messages.
- Spanning
- Wrapper that carries span context with a value.
- Timer
- Simple stopwatch for measuring elapsed time in log messages.
- Timestamp
- UTC timestamp with nanosecond precision.
Enums§
- Collector
Config - Configuration for how log messages should be collected.
- LogLevel
- The severity level of a log message.
Functions§
- continue_
span - Wraps a value with the current span context, or creates a new span if none exists.
- spawn_
collector_ from_ env - Spawn background log collector thread with configuration from the env var:
KVLOG_COLLECTOR_CONFIGUsing CollectorConfig::default() if the env var can’t be read. If quiet is not set to true, the selected logging configuration will be printed to stdout.