#logging #capture

logcap

A library for capturing log output

4 releases

0.1.3 Sep 14, 2025
0.1.2 Sep 14, 2025
0.1.1 Sep 6, 2025
0.1.0 Sep 2, 2025

#371 in Debugging

Download history 1437/week @ 2025-10-14 1172/week @ 2025-10-21 1239/week @ 2025-10-28 772/week @ 2025-11-04 893/week @ 2025-11-11 776/week @ 2025-11-18 861/week @ 2025-11-25 729/week @ 2025-12-02 805/week @ 2025-12-09 646/week @ 2025-12-16 663/week @ 2025-12-23 397/week @ 2025-12-30 675/week @ 2026-01-06 1152/week @ 2026-01-13 1050/week @ 2026-01-20 671/week @ 2026-01-27

3,659 downloads per month

MIT license

27KB
526 lines

logcap

A Rust crate for capturing application log output for integration testing.

The logger can have a threaded scope to capture logs from a thread, or with a process scope to capture across all threads.

See the documentation. Crate: https://crates.io/crates/logcap.

Examples

Capture logs within a thread

use log::{info, Level};
use logcap::assert_logs;

#[test]
fn test_logs() {
    logcap::setup();

    // test logic outputting logs
    info!("foobar");
    info!("moocow");
    info!("hello, world!");

    // make assertions on logs
    assert_logs!(
        "foobar",
        "^m.*w$",
        (Level::Info, "hello, world!")
    );
}

Capture logs across threads

Run tests with --test_threads=1 to avoid clobbering logs between tests, or use a mutex for synchronization.

use log::{LevelFilter,warn};
use logcap::{assert_logs, CaptureScope};

#[test]
fn test_logs() {
    logcap::builder()
        .scope(CaptureScope::Process)
        .max_level(LevelFilter::Trace)
        .setup();

    // test multi-threaded logic outputting logs
    warn!("warning from main thread");
    let _ = thread::spawn(|| warn!("warning from thread 1")).join();
    let _ = thread::spawn(|| warn!("warning from thread 2")).join();

    // make assertions on logs
    logcap::consume(|logs| {
        assert_eq!(3, logs.len());
        assert!(logs.iter.find(|log| log.body.contains("thread 1")).is_some());
        assert!(logs.iter.find(|log| log.body.contains("thread 2")).is_some());
        assert!(logs.iter.find(|log| log.body.contains("main thread")).is_some());
    });
}

Dependencies

~2–3MB
~53K SLoC