Expand description
Minimal-resource logger for Rust applications.
minimal_logger provides a low-allocation, thread-buffered logger
with optional file output, periodic flushing, platform-native log rotation, and
change-aware runtime reconfiguration via a builder API.
§Quick start
use log::{error, info, warn};
fn main() {
let _guard = minimal_logger::init(minimal_logger::MinimalLoggerConfig::new())
.expect("failed to initialise logger");
info!("application started");
warn!("disk usage above 80%");
error!("connection refused");
}§Configuration
All settings are passed through a MinimalLoggerConfig builder. Unset fields use
compile-time defaults on init() and keep their current value on reinit().
| Builder method | Default at init | Description |
|---|---|---|
.level(l) | Info | Global log level |
.filter(t, l) | (none) | Per-target level override; may be called many times |
.file(path) | (stderr) | Append log records to a file (O_APPEND) |
.stderr() | (default) | Explicitly route output back to stderr |
.buf_capacity(n) | 4096 | Per-thread BufWriter capacity in bytes |
.flush_ms(ms) | 1000 | Periodic flush interval; 0 flushes every record |
.format(tmpl) | see below | Log-line template with {field} placeholders |
New Unix log files are created with owner-only permissions, subject to the process umask. Oversized environment/config values are bounded to avoid accidental memory or latency spikes.
§Reading from environment variables
config_from_env() reads the standard RUST_LOG* environment variables and
returns a pre-populated MinimalLoggerConfig. Builder methods can be chained
to override individual settings before passing to init() or reinit():
// Pure environment-variable configuration.
let _guard = minimal_logger::init(minimal_logger::config_from_env())
.expect("logger init failed");
// Env vars as a baseline with a programmatic override.
let _guard = minimal_logger::init(
minimal_logger::config_from_env().level(log::LevelFilter::Debug)
).expect("logger init failed");§Level and filter syntax
Set a global default level and optional per-target overrides:
let _guard = minimal_logger::init(
minimal_logger::MinimalLoggerConfig::new()
.level(log::LevelFilter::Debug) // all targets at DEBUG
).expect("logger init failed");
let _guard = minimal_logger::init(
minimal_logger::MinimalLoggerConfig::new()
.level(log::LevelFilter::Warn) // global WARN
.filter("myapp", log::LevelFilter::Debug) // myapp and submodules at DEBUG
).expect("logger init failed");Recognised levels: Off, Error, Warn, Info, Debug, Trace.
When multiple filters match a target the most specific (longest prefix) wins.
§Format fields
| Placeholder | Example output |
|---|---|
{timestamp} | 2026-04-18T12:34:56.789012Z |
{level} | INFO |
{thread_name} | main |
{target} | myapp::server |
{module_path} | myapp::server |
{file} | src/server.rs |
{line} | 42 |
{args} | listening on :8080 |
Width and alignment: {level:<5} left-aligns in a field of width 5;
{line:>4} right-aligns. Use {{ and }} for literal braces.
Default format string:
{timestamp} [{level:<5}] T[{thread_name}] [{target}] {args}§Lifecycle
init()registers the global logger and starts the flush worker thread when the configured flush interval is non-zero.- Log macros (
info!,debug!, …) render one log line and write it into a shared buffered file writer (or stderr when file output is disabled). reinit()applies a newMinimalLoggerConfigand updates only the subsystems whose effective configuration changed.- The
ShutdownGuardreturned byinit()callsshutdown()when dropped, flushing active buffered output on every exit path (normal return,?propagation, or panic).
§Runtime reconfiguration
Build a MinimalLoggerConfig with only the fields you want to change and call
reinit(). Unset fields keep their current values — no need to repeat the
full configuration:
// Switch to debug level without touching file, format, or flush settings.
minimal_logger::reinit(
minimal_logger::MinimalLoggerConfig::new().level(log::LevelFilter::Debug)
);Only the components whose resolved value actually changed are updated:
- Filters / max level — recomputed and applied via
log::set_max_level. - Output file — destination swapped atomically; the previous writer is flushed/synced before close.
- Flush interval — old worker thread stopped and joined; new one spawned.
- Format template — new parsed template swapped in atomically.
- Buffer size — applied to newly opened log files.
§Flush model
| Trigger | Mechanism |
|---|---|
| Buffer full | BufWriter flushes automatically on the next write_all call |
| Periodic | Background worker flushes the active shared file buffer |
| Guard drop | ShutdownGuard from init() calls shutdown() on drop |
| Explicit | shutdown() or Log::flush() flushes the active buffer |
§Log rotation
| Platform | Signal / mechanism |
|---|---|
| Linux / macOS | SIGHUP |
| Other Unix | SIGHUP |
| Windows | Local\RustLogger_LogRotate named event |
When rotation fires, the logger opens a new file and atomically swaps the active writer. The old writer is flushed and synced before close.
Structs§
- Minimal
Logger Config - Builder for logger configuration.
- Shutdown
Guard - A drop guard that calls
shutdown()when it goes out of scope.
Functions§
- config_
from_ env Deprecated - Build a
MinimalLoggerConfigfrom the standardRUST_LOG*environment variables. - init
- Initialise the logger and start the periodic flush worker.
- reinit
- Apply an updated configuration to the running logger.
- shutdown
- Flush active buffered output and stop the background flush worker.