4 releases
new 0.2.1 | Dec 7, 2024 |
---|---|
0.2.0 | Nov 11, 2024 |
0.1.1 | Oct 22, 2024 |
0.1.0 | Oct 14, 2024 |
#141 in Debugging
198 downloads per month
Used in 5 crates
(4 directly)
120KB
898 lines
logwise
logwise is an opinionated logging library for Rust.
Development status
logwise is experimental and the API may change.
The problem
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:
- Suppose I am doing print-style debugging in my library. Is
debug
the right level to use? Or isdebug
where I put messages for users of my library to debug their own code? - How can I compile-out expensive logs by default but collect them from users when they report a bug?
- What's the appropriate log level for "This is slow and should be optimized"?
These problems cannot be solved within the ecosystem-wide common-denominator API, so here we are.
An analogy
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.
The facade
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).
The implementation
logwise currently logs all messages to stderr. In the future, other logging backends may be added.
The API
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.
Privacy
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.
Multithreading
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.
Dependencies
~0–3MB
~54K SLoC