[−][src]Crate delog
Deferred logging, for instance for printf()
-debugging (a.k.a tracing)
This is an implementation of the log::Log
trait, suitable for use
in both embedded and desktop environments.
Compared to existing approaches such as ufmt
, cortex-m-funnel
and defmt
,
we pursue different values and requirements, namely:
- compatibility with the standard
core::fmt
traits and the standardlog
library API. This means that, while libraries may "upgrade" their logging capabilities by usingdelog
as drop-in replacement for their logging calls (see below), any existing library that already useslog
is compatible. This, for our use cases, is a huge win, as opposed to using up "weirdness budget" and requiring custom tooling for something that is often trivial, throw-away, simple logging. - it follows that one can easily drop a
trace!("{:?}", &suspicious_object)
call at any time for any object that has a (possibly automatically derived)Debug
trait implementation – without passing around structures and keeping on top of lifetimes. - deferred logging: This is a typical "shared memory" logger, calls to
info!
etc. are not directly sent to their final output, but instead are stored in a circular buffer that is "drained" by callingflush
on the logger at a convenient moment, for instance in an idle loop. - immediate mode logging: Sometimes one wants to bypass the deferred flushing of logs,
this is possible using either the little-known
target
argument toinfo!
and friends with "!" as parameter, or using the additionalimmediate_info!
and friends macros. - ability to set log levels per library, at compile-time. This can be easily retro-fitted
on existing
log
-based libraries, by adding the requisite features inCargo.toml
and replacinglog
withdelog
(seegate-tests
for examples of this). - the outcome is that one can leave useful logging calls in the library code, only to activate them in targeted ways at build time, exactly as needed.
- helper macros to easily output binary byte arrays and slices in hexadecimal representations,
which wrap the data in newtypes with custom
fmt::UpperHex
etc. implementations.
Non-goals:
- ultimate speed or code size: Our intention are "normal" logs, not the use of logging/tracing to
for stream binary data to the host. While admittedly the
core::fmt
-ing facilities are not as efficient as one might hope, in our use cases we have sufficient flash and RAM to use these (and some hope that, someday, eventually, maybe, the formatting machinery will be revisited and improved at the root level, namely the language itself.)
That said, we believe there is opportunity to extend delog
in the defmt
direction by
using, e.g., the fmt::Binary
trait, newtypes and sentinel values to embed raw binary
representations of data in time-critical situations without formatting, deferring
the extraction and actual formatting to some host-side mechanism.
Features
The flushers
and semihosting
features mostly exist to share code within the examples,
including the example
feature. Without them, dependencies are quite minimal, and compilation fast.
The fallible
and immediate
features (default on) activate the try_*!
and *_now!
macros, respectively.
Warning
The current circular buffer implementation (v0.1.0) is definitely unsound on desktop.
For embedded use, atomics are required (so no Cortex-M0/M1, and no plans to support non-atomic
platforms, which are likely to also be too resource-constrained to support the bloat inherent
in core::fmt
). While we think the implemented circular buffer algorithm works for the "nested interrupt"
setup of NVICs, it has not been tested much.
The hope is that the worst case scenario is some slightly messed up log outputs.
Outlook
We plan to iterate towards a v0.2.0 soon, making use of a separate "flusher" for the "immediate" logging path. For instance, when logging via serial-over-USB, one might want immediate logs to pend a separate RTIC interrupt handler that blocks until the logs are pushed and read (allowing one to debug the boot process of a firmware), or one might want to just write to RTT (or even semihosting xD) for these, during development.
Re-exports
pub use log as upstream; |
Modules
example | An example deferred logger, generated as |
flushers | Typical flushers in various environments. |
hex | Convenient |
render | A lone helper function to render formatting arguments. |
Macros
debug | Logs a message at the debug level. |
debug_now | Immediate version of |
delog | Generate a deferred logger with specified capacity and flushing mechanism. |
error | Logs a message at the error level. |
error_now | Immediate version of |
hex_str | Compactly format byte arrays and slices as hexadecimals. |
hexstr | More compactly format byte arrays and slices as hexadecimals. |
info | Logs a message at the info level. |
info_now | Immediate version of |
local_debug | Local version of |
local_delog | Generate logging macros that can be gated by library. |
local_error | Local version of |
local_info | Local version of |
local_log | Local version of |
local_trace | Local version of |
local_warn | Local version of |
log | The standard logging macro. |
log_enabled | Determines if a message logged at the specified level in that module will be logged. |
log_now | Immediate version of |
trace | Logs a message at the trace level. |
trace_now | Immediate version of |
try_debug | Fallible version of |
try_debug_now | Fallible immediate version of |
try_error | Fallible version of |
try_error_now | Fallible immediate version of |
try_info | Fallible version of |
try_info_now | Fallible immediate version of |
try_log | Fallible version of |
try_log_now | Fallible immediate version of |
try_trace | Fallible version of |
try_trace_now | Fallible immediate version of |
try_warn | Fallible version of |
try_warn_now | Fallible immediate version of |
upstream | The standard logging macro. |
warn | Logs a message at the warn level. |
warn_now | Immediate version of |
Structs
Statistics | Statistics on logger usage. |
Enums
Level | An enum representing the available verbosity levels of the logger. |
LevelFilter | An enum representing the available verbosity level filters of the logger. |
Traits
Delogger | Semi-abstract characterization of the deferred loggers that the |
Flusher | A way to pass on logs, user supplied. |
TryLog | Fallible, panic-free version of the |
TryLogWithStatistics | TryLog with some usage statistics on top. |
Functions
dequeue⚠ | The core "read from circular buffer" method. Marked unsafe to discourage use! |
enqueue⚠ | The core "write to circular buffer" method. Marked unsafe to discourage use! |
try_enqueue⚠ | The fallible "write to circular buffer" method. Marked unsafe to discourage use! |
trylogger | Returns a reference to the logger (as |