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.1.tar.gz (64.0 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.1-cp314-cp314-manylinux_2_34_x86_64.whl (269.3 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.34+ x86-64

File details

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

File metadata

  • Download URL: proctrace-0.1.1.tar.gz
  • Upload date:
  • Size: 64.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for proctrace-0.1.1.tar.gz
Algorithm Hash digest
SHA256 7bff7bc6c7cb2c08cd649ab167a9026b6494533ac51c35451000b1a74667d903
MD5 6b5da0bca4d181762d1531aad6d66960
BLAKE2b-256 d4996cb66ca87252c9fea066767235921c53c38b087a012dbcf710dd4622c88c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for proctrace-0.1.1-cp314-cp314-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 52ccd86720d76eee7cba3e62cc0fe9ed544a73af3fdfa2772b7a5ec4b36f3103
MD5 fb60bfb37fb1085db9643fca3b7b4754
BLAKE2b-256 441ee8e2c67dba0e81548413eb51e2d2bd6808cd3543e997b9102fd5b596e477

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

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