minimal_logger 0.7.0

A minimal-resource, platform-native logger for Rust applications.
Documentation

minimal_logger

A minimal-resource, multi-platform logger for Rust with optional file output, automatic flushing, platform-native log rotation, and change-aware runtime reconfiguration via a builder API.

Features

  • Shared buffered file logging with BufWriter
  • Platform-specific log rotation
    • Linux / macOS: SIGHUP
    • Windows: Local\\RustLogger_LogRotate named event
  • Periodic background flush thread with configurable interval
  • Builder-based configuration for log level, output file, buffer size, and format
  • Environment-variable bootstrap via config_from_env()
  • Falls back to stderr when file output is unavailable
  • Change-aware runtime reconfiguration — only updated subsystems are re-initialised

Installation

Add to your Cargo.toml:

[dependencies]
minimal_logger = "0.4"
log = "0.4"

Getting started

Construct a MinimalLoggerConfig and pass it to init() once at startup:

use log::{error, info};

fn main() {
    let _guard = minimal_logger::init(
        minimal_logger::MinimalLoggerConfig::new()
            .level(log::LevelFilter::Info)
    ).expect("failed to initialise logger");

    info!("application started");
    error!("shutdown due to error");
}

Or seed configuration from the standard RUST_LOG* environment variables:

fn main() {
    let _guard = minimal_logger::init(minimal_logger::config_from_env())
        .expect("failed to initialise logger");
}

Runtime reconfiguration

Call reinit() with a new MinimalLoggerConfig to update a running logger.

reinit() is change-aware and only updates components whose effective configuration changed:

  • log filters and max level (.level() / .filter())
  • output destination (.file() / .stderr())
  • periodic flush worker interval (.flush_ms())
  • rendering format (.format())
  • buffer capacity for newly opened file writers (.buf_capacity())

Unset fields keep their current value — you can change a single subsystem without repeating the full configuration. If nothing changed, reinit() returns immediately.

use log::info;

fn reconfigure() {
    // Switch to debug level; all other settings unchanged.
    minimal_logger::reinit(
        minimal_logger::MinimalLoggerConfig::new()
            .level(log::LevelFilter::Debug)
            .filter("myapp::db", log::LevelFilter::Trace)
    );
    info!("logger reconfigured");
}

Configuration

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 Shared file 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 buffer sizes, flush intervals, format templates, format widths, and filter lists are bounded to avoid accidental memory or latency spikes from environment variables.

Level and filter syntax

// All targets at DEBUG
MinimalLoggerConfig::new().level(log::LevelFilter::Debug)

// Global WARN; myapp at DEBUG
MinimalLoggerConfig::new()
    .level(log::LevelFilter::Warn)
    .filter("myapp", log::LevelFilter::Debug)

// Layered per-module overrides
MinimalLoggerConfig::new()
    .level(log::LevelFilter::Info)
    .filter("myapp::db", log::LevelFilter::Trace)
    .filter("hyper", log::LevelFilter::Off)

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 brace characters.

Default format string:

{timestamp} [{level:<5}] T[{thread_name}] [{target}] {args}

Log rotation

The logger reopens its log file on a platform-native signal or event, with no gap in output and no lost bytes.

Platform Trigger
Linux / macOS SIGHUP
Other Unix SIGHUP
Windows Local\RustLogger_LogRotate named event

When the signal fires, the logger opens a new file and atomically swaps the active writer. Buffered output on the old writer is flushed and synced before the old descriptor is closed.

Example logrotate configuration (Linux):

/var/log/myapp.log {
    daily
    rotate 7
    postrotate
        kill -HUP $(cat /var/run/myapp.pid)
    endscript
}

API summary

Function Description
init(MinimalLoggerConfig) Register the logger; returns a [ShutdownGuard] that flushes on drop.
reinit(MinimalLoggerConfig) Apply a new config; update only changed subsystems.
config_from_env() Build a MinimalLoggerConfig from RUST_LOG* environment variables.
shutdown() Flush active buffered output; called automatically by ShutdownGuard.

Cargo metadata

This crate exposes docs on docs.rs.