Skip to main content

Crate minimal_logger

Crate minimal_logger 

Source
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 methodDefault at initDescription
.level(l)InfoGlobal 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)4096Per-thread BufWriter capacity in bytes
.flush_ms(ms)1000Periodic flush interval; 0 flushes every record
.format(tmpl)see belowLog-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

PlaceholderExample 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

  1. init() registers the global logger and starts the flush worker thread when the configured flush interval is non-zero.
  2. Log macros (info!, debug!, …) render one log line and write it into a shared buffered file writer (or stderr when file output is disabled).
  3. reinit() applies a new MinimalLoggerConfig and updates only the subsystems whose effective configuration changed.
  4. The ShutdownGuard returned by init() calls shutdown() 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

TriggerMechanism
Buffer fullBufWriter flushes automatically on the next write_all call
PeriodicBackground worker flushes the active shared file buffer
Guard dropShutdownGuard from init() calls shutdown() on drop
Explicitshutdown() or Log::flush() flushes the active buffer

§Log rotation

PlatformSignal / mechanism
Linux / macOSSIGHUP
Other UnixSIGHUP
WindowsLocal\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§

MinimalLoggerConfig
Builder for logger configuration.
ShutdownGuard
A drop guard that calls shutdown() when it goes out of scope.

Functions§

config_from_envDeprecated
Build a MinimalLoggerConfig from the standard RUST_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.