Skip to main content

Crate minimal_logger

Crate minimal_logger 

Source
Expand description

Minimal-resource logger for Rust applications.

minimal_logger provides a zero-allocation-on-hot-path, 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() {
    minimal_logger::init(minimal_logger::MinimalLoggerConfig::new())
        .expect("failed to initialise logger");

    info!("application started");
    warn!("disk usage above 80%");
    error!("connection refused");

    minimal_logger::shutdown();
}

§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 in milliseconds
.format(tmpl)see belowLog-line template with {field} placeholders

§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.
minimal_logger::init(minimal_logger::config_from_env())
    .expect("logger init failed");

// Env vars as a baseline with a programmatic override.
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:

minimal_logger::init(
    minimal_logger::MinimalLoggerConfig::new()
        .level(log::LevelFilter::Debug)               // all targets at DEBUG
).expect("logger init failed");

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}] [{file}:{line}] {args}

§Lifecycle

  1. init() registers the global logger and starts the flush worker thread.
  2. Log macros (info!, debug!, …) write into the calling thread’s BufWriter with no heap allocation on the steady-state path.
  3. reinit() applies a new MinimalLoggerConfig and updates only the subsystems whose effective configuration changed.
  4. shutdown() flushes the calling thread’s buffered writer to the kernel.

§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 — old file flushed, synced, and closed; new file opened.
  • Flush interval — old worker thread stopped and joined; new one spawned.
  • Format template — new parsed template swapped in atomically.
  • Buffer size — applied the next time a thread-local writer is recreated.

§Flush model

TriggerMechanism
Buffer fullBufWriter flushes automatically on the next write_all call
PeriodicBackground worker sets a flag; next log call calls bw.flush()
Thread exitBufWriter::drop() calls flush() automatically
Explicitshutdown() or Log::flush() flushes the calling thread

§Log rotation

PlatformSignal / mechanism
Linux / macOSSIGHUP
Other UnixSIGHUP
WindowsGlobal\RustLogger_LogRotate named event

When rotation fires, each thread detects the new file on its next log call via an Arc pointer comparison: it flushes buffered bytes to the old file descriptor, then creates a new BufWriter pointing to the freshly opened file. The old descriptor is closed once no thread holds a reference to it.

Structs§

MinimalLoggerConfig
Builder for logger configuration.

Functions§

config_from_env
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 the calling thread’s buffered writer to the kernel.