Skip to main content
Auto-tracing is on by default. After enable(), slomo records every function call in your project code — enter, arguments, exit, result, duration, and any exception that escapes — with no decorators, no imports in your modules, no code changes beyond the one enable() call.

How it works

Auto-tracing is built on sys.monitoring (PEP 669), the low-overhead monitoring API introduced in Python 3.12 — the reason slomo requires 3.12+. What counts as project code: files under the directory containing .slomo/ (your project root). Everything else — the standard library, site-packages, and slomo itself — is not just filtered; it is switched off inside the interpreter after its first call via PEP 669’s per-code-object DISABLE, so foreign code costs effectively nothing after warm-up. For each project function call, slomo emits:

Why this matters for web frameworks

Frameworks convert exceptions into 500 responses before sys.excepthook can see them. Auto-tracing records the exception the moment it escapes your handler function — so those 500s land in slomo issues with args, locals, and the SQL/HTTP calls that led up to them. See Web frameworks.

Tuning

Configure under [hooks.autotrace] in .slomo/config.toml:
Kill it entirely for one run with an environment variable:
capture_args = false / capture_results = false keep the call tree and durations while dropping the values — useful when values are large or sensitive beyond what redaction covers.

Interaction with @track

Functions decorated with @track are never recorded twice. Tracked code objects are registered by identity, and auto-trace defers to the decorator — so you can freely mix the two:
  • Use auto-trace for blanket coverage of project code.
  • Use @track to force-trace code outside the project root (a shared internal library, for example), or to take control of capture per function (capture_args=False, a custom span name, …).

Overhead notes

  • Foreign code (stdlib, dependencies) is disabled at the interpreter level after first hit — near-zero steady-state cost.
  • Project-code events go through the same lock-free queue as everything else; the writer thread batches to disk off your critical path.
  • Value capture is bounded by the recording limits (max_value_repr, max_collection_items, max_depth), so a huge object graph can’t bloat your timeline.
For hot loops where even bounded capture is too much, exclude the module, or set capture_args/capture_results to false globally and re-enable per function with @track.