Ignoring routes
NIGHTOWL_IGNORE_ROUTES takes a comma-separated list of patterns. A matching request is never stored, and neither are the queries, logs, cache events and other records it made:
- Patterns are matched against the route’s path, name and action.
*is the only wildcard and it spans/, and a leading slash is optional.upmatches Laravel’s/uphealth check route. - For Livewire, use the route name:
*livewire.updatematches Livewire 3 (default.livewire.update) and Livewire 4 (default-livewire.update), whilelivewire/*matches only Livewire 3’s path. - Exceptions thrown during an ignored request are still stored, and so are the jobs it dispatched and what those jobs recorded.
- The agent applies the list while draining, so set it in the
.envof the machine that runsnightowl:agentand restart the agent.
app_vitals.requests_ignored on /status).
In-code filtering
Use Nightwatch’s filtering API to stop recording inside a block of code:NIGHTOWL_IGNORE_ROUTES.
Sampling
Sampling is a Nightwatch setting, applied in your app before anything is sent. Every rate defaults to1.0, which keeps everything:
Context metadata
Attach custom key-value data to traces using Laravel’sContext facade (Laravel 11+):
5:ERROR, and a refused transmission loses the whole request’s telemetry, so keep context entries small and structured.
Good things to put in context:
- Tenant, workspace or organization ID.
- Feature flag decisions that affected this request.
- User role or permission set.
- Debugging flags you set temporarily during an incident.
Context: entries are passed through verbatim.
Context::add() doesn’t make logs searchable. On log lines, Laravel adds the context to the log’s extra data, which the Logs page doesn’t search. To find a log by a value, pass it in the log call itself, as in the next section.
Searching log context
The context you pass with a log, the array inLog::error('Payment failed', ['order_id' => 8412]), is shown on the log’s detail page, but the Logs page search box doesn’t match inside it by default. Log context is stored compressed, and PostgreSQL can’t decompress it while running a query, so the search falls back to the message and the page shows a “Narrowed search” note explaining that.
Set NIGHTOWL_LOG_CONTEXT_SEARCHABLE=true to store it uncompressed and make it searchable. It trades storage for that, and existing logs need converting. See Searchable log context for the sizing check and the conversion command.
Context search only covers a time range that starts at least 24 hours after the point where uncompressed context begins, to allow for clock differences between machines and drain delays. So after you turn the setting on, searching context starts working about a day later, and running php artisan nightowl:backfill-log-context moves that point back over your older logs. Until then the search matches the message only and says so.
Redaction
PII redaction lives inlaravel/nightwatch and runs inside your app’s PHP process before the payload is sent to the agent. Configure it in .env:
NIGHTWATCH_REDACT_HEADERS strips named headers from every request record. NIGHTWATCH_REDACT_PAYLOAD_FIELDS recursively replaces matching keys in the request payload with a [N bytes redacted] marker. Both are applied when the record is built, so the agent’s TCP buffer, its SQLite buffer and PostgreSQL never see the unredacted values.
Note: Nightwatch writes the request payload only for HTTP 500 responses, only when NIGHTWATCH_CAPTURE_REQUEST_PAYLOAD=true (it’s off by default), and only for application/json and form-encoded bodies. It never writes response bodies. To capture payloads for other statuses, or response bodies, see Request payloads and response bodies.
Combining the layers
A common production setup:Nightwatch::ignore() around bulk jobs you don’t need traced, and Context::add() for tenant IDs.