Process & worker metrics

Queue counters, process snapshots, and per-worker task timings — collected automatically, with no extra setup.

KioMQ collects three kinds of metrics in the background. Queue counters are in-memory and free to read; process and worker metrics are published to the store with a TTL and refreshed by the queue’s timer subsystem.

Queue counters

queue.current_metrics is a cheap, always-live handle. The counters are refreshed from the store whenever get_metrics() is called, so between calls they may be slightly stale — prefer the helper methods over reading raw fields.

let metrics = queue.current_metrics.clone();

metrics.all_jobs_completed(); // nothing left to do
metrics.is_idle();            // no work and no active jobs
metrics.has_active_jobs();    // at least one job in flight
metrics.has_delayed();        // something is scheduled for later
metrics.queue_has_work();     // jobs waiting or prioritised
metrics.queue_is_paused();    // paused flag
metrics.workers_idle();       // every worker is parked

// Pull fresh counts from the store.
let snapshot = queue.get_metrics().await?;

These are the right tool for graceful shutdown and for tests that need to wait until the queue drains.

Process metrics

A process-level snapshot, refreshed every PROCESS_METRIC_UPDATE_INTERVAL milliseconds and stored with a TTL. Snapshots are keyed by PID, so a multi-process deployment stays distinguishable.

// keyed by PID so multi-process deployments can be distinguished
let snapshots: std::collections::BTreeMap<u32, kiomq::ProcessMetrics> =
    queue.fetch_proess_metrics().await?;

if let Some(m) = snapshots.values().next() {
    println!(
        "cpu: {:.1}%  mem: {} MB  tokio workers: {}",
        m.process_cpu_usage,
        m.memory_usage / 1_024 / 1_024,
        m.rt_metrics.workers_count,
    );
}

Each snapshot captures:

FieldWhat it holds
process_cpu_usageCPU usage of the process tree, as a percentage
memory_usageResident set size in bytes
memory_statsHeap allocator statistics via the built-in Heapster instrumented allocator
rt_metricsTokio runtime counters — thread count, live tasks, park counts, busy durations (RawRuntimeMetrics)
workersVec<WorkerMeta>: state, options, and active-job count for every registered worker
hostname / pidProcess identity
Note

fetch_proess_metrics is spelled with that typo in the public API. It is kept as-is for backwards compatibility.

Worker metrics

Fine-grained, per-worker timing data for every in-flight job — useful for latency profiling and capacity planning. Workers publish theirs every metrics_update_interval milliseconds (default 100).

let worker_metrics = queue.fetch_worker_metrics().await?;

for (worker_id, wm) in &worker_metrics {
    for task in &wm.tasks {
        println!(
            "worker {worker_id}  polls={}  idle={:?}",
            task.metrics.total_poll_count,
            task.metrics.total_idle_duration,
        );
    }
}

The per-task numbers come from tokio-metrics , so you get poll counts, idle durations, and scheduling delays for each job the worker is running.

Exporting

Both fetch_* methods return plain maps, which makes wiring them into an exporter straightforward — scrape them from a background task and publish to whatever your stack uses:

tokio::spawn({
    let queue = queue.clone();
    async move {
        let mut tick = tokio::time::interval(std::time::Duration::from_secs(15));
        loop {
            tick.tick().await;
            if let Ok(snapshots) = queue.fetch_proess_metrics().await {
                for (pid, m) in snapshots {
                    gauge!("kiomq.cpu", "pid" => pid.to_string()).set(m.process_cpu_usage);
                    gauge!("kiomq.rss", "pid" => pid.to_string()).set(m.memory_usage as f64);
                }
            }
            if let Ok(counters) = queue.get_metrics().await {
                gauge!("kiomq.idle").set(u8::from(counters.is_idle()));
            }
        }
    }
});

With RedisStore, metrics land in Redis with a TTL — so a separate dashboard process can read the fleet’s numbers without running a worker of its own.

Storing your own snapshots

The store methods are public, should you want to publish metrics from code the workers don’t own:

queue.store_worker_metrics(metrics, 30_000).await?;   // ttl in ms
queue.store_process_metrics(snapshot, 30_000).await?;
Esc

Type to search the docs.