rmesg 1.0.21

This is a fully Rust-based implementation of the popular dmesg Linux utility, giving programmatic access to the kernel log buffer.
Documentation

Build Status

rmesg

A 'dmesg' implementation in Rust

As a crate: https://crates.io/crates/rmesg

As a command-line utility

Obtain the latest release binary

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

cargo install rmesg

Usage

rmesg: A 'dmesg' port onto Rust 1.0.0
Archis Gore <me@archisgore.com>
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]

As a Crate

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.

Depend on the rmesg crate

Include it in Cargo.toml:

[dependencies]
rmesg = "1.0.0"

Suppots two features:

  • async - Exposes asynchronous Stream API
  • sync - Exposes synchronous Iterator API

Reading the buffer single-shot (non-blocking)

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)
    }

Indefinitely iterating

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);
    }