log-lazy 0.2.0

A lazy logging library with bitwise level control
Documentation
  • Coverage
  • 29.71%
    41 out of 138 items documented1 out of 81 items with examples
  • Size
  • Source code size: 51.82 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.83 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 15s Average build duration of successful builds.
  • all releases: 49s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • link-foundation/log-lazy
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • konard

log-lazy for Rust

A lazy logging crate with the same bitwise level model as the JavaScript log-lazy package.

Core Idea

The entire closure passed to a log method is either executed or skipped. This lets production code keep detailed diagnostics without paying for formatting, serialization, or data collection when the level is disabled.

use log_lazy::{debug_lazy, levels, LogLazy};

let log = LogLazy::with_level(levels::PRODUCTION);

log.error(|| "this error message is emitted");

debug_lazy!(log, "debug payload: {}", expensive_payload());

expensive_payload() is not called while debug is disabled.

Levels

The crate uses the same bit flags as the JavaScript package:

Name Value
none 0
fatal 1
error 2
warn 4
info 8
debug 16
verbose 32
trace 64
silly 128
all 255
production 7
development 31

Combine levels with bitwise OR:

use log_lazy::{levels, LogLazy};

let mut log = LogLazy::with_level(levels::ERROR | levels::WARN);
log.enable_level("info");
log.disable_level("warn");

assert_eq!(log.get_enabled_levels(), vec!["error", "info"]);

Custom Sinks

By default, fatal/error/warn messages go to stderr and the other levels go to stdout. Use with_sink to route messages into another logger:

use log_lazy::{levels, LogLazy};

let log = LogLazy::with_sink(levels::ALL, |level, message| {
    eprintln!("[{}] {}", level.name(), message);
});

log.info(|| "service started");

Preprocessors and Postprocessors

Use LogLazyOptions when you need a processor pipeline. Preprocessors receive lazy LogArg values before they are evaluated. Postprocessors receive the compiled message string immediately before the sink is called.

use log_lazy::{
    levels, postprocessors, preprocessors, LogArg, LogLazy, LogLazyOptions,
};

let log = LogLazy::with_options(
    LogLazyOptions::new()
        .level(levels::ALL)
        .preprocessor(preprocessors::add_context(
            preprocessors::AddContextOptions::new("service=orders"),
        ))
        .postprocessor(postprocessors::level(
            postprocessors::LevelOptions::new(),
        ))
        .postprocessor(postprocessors::prefix(
            postprocessors::TextOptions::new("[api]"),
        )),
);

log.emit_args(
    "info",
    [LogArg::from("order created"), LogArg::lazy(|| expensive_payload())],
);

When no processors are configured, the existing closure-based logging path is used directly.