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 onsys.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 beforesys.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:
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
@trackto 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 spanname, …).
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
recordinglimits (max_value_repr,max_collection_items,max_depth), so a huge object graph can’t bloat your timeline.
exclude the module, or set capture_args/capture_results to false globally and re-enable per function with @track.