Skip to main content

proctrace

Non-invasive process and OS state introspection for Python developers.

Diagnose memory leaks, file descriptor leaks, race conditions, and IPC bottlenecks with a single import — no agents, no profilers, no code changes required.

Built on a Rust core exposed to Python via PyO3 and Maturin.

Status: Under construction.
Platform support: Linux ✓ · macOS ✓ · Windows ✗
Python: ≥ 3.10
License: MIT


Installation

pip install proctrace

Or to build from source (requires Rust + maturin):

pip install maturin
maturin develop --release

Quick Start

Context manager

import proctrace

with proctrace.watch() as probe:
    your_code_here()

print(probe.result.report())

Sample output:

┌─ proctrace ResourceDelta ──────────────────────────────────┐
│  memory rss      +12.34 MB                                 │
│  memory peak     +45.00 MB                                 │
│  virtual mem     +8.00 MB                                  │
│  open fds        +3                                        │
│  threads         +2 (new: worker-1, worker-2)              │
│  child procs     +0                                        │
│  elapsed         142.5 ms                                  │
└────────────────────────────────────────────────────────────┘

Decorator

from proctrace.decorators import probe

@probe(memory=True, fds=True, output="stderr")
def load_data(path):
    ...

load_data("big_file.csv")
# ResourceDelta printed to stderr automatically

# Access the result programmatically
result = load_data.last_probe_result
print(result.rss_delta_mb)

Works on both regular and async functions.


API Reference

proctrace.watch(...)ResourceWatcher

Returns a context manager that snapshots OS resources before and after the block.

Parameter Type Default Description
memory bool True Track RSS / VMS memory
fds bool True Track open file descriptors
threads bool True Track thread count and names
children bool True Track child process count
sample_interval float 0.1 Background sampler interval in seconds (for peak RSS)

After the with block, probe.result is a ResourceDelta.

ResourceDelta

Attribute Type Description
rss_delta_bytes int RSS change in bytes (can be negative)
vms_delta_bytes int Virtual memory size change
fd_delta int Open FD count change
peak_rss_bytes int Highest RSS seen during the block
thread_delta int Thread count change
child_delta int Child process count change
elapsed_ns int Wall-clock time of block in nanoseconds
leaked_fds list[str] FD paths present at exit but not at entry
new_thread_names list[str] Names of threads created during the block

Convenience properties: .rss_delta_mb, .vms_delta_mb, .peak_rss_mb, .elapsed_ms.

Serialization: .to_dict(), .to_json(indent=...), .from_dict(d).

@probe(...) decorator

from proctrace.decorators import probe

@probe(
    memory=True,
    fds=True,
    threads=True,
    children=False,
    sample_interval=0.05,
    output="stderr",  # or "none"
    store=True,       # stores result on fn.last_probe_result
)
def my_function(): ...

IPC Tracing

Wrap queues, pipes, and sockets to measure latency and throughput:

import queue, os
from proctrace.ipc import trace_ipc, trace_pipe, trace_socket, ipc_report

# Queues
q = trace_ipc(queue.Queue(), name="task-queue")
q.put(item)
item = q.get()

# OS pipes
r_fd, w_fd = os.pipe()
pipe = trace_pipe(r_fd, w_fd, name="my-pipe")
pipe.write(b"hello")
data = pipe.read(5)

# Sockets
sock = trace_socket(raw_socket, name="worker-conn")
sock.sendall(b"data")
response = sock.recv(1024)

# Print a report of all traced channels
print(ipc_report())

On-demand stack dumps

Install a signal handler to dump all threads and asyncio tasks to stderr on demand:

import proctrace

proctrace.install_signal_handler(sig="SIGUSR1")  # SIGUSR1, SIGUSR2, or SIGALRM

# From the terminal:
# kill -USR1 <pid>

Outputs a timestamped dump of every thread's stack trace plus any running asyncio tasks.


CLI

proctrace <subcommand> [options]

proctrace run — measure a subprocess

proctrace run -- python myscript.py
proctrace run --json -- python myscript.py   # JSON output to stdout

proctrace watch — live memory polling

proctrace watch --pid <PID> --interval 1.0 --duration 30

Prints a live-updating table of RSS and VMS (MB) for the target process.

proctrace dump — trigger a stack dump

proctrace dump --pid <PID> --signal SIGUSR1

Sends a signal to a running proctrace-instrumented process to trigger a thread dump.


Benchmarks

Measured on a quiet machine: single-threaded hot loop, 200,000 iterations of snapshot_resources(), which reads memory, FD count, and thread state in a single Rust call.

Snapshot latency

Operation Latency Throughput
snapshot_resources() 7.9 µs/call ~127k calls/s

Detection accuracy

Scenario: inside the measured region, allocate 64 MB, open 10 FDs, start 2 threads, and spawn 1 child process.

Metric Detected
RSS delta +64.3 MB
Open FD delta +10
Thread delta +2
Child process delta +1

Measured on: Linux 7.1.8 (x86_64, 12 cores), CPython 3.14, proctrace 0.1.0. Results vary by machine.


Development

# Create virtual environment
python -m venv .venv && source .venv/bin/activate

# Install dev dependencies and build the Rust extension
pip install -e ".[dev]"
maturin develop

# Run tests
pytest

Requires: Rust toolchain, Python ≥ 3.10.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

proctrace-0.1.0.tar.gz (67.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

proctrace-0.1.0-cp314-cp314-manylinux_2_34_x86_64.whl (267.2 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.34+ x86-64

File details

Details for the file proctrace-0.1.0.tar.gz.

File metadata

  • Download URL: proctrace-0.1.0.tar.gz
  • Upload date:
  • Size: 67.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for proctrace-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0879c09ffcc3946547aa50147012aa15f37d371f00022aa842b771ab19413b66
MD5 8e3b41d30d799529693fda179272d690
BLAKE2b-256 0dd6957a0dea4fa536e4f2d1fa72a444e2bddb1a1d35d037d9f1b9e901307981

See more details on using hashes here.

File details

Details for the file proctrace-0.1.0-cp314-cp314-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for proctrace-0.1.0-cp314-cp314-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 3f61d8ebf4f59e894a8fef8e8d89febfd36ad7a512bd682729745f7a64fc85e4
MD5 3410e1ab2ebdee77a286d5c1a617958a
BLAKE2b-256 bfda2eda52d6139c50c4706b1baae06415a6ab50582769fcb71d0362693b243e

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page