tracing-calltree 0.1.2

Always-on hierarchical profiling for Rust tracing spans with rolling latency statistics.
Documentation
use std::time::Duration;
use tracing_calltree::CallTree;
use tracing_subscriber::prelude::*;

#[test]
fn rolling_window_tracks_recent_samples_only() {
    let calltree = CallTree::builder().window_size(100).build();
    let subscriber = tracing_subscriber::registry().with(calltree.layer());

    tracing::subscriber::with_default(subscriber, || {
        for nanos in 1..=150_u64 {
            let span = tracing::info_span!("query");
            let guard = span.enter();
            std::thread::sleep(Duration::from_nanos(nanos));
            drop(guard);
        }
    });

    let snapshot = calltree.snapshot();
    let node = &snapshot.roots[0];

    assert_eq!(node.total_calls, 150);
    assert_eq!(node.wall.samples, 100);
    assert!(node.wall.min > Duration::ZERO);
}

#[test]
fn cardinality_limits_reject_extra_nodes_without_panicking() {
    let calltree = CallTree::builder().max_nodes(2).build();
    let subscriber = tracing_subscriber::registry().with(calltree.layer());

    tracing::subscriber::with_default(subscriber, || {
        tracing::info_span!("one").in_scope(|| {});
        tracing::info_span!("two").in_scope(|| {});
        tracing::info_span!("three").in_scope(|| {});
    });

    let stats = calltree.internal_stats();
    assert_eq!(stats.nodes, 2);
    assert!(stats.rejected_nodes >= 1);
}