proc-tree 0.5.0

Linux process tree: snapshot, incremental maintenance via fork/exec events, ancestry chain queries, PID reuse detection
Documentation

proc-tree

Linux process tree — snapshot from /proc, incremental maintenance via fork/exec/exit events, ancestry chain queries, and pstree-style display.

Crates.io Docs.rs License: MIT CI

Overview

proc-tree provides a unified interface for maintaining a Linux process tree with O(1) child lookups, incremental updates from process events, and ancestry chain queries. It supports both one-shot snapshots from /proc and real-time updates via fork/exec/exit events, with PID reuse detection and thread-safe storage.

Why proc-tree?

Unlike simple process listing tools that only show a point-in-time snapshot, proc-tree maintains an in-memory process tree that can be incrementally updated as processes fork, exec, and exit. This makes it ideal for tools that need to track process hierarchies over time, build ancestry chains, or find processes by name or user. The library's unified storage interface and zero-allocation iteration patterns make it suitable for high-performance system monitoring applications.

Usage

Add to your Cargo.toml:

[dependencies]
proc-tree = "0.5.0"

Requirements

  • Linux with /proc filesystem
  • No special capabilities required for snapshot mode
  • CAP_NET_ADMIN for real-time event updates via proc-connector

Quick start

use proc_tree::{DefaultStore, snapshot, resolve, display};

let store = DefaultStore::new(600);  // TTL in seconds
snapshot(&store).expect("failed to read /proc");

// Resolve any PID
let info = resolve(&store, 1).unwrap();
println!("PID 1: {} ({})", info.comm(), info.user());  // "systemd" (binary name)
println!("PID 1 cmd: {}", info.cmd());  // "/usr/lib/systemd/systemd --user" (full cmdline)

// Render pstree-style tree
println!("{}", display(&store, 1));

Process matching

Use comm() for process tree matching — it returns the binary name from /proc/pid/comm:

use proc_tree::{DefaultStore, snapshot, is_descendant, find_by_cmd};

let store = DefaultStore::new(600);
snapshot(&store).expect("failed to read /proc");

// Check if current process is a descendant of "bash"
let my_pid = std::process::id();
if is_descendant(&store, my_pid, "bash") {
    println!("Running under bash");
}

// Find all bash processes
let bash_pids = find_by_cmd(&store, "bash");

Ancestry chains

build_chain_string() returns a JSON array, build_chain_links() returns Vec<ProcessLink>:

use proc_tree::{DefaultStore, snapshot, build_chain_string, build_chain_links};

let store = DefaultStore::new(600);
snapshot(&store).expect("failed to read /proc");

let my_pid = std::process::id();

// JSON string (for logging / serialization)
let json = build_chain_string(&store, my_pid);
println!("{}", json);
// [{"pid":1234,"comm":"touch","cmd":"touch /tmp/foo","user":"root"}, ...]

// Structured data (for programmatic access)
let links = build_chain_links(&store, my_pid);
for link in &links {
    println!("{} ({})", link.comm(), link.user());
}

Serde support

serde feature is enabled by default — ProcessInfo and ProcessLink support Serialize/Deserialize:

[dependencies]
proc-tree = "0.5.0"

To disable:

[dependencies]
proc-tree = { version = "0.5.0", default-features = false }