Skip to main content

proc_watch/
proc_watch.rs

1//! Simple process event monitor.
2//!
3//! Prints all process events as they happen.
4//! Requires root or `CAP_NET_ADMIN` to run.
5//!
6//! Usage:
7//! ```sh
8//! cargo run --example proc_watch
9//! ```
10//!
11//! Example output:
12//! ```text
13//! [2026-05-11T21:30:00Z] EXEC pid=1234 tgid=1234
14//! [2026-05-11T21:30:01Z] FORK parent=(1000,1000) child=(1235,1235)
15//! [2026-05-11T21:30:05Z] EXIT pid=1235 tgid=1235 code=0 signal=17
16//! ```
17
18use proc_connector::ProcConnector;
19use std::time::Instant;
20
21fn main() {
22    // Create connector (requires root / CAP_NET_ADMIN)
23    let conn = ProcConnector::new().expect("failed to create proc connector (try as root)");
24    let mut buf = vec![0u8; 4096];
25
26    println!("listening for process events... (Ctrl+C to stop)");
27
28    // Example 1: blocking recv loop
29    loop {
30        match conn.recv(&mut buf) {
31            Ok(event) => {
32                let now = humantime_or_iso(Instant::now());
33                println!("[{now}] {event}");
34            }
35            Err(e) => {
36                eprintln!("recv error: {e}");
37                break;
38            }
39        }
40    }
41}
42
43/// Format an Instant as a human-readable timestamp.
44fn humantime_or_iso(instant: Instant) -> String {
45    // Simple ISO-like timestamp since process start
46    let secs = instant.elapsed().as_secs();
47    let hours = secs / 3600;
48    let mins = (secs % 3600) / 60;
49    let secs = secs % 60;
50    format!("{:02}:{:02}:{:02}", hours, mins, secs)
51}