This page covers the Nette side of the dumpio/client package. Read the PHP library page first for the basics (dio(), Dumpio::dump(), typed helpers) — everything there works in Nette too. Here we add the Dumpio DI extension and its automatic capture.
Setup
Register the extension — dev-only is recommended, so put it in the config your development environment loads:
# config/common.neon (or config/local.neon, loaded only in dev)extensions: dumpio: Dumpio\Nette\DumpioExtensionThat single line is enough. Everything else has a default, and the connection settings fall back to the environment:
| Env var | Default | Meaning |
|---|---|---|
DUMPIO_HOST |
localhost |
Where the Dumpio app listens |
DUMPIO_PORT |
21234 |
The port |
DUMPIO_TOKEN |
"" |
Shared token, if the app requires one |
DUMPIO_DISABLE |
(unset) | Set it to turn the client off |
You can also set them in NEON, which wins over the environment:
dumpio: host: localhost port: 21234 token: secret enabled: %debugMode%Why the env fallback matters. Nette compiles the DI container once and caches it. Anything you write in NEON is baked into that cached container; anything you leave out is resolved on every container creation, from the environment. So keep per-machine values (host, port, token) in the environment — or at least out of the config you commit — and the same cached container works for everyone.
What it captures automatically
Once the extension is registered it wires itself into the services your application actually has. Nothing here needs code changes.
| Condition | What it forwards | Dump type / channel |
|---|---|---|
| nette/application | Unhandled exceptions (Application::$onError), with request context |
exception |
| nette/application | Every request opens a correlation scope (METHOD /path) |
— (metadata) |
| nette/database | Every executed SQL statement (SQL + bindings + timing) | query (database) |
| tracy/tracy | Everything Tracy logs — exceptions, warnings, Debugger::log() |
exception / log (tracy) |
nette/mail + listenMail: true |
Every outgoing email, as a rendered preview | mail (mail) |
nette/caching + listenCache: true |
Cache hit / missed / written / forgotten / cleaned | event (cache) |
latte/latte + listenViews: true |
Each rendered template, with render time | measure (views) |
Exceptions
Two independent paths, because Nette reports errors in two different places:
Application::$onError— every exception that escapes a presenter is forwarded as anexceptiondump with the request context (URL, method, query, client IP) and the presenter class. It fires whether Tracy shows you a BlueScreen or an error presenter takes over.- Tracy's logger — the extension wraps
Tracy\Debugger's logger, so everything Tracy records also reaches the viewer: fatal errors, warnings Tracy promotes, exceptions thrown outside the application (bootstrap, CLI commands, cron) and anything you send throughDebugger::log()yourself.Throwables arrive asexceptiondumps, plain messages aslogdumps on thetracychannel, with the Tracy severity mapped onto the flag color.
The original logger keeps running exactly as before — Tracy still writes its log files and sends its emails. See the app's Exceptions page for how a parsed exception renders.
Requests
On every request the extension opens a correlation scope labelled METHOD /path (GET /users), and closes it when the application shuts down. Every dump made in between carries the same requestId, so the viewer can group a request's dumps into one collapsible unit instead of a flat stream. It costs nothing — it is metadata on dumps you were already sending, not extra dumps. Console commands have no request and stay ungrouped.
Turn it off with stampRequests: false.
Database queries
Each Nette\Database\Connection in the container gets an onQuery listener that forwards every executed statement as a query dump on the database channel: the SQL, the bound parameters and the execution time. A multi-database app gets one listener per connection, and the connection name (default, analytics, …) rides along on every dump so you can tell them apart.
Failed statements are forwarded too, in red, carrying the driver error — so a broken query is visible right next to the ones that worked, instead of only in the BlueScreen.
Note that Nette's SQL preprocessor inlines values like dates into the statement itself before it reaches PDO; the dump shows the statement Nette actually ran, plus whatever stayed a real bound parameter.
dumpio: listenMail: trueThe extension puts a decorator in front of your Nette\Mail\Mailer (the same shape Nette's own Interceptor uses), and every outgoing message is previewed in the viewer as a mail dump: rendered HTML and text, subject, from/to/cc/bcc and the attachment list, rendered in the viewer's sandboxed iframe. Delivery is untouched — the message goes to your real mailer exactly as before.
Add interceptMail: true and the real send is swallowed instead (Mailpit-style): dev mail lands in Dumpio only and never reaches a real mailbox.
Off by default, because email payloads are large.
Cache
dumpio: listenCache: trueThe extension decorates Nette\Caching\Storage and forwards every operation as an event dump on the cache channel — cache.hit / cache.missed (with the key), cache.written, cache.forgotten and cache.cleaned. The decorator is a pure passthrough: it never changes what the cache returns and never throws into your app; only the telemetry is added. It implements BulkReader as well, so decorating doesn't cost Cache::bulkLoad() its fast path. This mirrors the Laravel and Symfony cache capture, so all three frameworks land the same shape in the viewer.
Off by default, because it sits in front of every cache call.
Latte templates
dumpio: listenViews: trueA Latte extension times every rendered template and forwards it as a measure dump on the views channel (template name + render time), so you can see which templates cost what.
Off by default, because it instruments every render.
Configuration reference
dumpio: # connection — omit to use DUMPIO_HOST / DUMPIO_PORT / DUMPIO_TOKEN / DUMPIO_DISABLE host: localhost port: 21234 token: '' enabled: %debugMode% stampRequests: true # group a request's dumps under one requestId listenExceptions: true # Application::$onError → exception dumps listenQueries: true # Nette Database → query dumps listenLogs: true # Tracy log → exception / log dumps listenMail: false # outgoing email → mail dumps interceptMail: false # …and swallow the real send listenCache: false # cache operations → cache.* events listenViews: false # Latte renders → measure dumpsSetting a capture to false removes its wiring from the compiled container entirely — no decorator, no listener. Leaving it out keeps the wiring in place and lets the runtime switches decide, which is what makes the toggles below work.
The listenMail / listenCache / listenViews defaults also read DUMPIO_LISTEN_MAIL, DUMPIO_LISTEN_CACHE and DUMPIO_LISTEN_VIEWS, so they can be flipped per machine without touching the config.
Turning capture on and off at runtime
Every capture checks its switch on each call, so you can narrow the stream from inside a presenter, a service, or a console command:
Dumpio::stopShowingQueries(); // quiet the query firehose for a moment$this->importer->run();Dumpio::showQueries(); // and back on Dumpio::showAll(); // everything onDumpio::stopShowingAll(); // everything offThere's a show…() / stopShowing…() pair for Queries, Exceptions, Logs, Mail, Cache, and Views.
Manual dumps anywhere
The static client and global helpers work from anywhere in your code, independent of the automatic capture:
\Dumpio\Dumpio::query($sql, $bindings, $timeMs);dumpio($entity, 'entity');dio($order)->green()->channel('checkout');Unlike Tracy's dump() and bdump(), they don't need a rendered page or the Tracy bar — a dump from a presenter, a CLI command, a queue worker or an AJAX snippet all land in the same viewer. See the PHP library page for the full set of helpers.