logwise

An opinionated logging library for Rust with structured logging, privacy-aware data handling, and hierarchical task-based context management.
Development Status
logwise is experimental and the API may change.
The Problem
Traditional logging crates like log offer generic log levels
(error, warn, info, debug, trace) that are often too vague for real-world use cases.
This leads to several problems:
- Ambiguous levels: Is
debugfor print-style debugging in your library, or for users debugging their own code? - Build control: How do you compile out expensive logs by default but enable them when debugging user-reported issues?
- Missing use cases: What level is appropriate for "this is slow and should be optimized"?
logwise solves these problems with opinionated, use-case-specific log levels.
Core Philosophy
Think of log levels like module visibility. You have pub, pub(crate), pub(super), and
private visibility for different use cases. logwise provides similar granular control for logging.
Log Levels
logwise provides specific log levels for defined use cases:
| Level | Use Case | Build Type | Thread Control |
|---|---|---|---|
trace |
Detailed debugging | debug only | Must enable per-thread via Context::begin_trace() |
debuginternal |
Print-style debugging | debug only | On by default in current crate, per-thread in downstream |
info |
Supporting downstream crates | debug only | On by default |
perfwarn |
Performance problems with analysis | all builds | Always on |
warning |
Suspicious conditions | all builds | Always on |
error |
Logging errors in Results | all builds | Always on |
panic |
Programmer errors | all builds | Always on |
Quick Start
Basic Logging
// Simple structured logging
info_sync!;
// With multiple parameters
warn_sync!;
// Async logging for better performance
async
Privacy-Aware Logging
logwise's privacy system ensures sensitive data is handled appropriately:
use ;
// Complex types require explicit privacy handling
let user = User ;
// Use LogIt wrapper for complex types
info_sync!;
// Mark explicitly non-private data when it's safe
let public_id = "PUBLIC-123";
info_sync!;
Context and Task Management
Track hierarchical tasks with automatic performance monitoring:
use Context;
// Create a new task
let ctx = new_task;
ctx.clone.set_current;
// Enable detailed tracing for debugging
begin_trace;
// Nested tasks automatically track hierarchy
let child_ctx = new_task;
child_ctx.clone.set_current;
// Task completion is logged automatically when dropped
Performance Tracking
Use the perfwarn! macro to track and log slow operations:
// Tracks execution time automatically
perfwarn!;
// Logs warning if operation exceeds threshold
Architecture Overview
Core Components
Logger: The trait defining logging backendsLogRecord: Structured log entry with metadataLevel: Enumeration of available log levelscontextmodule: Thread-local hierarchical task managementprivacymodule: Privacy-aware data handling systemglobal_loggermodule: Global logger registration and management
Logging Flow
- Macros generate a
LogRecordwith source location metadata - The
privacy::Loggabletrait determines how values are logged - Records are dispatched to registered
Loggerimplementations - Loggers can process records synchronously or asynchronously
Examples
Complete Application Example
use ;
Custom Logger Implementation
use ;
use Arc;
use Debug;
use Pin;
use Future;
;
// Register the logger
add_global_logger;
Thread Safety and Async Support
logwise is designed for concurrent and async environments:
- All
Loggerimplementations must beSend + Sync - Context is thread-local with parent inheritance
context::ApplyContextpreserves context across async boundaries- Both sync and async logging variants are available
Performance Considerations
- Use async variants (
*_async!) in async contexts for better performance - The
perfwarn!macro includes automatic interval tracking - Debug-only levels are compiled out in release builds
- Thread-local caching reduces synchronization overhead
WASM Support
logwise includes WebAssembly support with browser-specific features:
- Uses
web-timefor time operations - Console output via
web-sys - Batched logging with
InMemoryLogger::periodic_drain_to_console