Crates.io | loga |
lib.rs | loga |
version | 0.5.2 |
source | src |
created_at | 2023-05-13 03:48:17.068147 |
updated_at | 2024-07-16 13:23:35.155026 |
description | Combined logging and error handling |
homepage | |
repository | https://github.com/andrewbaxter/loga |
max_upload_size | |
id | 863517 |
size | 50,587 |
Errors and log messages are closely related - both are events, where logs are output in realtime (to a terminal or remote logger) without affecting execution flow and errors are passed up in lieu of a successful result for another context to either log or discard. Both provide information what was happening at the time of the event, including context up the stack (what was happening, as part of what larger actions, and with what relationships to other entities).
With this library you build a tree of Log
objects to store context at multiple levels and the Log
object has methods for logging and creating errors which contain the full tree of context.
use loga::{
ea,
ResultContext,
INFO,
};
fn main1() -> Result<(), loga::Error> {
// All errors stacked from this will have "system = main"
let log = &loga::Log::new_root(INFO).fork(ea!(system = "main"));
// Convert the error result to `loga::Error`, add all the logger's attributes, add
// a message, and add additional attributes.
let res =
http_req(
"https://example.org",
).stack_context_with(log, "Example.org is down", ea!(process = "get_weather"))?;
match launch_satellite(res.body) {
Ok(_) => (),
Err(e) => {
let e = e.stack_context(log, "Failed to launch satellite");
if let Err(e2) = shutdown_server() {
// Attach incidental errors
return Err(e.also(e2.into()));
}
return Err(e);
},
}
if res.code == 295 {
return Err(loga::err("Invalid response"));
}
log.log(INFO, "Obtained weather");
return Ok(());
}
fn main() {
match main1() {
Ok(_) => (),
Err(e) => loga::fatal(e),
}
}
The goal of this crate is to make it easy to produce clear and informative log messages and errors with full context. To do that creating errors and log messages as well as adding context must be easy.
Optimization will be considered as necessary as far as it doesn't impact ease of use and expressivity.
Events (errors and log messages) also have a tree structure, with the following dimensions:
The errors are intended only for human consumption. Any information that may need to be handled programmatically should be in a non-error return.
In non-logging functions or objects that may be shared in multiple contexts, rather than receive a logger from the caller it may be simpler to start a new (blank) Log tree internally, or just use .context
. The caller can later root the context using .stack_context
or the logger's context will naturally be added in log.log_err
.
Currently logging is written to stderr only. Adding more log destinations and formats in the future would be nice.