sdjournal is a pure Rust systemd journal reader and query engine. It reads *.journal files directly and does not depend on libsystemd or invoke journalctl (tests may use journalctl for golden comparisons).
- Pure Rust, with no
libsystemddependency - Bounded, corruption-resistant parsing for production use
- Stable merge ordering, cursor checkpoints, and follow/tail support
- Optional mmap, compression backends, tracing, Tokio follow, and FSS verification
- Target OS: Linux
- Non-Linux builds compile, but
Journal::open_default()is Linux-only - CI coverage includes Ubuntu 22.04 (systemd 249.x) and Ubuntu 24.04 (systemd 255.x)
cargo add sdjournal- Default:
mmap,lz4,zstd - Optional:
xz: enable XZ decompressiontracing: emit diagnostics viatracing(caller installs a subscriber)tokio: provides an async follow adapterverify-seal: verify Forward Secure Sealing (TAG/FSS) with a systemd verification key
use sdjournal::Journal;
let journal = Journal::open_default()?;
let mut q = journal.query();
q.match_exact("_SYSTEMD_UNIT", b"sshd.service");
q.since_realtime(0);
for item in q.iter()? {
let entry = item?;
if let Some(msg) = entry.get("MESSAGE") {
println!("{}", String::from_utf8_lossy(msg));
}
}
# Ok::<(), sdjournal::SdJournalError>(())An end-to-end example that persists the last cursor and resumes via after_cursor is in:
examples/checkpoint_follow.rs
Run it on Linux:
cargo run --example checkpoint_follow -- sshd.service /var/tmp/sdjournal.cursorTo understand the crate quickly, read or run these examples in order:
tour: guided walkthrough ofJournal,JournalQuery,EntryRef/EntryOwned,Cursor, andFollowtail: the smallest “open default journal and read entries” pathmatch_unit: the most common production filter shapecheckpoint_follow: resume-safe follow loop for long-running consumers
Open / discovery:
tour: guided API overview and mental modelopen_dir: open one journal directory and print entriesopen_dirs: merge multiple journal rootsopen_with_config: customizeJournalConfig
Query builder patterns:
tail: print the newest entries from the default journalfilter_exact: query by an exact field/value pairmatch_present: query by field presencematch_unit: query one systemd unitor_units: OR across two units withor_grouprecent_unit: query a unit within a recent time windowprint_fields: dump all fields from the newest matching entrycollect_owned: detach results intoEntryOwned
Cursor / resume:
cursor_roundtrip: print a cursor and resume from it withseek_cursorafter_cursor: resume strictly after a saved cursor stringcheckpoint_follow: persist cursors while following
Streaming / integration:
follow_unit: block and print a few newly appended entriesfollow_tokio: use the Tokio follow adapter (--features tokio)verify_seal: verify FSS tags (--features verify-seal)