From laravel-nightwatch
Configures Laravel Nightwatch sampling, filtering, and redaction rules to manage data volume, protect PII, and optimize production event collection.
npx claudepluginhub laravel/agent-skills --plugin laravel-nightwatchThis skill uses the workspace's default tool permissions.
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.
Conducts multi-round deep research on GitHub repos via API and web searches, generating markdown reports with executive summaries, timelines, metrics, and Mermaid diagrams.
Dynamically discovers and combines enabled skills into cohesive, unexpected delightful experiences like interactive HTML or themed artifacts. Activates on 'surprise me', inspiration, or boredom cues.
Generates images from structured JSON prompts via Python script execution. Supports reference images and aspect ratios for characters, scenes, products, visuals.
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.
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:
Nightwatch processes events through three stages:
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 determines which entry points (requests, commands, scheduled tasks) trigger full trace collection. When an entry point is sampled, all related events are captured.
Configure via environment variables:
# Default: 100% sampling (all requests/commands captured)
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1 # Recommended: 10% of requests
NIGHTWATCH_COMMAND_SAMPLE_RATE=1.0 # Capture all commands
NIGHTWATCH_EXCEPTION_SAMPLE_RATE=1.0 # Always capture exceptions
Recommendation: Start with 0.1 (10%) for requests in production, adjust based on volume and needs.
Apply different rates to specific routes using the Sample middleware:
use Illuminate\Support\Facades\Route;
use Laravel\Nightwatch\Http\Middleware\Sample;
// Sample admin routes at 100%
Route::middleware(Sample::rate(1.0))->prefix('admin')->group(function () {
// All admin routes sampled fully
});
// Sample API routes at 5%
Route::middleware(Sample::rate(0.05))->prefix('api')->group(function () {
// API routes sampled sparingly
});
// Always sample critical endpoints
Route::post('/checkout', [CheckoutController::class, 'process'])
->middleware(Sample::always());
// Never sample health checks
Route::get('/health', [HealthController::class, 'check'])
->middleware(Sample::never());
Handle 404/bot traffic with reduced sampling:
Route::fallback(fn () => abort(404))
->middleware(Sample::rate(0.01)); // 1% sampling for unmatched routes
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(); // Always sample admin requests
}
return $next($request);
}
}
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();
}
});
}
Nightwatch automatically ignores framework/internal commands. Opt-in to capture them:
Nightwatch::captureDefaultVendorCommands();
Filtering excludes specific events from collection after sampling. Use filtering to reduce noise and quota usage.
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
{
// Filter job table queries (PostgreSQL)
Nightwatch::rejectQueries(function (Query $query) {
return str_contains($query->sql, 'into "jobs"');
});
// Filter cache table queries (MySQL)
Nightwatch::rejectQueries(function (Query $query) {
return str_contains($query->sql, 'from `cache`')
|| str_contains($query->sql, 'into `cache`');
});
}
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:');
});
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');
});
Filter all notifications:
NIGHTWATCH_IGNORE_NOTIFICATIONS=true
Filter by channel:
use Laravel\Nightwatch\Records\Notification;
Nightwatch::rejectNotifications(function (Notification $notification) {
return $notification->channel === 'database';
});
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');
});
Filter specific jobs:
use Laravel\Nightwatch\Records\QueuedJob;
Nightwatch::rejectQueuedJobs(function (QueuedJob $job) {
return $job->name === 'App\Jobs\LowPriorityJob';
});
Sample jobs independently from parent contexts:
use Illuminate\Support\Facades\Queue;
public function boot(): void
{
Queue::before(fn () => Nightwatch::sample(rate: 0.5));
}
Redaction modifies captured data to remove or obfuscate sensitive information. Unlike filtering, redaction keeps the event but sanitizes its content.
Redact sensitive headers (automatically redacts: Authorization, Cookie, X-XSRF-TOKEN):
# Customize redacted headers
NIGHTWATCH_REDACT_HEADERS=Authorization,Cookie,Proxy-Authorization,X-API-Key
Redact request payloads (disabled by default):
# Enable payload capture
NIGHTWATCH_CAPTURE_REQUEST_PAYLOAD=true
# Customize redacted fields
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);
});
use Laravel\Nightwatch\Records\Query;
Nightwatch::redactQueries(function (Query $query) {
$query->sql = str_replace('secret_token', '***', $query->sql);
});
use Laravel\Nightwatch\Records\CacheEvent;
Nightwatch::redactCacheEvents(function (CacheEvent $cacheEvent) {
$cacheEvent->key = str_replace('user:', 'user:***:', $cacheEvent->key);
});
use Laravel\Nightwatch\Records\Command;
Nightwatch::redactCommands(function (Command $command) {
$command->command = preg_replace('/--password=\S+/', '--password=***', $command->command);
});
use Laravel\Nightwatch\Records\Exception;
Nightwatch::redactExceptions(function (Exception $exception) {
$exception->message = str_replace('secret', '***', $exception->message);
});
use Laravel\Nightwatch\Records\Mail;
Nightwatch::redactMail(function (Mail $mail) {
$mail->subject = str_replace('Invoice #', 'Invoice ***', $mail->subject);
});
use Laravel\Nightwatch\Records\OutgoingRequest;
Nightwatch::redactOutgoingRequests(function (OutgoingRequest $outgoingRequest) {
$outgoingRequest->url = preg_replace('/api_key=\w+/', 'api_key=***', $outgoingRequest->url);
});