# What Process Metrics Does witr Collect in Verbose Mode? A Deep Dive into Extended Process Telemetry

> Discover the extended process telemetry collected by witr in verbose mode. Explore detailed memory, I/O, file descriptors, threads, capabilities, and env vars.

- Repository: [Pranshu Parmar/witr](https://github.com/pranshuparmar/witr)
- Tags: deep-dive
- Published: 2026-08-10

---

**When you run witr with `--verbose`, it augments basic process snapshots with nine categories of extended metrics including detailed memory breakdown, I/O counters, open file descriptors with paths, thread counts, capabilities, and environment variables.**

The witr process inspector (available at `pranshuparmar/witr`) provides two output modes: a default minimal view and an expanded verbose mode triggered by the `--verbose` flag. The verbose implementation gathers comprehensive process telemetry through platform-specific extended collectors, making it invaluable for debugging resource leaks, analyzing I/O patterns, and auditing process security configurations.

## How Verbose Mode Works Internally

The verbose pipeline follows a clear data flow through the codebase.

**Flag Parsing** — In [`internal/app/app.go`](https://github.com/pranshuparmar/witr/blob/main/internal/app/app.go), witr parses the `--verbose` flag and propagates the boolean through the inspection pipeline.

**Data Collection** — The `model.Process` struct in [`pkg/model/process.go`](https://github.com/pranshuparmar/witr/blob/main/pkg/model/process.go) defines fields for both basic and extended metrics. When verbose mode is active, platform-specific collectors populate the extended fields.

**Rendering** — In [`internal/output/standard.go`](https://github.com/pranshuparmar/witr/blob/main/internal/output/standard.go) (lines 348–349), the `RenderStandard` function checks `if verbose { … }` and prints the extended field set.

## Complete List of Verbose Mode Metrics

### MemoryInfo (Memory)

The **MemoryInfo** metric provides granular memory statistics in both bytes and megabytes:

- Virtual memory size (VMS)
- Resident set size (RSS)
- Shared memory
- Code/text segment
- Libraries
- Data + stack
- Dirty pages

Source: [`pkg/model/process.go`](https://github.com/pranshuparmar/witr/blob/main/pkg/model/process.go), lines 58–68

```bash

# Example verbose memory line

Memory: VMS=1.4GB RSS=450MB Shared=100MB Text=30MB Lib=50MB Data=320MB Dirty=0KB

```

### IOStats (IO)

The **IOStats** metric captures process-level I/O activity:

- Bytes read
- Bytes written
- Read operations
- Write operations

Source: [`pkg/model/process.go`](https://github.com/pranshuparmar/witr/blob/main/pkg/model/process.go), lines 70–76

### File Descriptor Telemetry

witr collects three related metrics for file descriptor analysis:

| Metric | Description | Source Location |
|--------|-------------|---------------|
| **FileDescs** | List of open file descriptors with target paths (e.g., `3 → /var/lib/mysql/mysql.sock`) | [`internal/proc/extended_linux.go`](https://github.com/pranshuparmar/witr/blob/main/internal/proc/extended_linux.go), lines 77–86 |
| **FDCount** | Total count of open file descriptors | Same file, line 79 |
| **FDLimit** | Soft limit on file descriptors from `/proc/[pid]/limits` | Same file, line 89 |

### Children

The **Children** field contains a slice of child PIDs discovered during process tree traversal. This is passed through the inspection pipeline.

Source: [`pkg/model/process.go`](https://github.com/pranshuparmar/witr/blob/main/pkg/model/process.go), line 53

### ThreadCount

The **ThreadCount** metric reads from `/proc/[pid]/status` to report the number of threads the process maintains.

Source: [`internal/proc/extended_linux.go`](https://github.com/pranshuparmar/witr/blob/main/internal/proc/extended_linux.go), lines 91–99

### Capabilities and Environment

Two fields are **always collected** but only displayed in verbose mode:

- **Capabilities** (`Capabilities`): Linux capability strings such as `CAP_NET_BIND_SERVICE` and `CAP_SYS_ADMIN`
- **Env** (`Env`): Complete environment variable list as `key=value` pairs

Sources: [`pkg/model/process.go`](https://github.com/pranshuparmar/witr/blob/main/pkg/model/process.go), lines 44 and 38

## Platform-Specific Implementation

The extended metric collection lives in platform-specific files:

- **Linux**: [`internal/proc/extended_linux.go`](https://github.com/pranshuparmar/witr/blob/main/internal/proc/extended_linux.go) — reads `/proc` filesystem
- **FreeBSD**: [`internal/proc/extended_freebsd.go`](https://github.com/pranshuparmar/witr/blob/main/internal/proc/extended_freebsd.go)
- **macOS**: [`internal/proc/extended_darwin.go`](https://github.com/pranshuparmar/witr/blob/main/internal/proc/extended_darwin.go)

All implement the same `ReadExtendedInfo` pattern to populate the `model.Process` struct.

## Practical Usage Examples

### Basic Verbose Inspection

```bash

# Inspect a MySQL process with full telemetry

witr mysql --verbose

```

### Machine-Readable Output

```bash

# Combine verbose with JSON for programmatic analysis

witr mysql --verbose --json > mysql_verbose.json

```

The JSON output contains all extended fields under the `process` object: `memory`, `io`, `fileDescs`, `fdCount`, `fdLimit`, `children`, `threadCount`, `capabilities`, and `env`.

### Sample Verbose Output

```

Process     : mysqld (pid 1234) {forked}
User        : mysql
Started     : 2h ago (2024-01-30 14:22:10)
...
Memory      : VMS=1.4GB RSS=450MB Shared=100MB Text=30MB Lib=50MB Data=320MB Dirty=0KB
IO          : ReadBytes=12MiB WriteBytes=45MiB ReadOps=312 WriteOps=87
FDCount     : 42  FDLimit: 1024
FileDescs   : 0 → /dev/null
              1 → /dev/null
              2 → /dev/null
              3 → /var/lib/mysql/mysql.sock
...
Children    : [1245 1246]
ThreadCount : 18
Capabilities: [CAP_NET_BIND_SERVICE CAP_SYS_ADMIN]
Env         : [PATH=/usr/local/sbin:… LANG=en_US.UTF-8 …]

```

## Summary

- **Verbose mode** activates nine extended metric categories via the `--verbose` flag
- **MemoryInfo** delivers byte-level memory breakdown (VMS, RSS, shared, text, libraries, data, dirty pages)
- **IOStats** tracks read/write bytes and operation counts
- **File descriptor metrics** include open FD list with paths, total count, and system limits
- **ThreadCount** reports active threads from `/proc/[pid]/status`
- **Children** exposes the process's PID descendants
- **Capabilities and Environment** are always captured, displayed only in verbose mode
- Core implementation spans [`pkg/model/process.go`](https://github.com/pranshuparmar/witr/blob/main/pkg/model/process.go), `internal/proc/extended_*.go`, and [`internal/output/standard.go`](https://github.com/pranshuparmar/witr/blob/main/internal/output/standard.go)

## Frequently Asked Questions

### How do I enable verbose mode in witr?

Pass the `--verbose` flag to any witr command. For example: `witr nginx --verbose`. The flag is parsed in [`internal/app/app.go`](https://github.com/pranshuparmar/witr/blob/main/internal/app/app.go) and propagated through the inspection pipeline to trigger extended metric collection and rendering.

### Does verbose mode work on macOS and FreeBSD?

Yes. Platform-specific collectors in [`internal/proc/extended_darwin.go`](https://github.com/pranshuparmar/witr/blob/main/internal/proc/extended_darwin.go) (macOS) and [`internal/proc/extended_freebsd.go`](https://github.com/pranshuparmar/witr/blob/main/internal/proc/extended_freebsd.go) implement the same `ReadExtendedInfo` interface as the Linux version. The specific metrics available depend on what each operating system exposes through its native APIs.

### Can I export verbose metrics to JSON?

Absolutely. Combine `--verbose` with `--json` for structured output: `witr <process> --verbose --json`. The resulting JSON includes all extended fields—memory, I/O, file descriptors, thread count, children, capabilities, and environment—nested under the `process` object.

### What's the performance impact of verbose mode?

Verbose mode requires additional syscalls to read `/proc` files, parse status information, and enumerate file descriptors. For most single-process inspections, the overhead is negligible. When monitoring high-churn processes or running frequent polls, consider using default mode and selectively enabling verbose for deep-dive analysis.