| name | nightwatch-configure |
| description | Configure Laravel Nightwatch data collection, sampling rates, filtering rules, and redaction policies. Use this when setting up Nightwatch, managing data volume, protecting sensitive data (PII), or optimizing event collection for production workloads. |
Nightwatch Configuration Guide
This skill helps configure Laravel Nightwatch data collection to balance observability, performance, and privacy. Covers sampling strategies, filtering rules, and redaction methods across all event types.
When to Use This Skill
Invoke when:
- Setting up Nightwatch for the first time
- Reducing data volume or event quota usage
- Protecting sensitive data (PII, credentials, tokens)
- Configuring production monitoring
- Optimizing for high-traffic applications
- Understanding filtering vs sampling vs redaction
Documentation Reference
The Nightwatch Documentation is the definitive and up-to-date source of information for all Nightwatch configuration options. This skill provides practical guidance and common patterns, but always consult the official documentation as the primary source of truth for specific details, environment variables, and API behavior. The documentation includes comprehensive coverage of:
- Filtering and Configuration - Core concepts for sampling, filtering, and redaction
- Individual event type pages with specific configuration options:
- Requests - Request sampling, header handling, payload capture
- Commands - Command sampling and redaction
- Queries - Query filtering and redaction
- Cache - Cache event filtering by key or pattern
- Jobs - Job filtering and sampling decoupling
- Mail - Mail event filtering
- Notifications - Notification filtering by channel
- Exceptions - Exception sampling and throttling
- Outgoing Requests - HTTP request filtering
Data Collection Flow
Nightwatch processes events through three stages:
- Sampling - Controls which entry points are captured (requests, commands, scheduled tasks)
- Filtering - Excludes specific events after sampling (queries, cache, mail, etc.)
- Redaction - Modifies captured data to remove/obfuscate sensitive information
Request/Command/Scheduled Task
|
v
[Sampling?] ----NO----> Drop entire trace
| YES
v
Events generated
|
v
[Filtering?] ----YES---> Drop specific event
| NO
v
[Redaction] ----------> Store modified data
Sampling Configuration
Sampling determines which entry points (requests, commands, scheduled tasks) trigger full trace collection. When an entry point is sampled, all related events are captured. For complete and authoritative information on all available sampling methods and environment variables, refer to the Requests documentation for HTTP request sampling and the Commands documentation for Artisan command sampling.
Global Sample Rates
Configure via environment variables:
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1
NIGHTWATCH_COMMAND_SAMPLE_RATE=1.0
NIGHTWATCH_EXCEPTION_SAMPLE_RATE=1.0
Recommendation: Start with 0.1 (10%) for requests in production, adjust based on volume and needs.
The full list of environment variables for sampling configuration and their default values can be found in the official Requests and Commands documentation pages.
Route-Based Sampling
Apply different rates to specific routes using the Sample middleware:
use Illuminate\Support\Facades\Route;
use Laravel\Nightwatch\Http\Middleware\Sample;
Route::middleware(Sample::rate(1.0))->prefix('admin')->group(function () {
});
Route::middleware(Sample::rate(0.05))->prefix('api')->group(function () {
});
Route::post('/checkout', [CheckoutController::class, 'process'])
->middleware(Sample::always());
Route::get('/health', [HealthController::class, 'check'])
->middleware(Sample::never());
Unmatched Route Sampling
Handle 404/bot traffic with reduced sampling:
Route::fallback(fn () => abort(404))
->middleware(Sample::rate(0.01));
Dynamic Sampling
Sample based on runtime conditions (user role, request attributes):
use Closure;
use Illuminate\Http\Request;
use Laravel\Nightwatch\Facades\Nightwatch;
class SampleAdminRequests
{
public function handle(Request $request, Closure $next)
{
if ($request->user()?->isAdmin()) {
Nightwatch::sample();
}
return $next($request);
}
}
Command Sampling
Exclude specific commands from sampling:
use Illuminate\Console\Events\CommandStarting;
use Illuminate\Support\Facades\Event;
use Laravel\Nightwatch\Facades\Nightwatch;
public function boot(): void
{
Event::listen(function (CommandStarting $event) {
if (in_array($event->command, ['schedule:finish', 'horizon:snapshot'])) {
Nightwatch::dontSample();
}
});
}
Vendor Commands
Nightwatch automatically ignores framework/internal commands. Opt-in to capture them:
Nightwatch::captureDefaultVendorCommands();
Filtering Configuration
Filtering excludes specific events from collection after sampling. Use filtering to reduce noise and quota usage. Each event type has specific filtering methods documented on its respective page. Refer to the Queries, Cache, Jobs, Mail, Notifications, and Outgoing Requests documentation for complete filtering options for each event type.
Database Queries
Filter all queries (disable query collection):
NIGHTWATCH_IGNORE_QUERIES=true
Filter specific queries by SQL pattern:
use Laravel\Nightwatch\Facades\Nightwatch;
use Laravel\Nightwatch\Records\Query;
public function boot(): void
{
Nightwatch::rejectQueries(function (Query $query) {
return str_contains($query->sql, 'into "jobs"');
});
Nightwatch::rejectQueries(function (Query $query) {
return str_contains($query->sql, 'from `cache`')
|| str_contains($query->sql, 'into `cache`');
});
}
Cache Events
Filter all cache events:
NIGHTWATCH_IGNORE_CACHE_EVENTS=true
Filter by cache key patterns:
Nightwatch::rejectCacheKeys([
'my-app:users', // Exact match
'/^my-app:posts:/', // Regex: starts with my-app:posts:
'/^[a-zA-Z0-9]{40}$/', // Regex: session IDs
]);
Filter with callback:
use Laravel\Nightwatch\Records\CacheEvent;
Nightwatch::rejectCacheEvents(function (CacheEvent $cacheEvent) {
return str_starts_with($cacheEvent->key, 'temp:');
});
Mail Events
Filter all mail:
NIGHTWATCH_IGNORE_MAIL=true
Filter specific mail:
use Laravel\Nightwatch\Records\Mail;
Nightwatch::rejectMail(function (Mail $mail) {
return str_contains($mail->subject, 'Newsletter');
});
Notification Events
Filter all notifications:
NIGHTWATCH_IGNORE_NOTIFICATIONS=true
Filter by channel:
use Laravel\Nightwatch\Records\Notification;
Nightwatch::rejectNotifications(function (Notification $notification) {
return $notification->channel === 'database';
});
Outgoing HTTP Requests
Filter all outgoing requests:
NIGHTWATCH_IGNORE_OUTGOING_REQUESTS=true
Filter by URL:
use Laravel\Nightwatch\Records\OutgoingRequest;
Nightwatch::rejectOutgoingRequests(function (OutgoingRequest $request) {
return str_contains($request->url, 'analytics.example.com');
});
Queued Jobs
Filter specific jobs:
use Laravel\Nightwatch\Records\QueuedJob;
Nightwatch::rejectQueuedJobs(function (QueuedJob $job) {
return $job->name === 'App\Jobs\LowPriorityJob';
});
Decoupling Job Sampling
Sample jobs independently from parent contexts:
use Illuminate\Support\Facades\Queue;
public function boot(): void
{
Queue::before(fn () => Nightwatch::sample(rate: 0.5));
}
Redaction Configuration
Redaction modifies captured data to remove or obfuscate sensitive information. Unlike filtering, redaction keeps the event but sanitizes its content. For authoritative details on what data can be redacted from each event type and the exact callback signatures, consult the individual event type documentation pages referenced in the filtering section above.
Request Redaction
Redact sensitive headers (automatically redacts: Authorization, Cookie, X-XSRF-TOKEN):
NIGHTWATCH_REDACT_HEADERS=Authorization,Cookie,Proxy-Authorization,X-API-Key
NIGHTWATCH_IGNORE_REQUEST_HEADERS=true
Redact request payloads (disabled by default):
NIGHTWATCH_CAPTURE_REQUEST_PAYLOAD=true
NIGHTWATCH_REDACT_PAYLOAD_FIELDS=password,password_confirmation,ssn,credit_card
Programmatic redaction:
use Laravel\Nightwatch\Facades\Nightwatch;
use Laravel\Nightwatch\Records\Request;
Nightwatch::redactRequests(function (Request $request) {
$request->url = str_replace('secret', '***', $request->url);
$request->ip = preg_replace('/\d+$/', '***', $request->ip);
});
Query Redaction
use Laravel\Nightwatch\Records\Query;
Nightwatch::redactQueries(function (Query $query) {
$query->sql = str_replace('secret_token', '***', $query->sql);
});
Cache Redaction
use Laravel\Nightwatch\Records\CacheEvent;
Nightwatch::redactCacheEvents(function (CacheEvent $cacheEvent) {
$cacheEvent->key = str_replace('user:', 'user:***:', $cacheEvent->key);
});
Command Redaction
use Laravel\Nightwatch\Records\Command;
Nightwatch::redactCommands(function (Command $command) {
$command->command = preg_replace('/--password=\S+/', '--password=***', $command->command);
});
Exception Redaction
use Laravel\Nightwatch\Records\Exception;
Nightwatch::redactExceptions(function (Exception $exception) {
$exception->message = str_replace('secret', '***', $exception->message);
});
Mail Redaction
use Laravel\Nightwatch\Records\Mail;
Nightwatch::redactMail(function (Mail $mail) {
$mail->subject = str_replace('Invoice #', 'Invoice ***', $mail->subject);
});
Outgoing Request Redaction
use Laravel\Nightwatch\Records\OutgoingRequest;
Nightwatch::redactOutgoingRequests(function (OutgoingRequest $outgoingRequest) {
$outgoingRequest->url = preg_replace('/api_key=\w+/', 'api_key=***', $outgoingRequest->url);
});
Configuration Summary by Event Type
| Event Type | Sampling | Filtering | Redaction |
|---|
| Requests | NIGHTWATCH_REQUEST_SAMPLE_RATE, Route middleware | Not applicable | Headers, payload, URL, IP |
| Commands | NIGHTWATCH_COMMAND_SAMPLE_RATE, Event listener | Not applicable | Command arguments |
| Queries | Parent context | rejectQueries(), NIGHTWATCH_IGNORE_QUERIES | SQL statement |
| Cache | Parent context | rejectCacheKeys(), rejectCacheEvents(), NIGHTWATCH_IGNORE_CACHE_EVENTS | Cache key |
| Jobs | Parent context, Queue::before | rejectQueuedJobs() | Not applicable |
| Mail | Parent context | rejectMail(), NIGHTWATCH_IGNORE_MAIL | Subject |
| Notifications | Parent context | rejectNotifications(), NIGHTWATCH_IGNORE_NOTIFICATIONS | Not applicable |
| Outgoing Requests | Parent context | rejectOutgoingRequests(), NIGHTWATCH_IGNORE_OUTGOING_REQUESTS | URL |
| Exceptions | NIGHTWATCH_EXCEPTION_SAMPLE_RATE | Not applicable | Exception message |
Production Recommendations
High-Traffic Applications
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.01
NIGHTWATCH_COMMAND_SAMPLE_RATE=0.1
NIGHTWATCH_EXCEPTION_SAMPLE_RATE=1.0
NIGHTWATCH_IGNORE_CACHE_EVENTS=true
NIGHTWATCH_IGNORE_QUERIES=true
Privacy-Conscious Applications
NIGHTWATCH_CAPTURE_REQUEST_PAYLOAD=false
NIGHTWATCH_IGNORE_REQUEST_HEADERS=true
Balanced Configuration (Recommended Start)
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1
NIGHTWATCH_COMMAND_SAMPLE_RATE=1.0
NIGHTWATCH_EXCEPTION_SAMPLE_RATE=1.0
Verification Checklist
After configuration:
Common Patterns
Filter Health Checks + Reduce Sampling
Route::get('/health', fn() => ['status' => 'ok'])
->middleware(Sample::never());
Exclude Internal/Vendor Queries
Nightwatch::rejectQueries(fn($q) =>
str_contains($q->sql, 'telescope') ||
str_contains($q->sql, 'pulse')
);
Protect User Data in Cache Keys
Nightwatch::redactCacheEvents(fn($e) =>
$e->key = preg_replace('/user:\d+/', 'user:***', $e->key)
);