Simple structured logging.
```rust use lumbermill::{info, Logger}
fn main() { // Initialize the logger early Logger::default().init();
// Log a single line info!("Incoming connection from {:?} {}", addr, port);
// Attach key-value pairs with the log message info!(addr.ip = ip, addr.port = port, "Listening on {}", port); // Or use the shorthand if the key's name is the same as the variable: info!(addr.ip, port, "Listening on {}", port);
// Attach key-value pairs with the log message, formatting them using their
// Debug
trait (useful when variables do not implement Display
)
info!(addr.ip = ?ip, addr.port = port, "Listening on {}", port);
// Or in the shorthand notation:
info!(?addr.ip, port, "Listening on {}", port);
}
```
The trace!
, debug!
, info!
, warn!
, error!
& fatal!
are heavily inspired
by tracing
's macros because they're good.
The default logger prints pretty logs to stdout
only, but you can configure the Logger
to behave differently:
```rust use lumbermill::{LogFormat, LogLevel, RollInterval};
Logger::builder() .format(LogFormat::Compact) // Set the format of logs .level(LogLevel::Info) // Set the minimum log level .stdout(false) // Stop printing to stdout .file("./logs", RollInterval::Daily) // Log to a directory; one file per day
// Shorthands .pretty() // .format(LogFormat::Pretty) .compact() // .format(LogFormat::Compact) .json() // .format(LogFormat::Json)
// Remember to call init
after configuration!
.init();
```
You can have different active configurations in different scenarios by using the
#![cfg]
macro:
```rust // Pretty logs on stdout during development
Logger::default().level(LogLevel::Trace).pretty().init();
// Compact logs on rolling files in production
{ let dir = "./logs"; std::fs::createdirall(dir)?; Logger::default() .level(LogLevel::Info) .compact() .file(dir, lumbermill::RollInterval::Hourly) .init(); } ```
Examples are a good entrypoint to learn about the library. Run them this way:
sh
$ cargo run --example 01-defaults # Or replace this wil a different example's name
Docs usually go into more detail once you get the hang of things.
The tracing
ecosystem is awesome, but it's also overkill for a lot of apps who
only need structured logging and not a distributed tracing solution. The log
crate
is the obvious alternative, but its kv
module is a work-in-progress.
You are also unable to log key-value pairs that do not implement Display
, in
a incovenient way.
This crate is a stop-gap till log::kv
stabilizes. It marries tracing
's awesome
event!
macro to log
's simplicity. The plan is to eventually drop the custom
macros in this crate and integrate with log
directly.