A 'dmesg' implementation in Rust
As a crate: https://crates.io/crates/rmesg
wget https://github.com/archisgore/rmesg/releases/latest/download/rmesg
chmod a+x ./rmesg
# Optionally move to a stable location
mv ./rmesg /usr/local/bin
cargo install rmesg
rmesg: A 'dmesg' port onto Rust 1.0.0
Archis Gore <[email protected]>
Reads (and prints) the kernel log buffer. Does not support all dmesg options (yet).
USAGE:
rmesg [FLAGS] [OPTIONS]
FLAGS:
-c Clear ring buffer after printing (only when using klogctl)
-f When specified, follows logs (like tail -f)
-h, --help Prints help information
-r Print raw data as it came from the source backend.
-V, --version Prints version information
OPTIONS:
-b <backend> Select backend from where to read the logs. klog is the syslog/klogctl system call through libc.
kmsg is the /dev/kmsg file. [possible values: klogctl, devkmsg]
The real value of this crate is programmatic access to kernel buffer from Rust
programs, allowing a dmesg
that can be consumed programmatically.
The complete API can be found in the main.rs
file which uses the sync/async versions of the APIs, both single-shot and iterative.
Include it in Cargo.toml:
[dependencies]
rmesg = "1.0.0"
Suppots two features:
async
- Exposes asynchronous Stream APIsync
- Exposes synchronous Iterator API
NOTE: Reading single-shot is the same interface for sync or async
use rmesg;
// Read all logs as one big string with line-breaks
let raw = rmesg::logs_raw(opts.backend, opts.clear).unwrap();
print!("{}", raw)
// Read logs as a Vec of Entry'ies (`Vec<Entry>`)
// and can be processed entry-by-entry
let entries = rmesg::log_entries(opts.backend, opts.clear).unwrap();
for entry in entries {
println!("{}", entry)
}
With feature sync
(i.e. synchronous), provides an Iterator over Result<Entry, RMesgError>.
use rmesg;
let entries = rmesg::logs_iter(opts.backend, opts.clear, opts.raw)?;
for maybe_entry in entries {
let entry = maybe_entry?;
println!("{}", entry);
}
With feature async
(i.e. asynchronous), provides a Stream over Result<Entry, RMesgError>.
use rmesg;
// given that it's a stream over Result's, use the conveniences provided to us
use futures_util::stream::TryStreamExt;
let mut entries = rmesg::logs_stream(opts.backend, opts.clear, opts.raw).await?;
while let Some(entry) = entries.try_next().await? {
println!("{}", entry);
}