witr

witr

Trace why a process is running

Description

The deploy script dies with EADDRINUSE because something holds port 8000, and what follows is the usual manual labour: `lsof -i :8000` for the PID, `ps -ef` for the command line, walk up the parents, find a node process, then work out which systemd unit owns it and remember there is a PM2 layer in between. Four or five tools stitched together to answer one question: what started this. witr prints the whole chain at once. `witr --port 8000` returns systemd → PM2 → node with the PID, start time, working directory and unit file of every link.

Its premise is that everything is a process question: ports, services, containers and file locks all resolve to a PID, and from a PID it reconstructs the causal chain. Queries are loose, a bare process name, `--port` for a port, `--pid`, `--file` for a held file, `--container` for a container, and the flags mix freely. Output comes in four shapes: the full report, a one-line chain with `--short`, a tree with `--tree`, and `--json` for scripts.

Running `witr` with no arguments opens an interactive TUI with four tabs for processes, ports, containers and locks. Lists sort and filter, a side panel shows the ancestry of whatever is highlighted, and the containers tab merges everything running under Docker, Podman, containerd, Kubernetes, LXC, LXD and FreeBSD jails into one table. Selected processes can be signalled or reniced in place, the mouse works, and colours adapt to a light or dark terminal.

It ships as a single static Go binary for Linux, macOS, Windows and FreeBSD and is packaged in Homebrew, apt, conda, the AUR, winget and MacPorts. The project site also hosts a browser sandbox that walks through real investigations on a simulated Linux box with nothing installed. Apache-2.0.

Features



Causal chain output: One command prints the full start chain from init down to the target, annotating each link with PID, start method and source.

Many query targets: Look up by process name, PID, port, held file or container; flags repeat and combine for several targets at once.

Interactive TUI: Processes, ports, containers and locks tabs with live refresh and a side panel showing the selected item's ancestry.

Full container coverage: Docker, Podman, nerdctl, Kubernetes/crictl, Incus, LXC, LXD and FreeBSD jails collected into one list.

Process details: Drill into child processes, environment variables, working directory, sockets and file context.

Process actions: Send Kill, Terminate, Pause and Resume signals or renice straight from the TUI on Unix.

File lock view: System wide file locks, with a key to switch into an all open files mode.

Output formats: Full report, one-line chain, ancestry tree and JSON for scripting.

Single static binary: Built in Go with no runtime dependencies for Linux, macOS, Windows and FreeBSD, packaged in the major package managers.

Browser sandbox: The project site runs a simulated Linux box with a guided tutorial and free play, no install required.