Crates.io | logwise |
lib.rs | logwise |
version | 0.2.0 |
source | src |
created_at | 2024-10-14 02:23:26.237347 |
updated_at | 2024-11-11 00:23:51.934342 |
description | an opinionated logging library for Rust |
homepage | https://sealedabstract.com/code/logwise |
repository | https://github.com/drewcrawford/logwise |
max_upload_size | |
id | 1407846 |
size | 160,579 |
logwise is an opinionated logging library for Rust.
logwise is experimental and the API may change.
Typical logging crates, such as log, offer small set of generic (that is, vague) log levels (error
, warn
, info
, debug
, trace
). But these are so vague and the implementations of loggers so varied that I am never really sure which one to use.
Here are some problems:
debug
the right level to use? Or is debug
where I put messages for users of my library to debug their own code?These problems cannot be solved within the ecosystem-wide common-denominator API, so here we are.
There is a simple analogy to module visibility. There are usecases to make a module private. There are usecases to make it public. To make it pub(crate)
. To make it pub(super)
, except if it's a release build, and so on. logwise provides tools like that, but for logging.
logwise provides an opinionated set of log levels for defined set of usecases.
Name | Usecase | Build type required | Conditions |
---|---|---|---|
trace | Detailed debugging | debug builds only | Must turn on per-thread |
debuginternal | print-style debugging | debug builds only | On by default in the current crate. Must turn on per-thread in downstream crates. |
info | Supporting downstream crates | debug builds only | On by default |
perfwarn | Log performance problems, with analysis | all | all |
warning | Suspicious condition | all | all |
error | logging the error in a Result |
all | all |
panic | logging a programmer error | all | all |
(More levels may be added).
logwise currently logs all messages to stderr. In the future, other logging backends may be added.
For example,
logwise::debuginternal_sync!("Hello {world}!",world=val);
See the docs for more information. Each log level has a synchronous and asynchronous version. The synchronous version can be used from any context. The asynchronous version allows the logging to be deferred to your async executor for better performance in some cases.
The API supports a simple key-value syntax for structured logging. The right-hand side of the expression is only evaluated if the log message is actually printed, and is compiled out when necessary.
Consider the following log message:
Completed job 23 named 'Gift for Alice' in 3.4 seconds.
Another gripe I have about the log
crate's API is there is no way to represent which parts of the log may contain
sensitive user data (in this case, the name of the job). It may be useful to collect this log, but it may be
undesirable to include the sensitive variable in the log message.
logwise's design is designed each variable in the log message conforms to the Loggable
trait, which defines a public
and private representation of the variable. This allows different versions of the log to be generated
from the same log message, depending on the desired privacy level.
logwise has out-of-the-box support for scoped logging in a stack-based, thread-local model.
If you are e.g. spawning a child thread, writing an async executor or similar,
consider using the logwise::context
APIs to propagate the logging context to child threads.