Understanding the witr JSON Output Schema: Complete Field Reference
The witr JSON output schema is defined by the model.Result struct in pkg/model/result.go, containing fields like Target, Process, Ancestry, and Warnings that describe process state, lineage, and system context.
When querying processes with witr (available at github.com/pranshuparmar/witr), the tool emits structured JSON that captures everything from process ancestry to container metadata. Understanding the witr JSON output schema is essential for building automation scripts, monitoring dashboards, or CI/CD integrations that consume process intelligence. The schema is implemented in Go and marshaled through helpers located in internal/output/json.go.
Core Schema Structure (model.Result)
The top-level JSON object corresponds to the Result type defined in pkg/model/result.go. Each field maps directly to a struct member, providing a comprehensive snapshot of the target process and its environment.
- Target (
model.Target): The original query supplied to witr, which could be a name, PID, port, file path, or container identifier. Defined inpkg/model/target.go. - ResolvedTarget (string): The concrete identifier actually resolved by the system (e.g., a PID discovered from a process name).
- Process (
model.Process): Detailed information about the primary matching process, including resource usage, environment variables, and execution context. - RestartCount (int): Number of times the process has been restarted, primarily used for container-runtime detection.
- Ancestry ([]
model.Process): Ordered list of parent processes, starting from the init/system process down to the immediate parent of the target. - Children ([]
model.Process): Direct child processes of the target. This field is omitted when empty (omitempty). - Source (
model.Source): Metadata about how the data was gathered, indicating which OS-specific backend provided the information. - Warnings ([]string): Array of non-fatal issues detected during collection, such as
high-cpuorzombiestates. - SocketInfo (*
model.SocketInfo): Network socket details for port-based queries, including state, protocol, and addresses. Omitted when not applicable. - ResourceContext (*
model.ResourceContext): macOS-specific resource-usage context, such as battery status and power source information. - FileContext (*
model.FileContext): File-descriptor and lock information for the target process, present only when querying file-related data.
The Process Object Deep Dive
The Process field, defined in pkg/model/process.go, contains the majority of the payload. This struct captures everything from basic identifiers to deep system introspection data.
Identification and Execution:
- PID, PPID: Process ID and parent process ID.
- Command, Cmdline: Executable name and full command-line string.
- Exe: Absolute path to the executable file.
- StartedAt: Timestamp indicating when the process began execution.
- User: Username owning the process.
- ExeDeleted: Boolean indicating if the executable file was removed after the process started.
Resource Utilization:
- CPUPercent: Current CPU usage percentage.
- MemoryRSS: Resident set size in bytes.
- MemoryPercent: Memory usage as a percentage of total system memory.
- Memory (
model.MemoryInfo): Detailed breakdown including VMS, RSS, shared, text, lib, data, and dirty pages. - IO (
model.IOStats): I/O statistics tracking bytes read/written and operation counts. - ThreadCount: Number of threads in the process.
Environment and Context:
- WorkingDir: Current working directory of the process.
- GitRepo, GitBranch: Associated Git repository and branch, if detectable.
- Env: Array of strings in
KEY=VALUEformat representing environment variables. - Capabilities: Linux capabilities (e.g.,
CAP_NET_BIND_SERVICE), omitted on non-Linux systems.
Container and Orchestration:
- Container, Service: Container name and service label when running inside orchestration platforms.
- ContainerID, ContainerRuntime, ContainerHealthcheck: Low-level container identification, runtime name (docker, podman, etc.), and health-check status. These are
omitemptyfields. - RestartCount: Tracked restarts for containerized processes.
Network and File Descriptors:
- Sockets ([]
model.Socket): List of network sockets owned by the process, including protocol, state, and local/remote addresses. - FileDescs ([]string): Paths of open file descriptors.
- FDCount (int), FDLimit (uint64): Current open file count and soft limit.
Status Indicators:
- Health: High-level status such as
healthy,zombie, orhigh-cpu. - Forked: Forking status indicating
forked,not-forked, orunknown.
Alternative JSON Output Formats
The internal/output/json.go file implements multiple marshaling helpers that reshape the Result struct for specific use cases. These are typically selected via CLI flags in cmd/witr/main.go.
- ToJSON: Returns the full
Resultstruct with all fields. This is the default machine-readable output. - ToShortJSON: Produces an array of simplified objects containing only
PIDandCommandfor the ancestry chain. Useful for quick lineage inspection. - ToTreeJSON: Returns a structure with
AncestryandChildrenarrays, where each entry containsPIDandCommand, formatted for tree-style visualization. - ToWarningsJSON: Filters the output to
{PID, Process, Command, Warnings}, ideal for alerting scripts that only care about anomalies. - ToEnvJSON: Exports
{PID, Process, Command, Env}, providing only the environment variables for the target process.
Working with the JSON Output
Here is an example of the default JSON structure returned by witr --json nginx:
{
"Target": {
"Name": "nginx",
"Type": "name"
},
"ResolvedTarget": "1234",
"Process": {
"PID": 1234,
"PPID": 1,
"Command": "nginx",
"Cmdline": "nginx: master process /usr/sbin/nginx",
"Exe": "/usr/sbin/nginx",
"User": "www-data",
"CPUPercent": 0.5,
"MemoryRSS": 10485760,
"WorkingDir": "/etc/nginx",
"Health": "healthy",
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
"NGINX_VERSION=1.24.0"
]
},
"Ancestry": [
{
"PID": 1,
"Command": "systemd"
}
],
"Warnings": []
}
To parse this output in Python for monitoring purposes:
import json
import subprocess
def get_process_info(name):
result = subprocess.run(
['witr', '--json', name],
capture_output=True,
text=True
)
data = json.loads(result.stdout)
proc = data['Process']
print(f"PID: {proc['PID']}, CPU: {proc['CPUPercent']}%, RSS: {proc['MemoryRSS']}")
if data['Warnings']:
print(f"Alerts: {', '.join(data['Warnings'])}")
return data
# Usage
info = get_process_info('nginx')
For ancestry-only extraction using the short format:
witr --short --json nginx | jq '.[] | {pid: .PID, cmd: .Command}'
Summary
- The witr JSON output schema centers on the
model.Resultstruct inpkg/model/result.go, providing a standardized wrapper for process intelligence. - Top-level fields cover target resolution (
Target,ResolvedTarget), process details (Process), lineage (Ancestry), and system anomalies (Warnings). - The Process object contains extensive metadata including resource metrics (
CPUPercent,MemoryRSS), Git context, container runtime details, and security capabilities. - Alternative output helpers (
ToShortJSON,ToTreeJSON,ToWarningsJSON,ToEnvJSON) allow consumers to extract specific slices of data without parsing the full schema. - All JSON generation is implemented in
internal/output/json.goand invoked based on CLI flags parsed incmd/witr/main.go.
Frequently Asked Questions
What Go struct defines the witr JSON output schema?
The Result struct in pkg/model/result.go defines the top-level schema, with the nested Process struct from pkg/model/process.go containing the detailed process information. These structs use JSON tags to control marshaling behavior and omitempty directives to keep the output clean.
How do I extract only the process ancestry in JSON format?
Use the ToShortJSON helper method, typically invoked via the --short flag. This outputs an array of objects containing only PID and Command fields, representing the process lineage from the init system down to your target process.
What does the ResolvedTarget field indicate?
ResolvedTarget contains the concrete system identifier that wirt actually queried after resolving your input. If you provided a process name like "nginx", this field contains the actual PID (e.g., "1234") that was found and inspected.
Are container-specific fields always present in the JSON output?
No, container fields such as ContainerID, ContainerRuntime, and ContainerHealthcheck are marked with omitempty JSON tags. They only appear in the output when witr detects the process is running inside a container runtime like Docker or Podman.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →