2 releases
Uses new Rust 2024
| 0.1.1 | Feb 6, 2026 |
|---|---|
| 0.1.0 | Feb 5, 2026 |
#458 in Debugging
15KB
182 lines
log-easy
Easy-to-use file logger that writes messages in a simple, readable format. Built for straightforward file logging with minimal setup.
Installation
[!INFO] Minimum supported Rust version (MSRV): 1.85
Add this to your Cargo.toml:
[dependencies]
log-easy = "0.1"
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
initorinit_withto 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");
Initialization (init vs init_with)
init(path)initializes the global logger at the default level (Info).init_with(logger)lets you provide a fully configuredLogger.
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.
Dependencies
~1MB
~18K SLoC