log-easy 0.2.0

Easy to use file logger with log levels and global logging macros.
Documentation

log-easy

Crates.io Docs.rs License: MIT OR Apache-2.0

Easy-to-use file logger that writes messages in a simple, readable format. Built for straightforward file logging with minimal setup.

Installation

[!NOTE] Minimum supported Rust version (MSRV): 1.85

Add this to your Cargo.toml:

[dependencies]
log-easy = "0.2"

Features

  • Log levels: Trace, Debug, Info, Warn, Error
  • Global macros for ergonomic logging (info!, warn!, etc.)
  • Instance-based API for explicit control
  • Minimal dependencies

Log Format

Each entry is written as:

[YYYY-MM-DD HH:MM:SS][LOG_LEVEL] Message

Quick Start (Global Logger + Macros)

use log_easy::{error, info, init_with, warn, LogLevel, Logger};

fn main() -> std::io::Result<()> {
    init_with(Logger::new("app.log").with_level(LogLevel::Info))?;

    info!("Application started");
    warn!("This is a warning");
    error!("Something went wrong");

    Ok(())
}

[!NOTE] Global macros require init or init_with to be called once before use.

Instance Logger (No Globals)

use log_easy::{LogLevel, Logger};

fn main() -> std::io::Result<()> {
    let logger = Logger::new("app-instance.log").with_level(LogLevel::Debug);

    logger.debug("Instance logger ready");
    logger.info("Application started");

    Ok(())
}

Formatting Messages

Macros accept formatting arguments like println!:

use log_easy::{info, init_with, LogLevel, Logger};

fn main() -> std::io::Result<()> {
    init_with(Logger::new("app.log").with_level(LogLevel::Info))?;

    let user = "alice";
    let id = 42;
    info!("user={} id={}", user, id);

    Ok(())
}

Instance methods accept a preformatted string:

use log_easy::{LogLevel, Logger};

fn main() -> std::io::Result<()> {
    let logger = Logger::new("app.log").with_level(LogLevel::Info);

    logger.info(&format!("user={} id={}", "alice", 42));

    Ok(())
}

Log Levels

Messages below the configured level are ignored.

use log_easy::{LogLevel, Logger};

let logger = Logger::new("app.log").with_level(LogLevel::Warn);
logger.info("This will not be logged");
logger.warn("This will be logged");

String Parsing

Log levels can be parsed from strings (case-insensitive). Invalid strings default to LogLevel::Info.

Valid names: trace, debug, info, warn, warning, error

Numeric aliases: 5 = trace, 4 = debug, 3 = info, 2 = warn, 1 = error

use log_easy::LogLevel;

assert_eq!(LogLevel::from_str("INFO"), LogLevel::Info);
assert_eq!(LogLevel::from_str("debug"), LogLevel::Debug);
assert_eq!(LogLevel::from_str("WARN"), LogLevel::Warn);
assert_eq!(LogLevel::from_str("5"), LogLevel::Trace);

Example: Parse log level from string

use log_easy::{LogLevel, Logger};

fn main() -> std::io::Result<()> {
    let logger = Logger::new("target/instance.log").with_level(LogLevel::from_str("Debug"));
    logger.info("Parser working");
    Ok(())
}

Initialization (init vs init_with)

  • init(path) initializes the global logger at the default level (Info).
  • init_with(logger) lets you provide a fully configured Logger.
use log_easy::{init, init_with, LogLevel, Logger};

init("app.log")?;
init_with(Logger::new("app.log").with_level(LogLevel::Trace))?;

Both return std::io::Result<()> and will error if the global logger is already initialized.

Error Handling

The convenience methods (info, warn, etc.) are non-intrusive and never return errors. If a write fails, the logger prints a message to stderr.

If you need to handle errors explicitly, use the try_* methods:

use log_easy::{LogLevel, Logger};

fn main() -> std::io::Result<()> {
    let logger = Logger::new("app.log").with_level(LogLevel::Info);

    logger.try_info("This can fail")?;
    Ok(())
}

The try_* macros return std::io::Result<()> as well:

use log_easy::{init_with, try_info, LogLevel, Logger};

fn main() -> std::io::Result<()> {
    init_with(Logger::new("app.log").with_level(LogLevel::Info))?;

    try_info!("This can fail")?;

    Ok(())
}

License

Licensed under either of:

  • Apache License, Version 2.0
  • MIT license

at your option.