Loading...
Loading...
Compare original and translation side by side
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 dataRequest/Command/Scheduled Task
|
v
[Sampling?] ----NO----> Drop entire trace
| YES
v
Events generated
|
v
[Filtering?] ----YES---> Drop specific event
| NO
v
[Redaction] ----------> Store modified dataundefinedundefined
**Recommendation**: Start with `0.1` (10%) for requests in production, adjust based on volume and needs.
**建议**:生产环境中请求采样率从`0.1`(10%)开始,根据数据量和需求调整。Sampleuse 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());Sampleuse Illuminate\Support\Facades\Route;
use Laravel\Nightwatch\Http\Middleware\Sample;
// 管理员路由100%采样
Route::middleware(Sample::rate(1.0))->prefix('admin')->group(function () {
// 所有管理员路由全量采样
});
// API路由5%采样
Route::middleware(Sample::rate(0.05))->prefix('api')->group(function () {
// API路由少量采样
});
// 关键端点始终采样
Route::post('/checkout', [CheckoutController::class, 'process'])
->middleware(Sample::always());
// 健康检查从不采样
Route::get('/health', [HealthController::class, 'check'])
->middleware(Sample::never());Route::fallback(fn () => abort(404))
->middleware(Sample::rate(0.01)); // 1% sampling for unmatched routesRoute::fallback(fn () => abort(404))
->middleware(Sample::rate(0.01)); // 未匹配路由1%采样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);
}
}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);
}
}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();
}
});
}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::captureDefaultVendorCommands();Nightwatch::captureDefaultVendorCommands();NIGHTWATCH_IGNORE_QUERIES=trueuse 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`');
});
}NIGHTWATCH_IGNORE_QUERIES=trueuse Laravel\Nightwatch\Facades\Nightwatch;
use Laravel\Nightwatch\Records\Query;
public function boot(): void
{
// 过滤任务表查询(PostgreSQL)
Nightwatch::rejectQueries(function (Query $query) {
return str_contains($query->sql, 'into "jobs"');
});
// 过滤缓存表查询(MySQL)
Nightwatch::rejectQueries(function (Query $query) {
return str_contains($query->sql, 'from `cache`')
|| str_contains($query->sql, 'into `cache`');
});
}NIGHTWATCH_IGNORE_CACHE_EVENTS=trueNightwatch::rejectCacheKeys([
'my-app:users', // Exact match
'/^my-app:posts:/', // Regex: starts with my-app:posts:
'/^[a-zA-Z0-9]{40}$/', // Regex: session IDs
]);use Laravel\Nightwatch\Records\CacheEvent;
Nightwatch::rejectCacheEvents(function (CacheEvent $cacheEvent) {
return str_starts_with($cacheEvent->key, 'temp:');
});NIGHTWATCH_IGNORE_CACHE_EVENTS=trueNightwatch::rejectCacheKeys([
'my-app:users', // 精确匹配
'/^my-app:posts:/', // 正则:以my-app:posts:开头
'/^[a-zA-Z0-9]{40}$/', // 正则:会话ID
]);use Laravel\Nightwatch\Records\CacheEvent;
Nightwatch::rejectCacheEvents(function (CacheEvent $cacheEvent) {
return str_starts_with($cacheEvent->key, 'temp:');
});NIGHTWATCH_IGNORE_MAIL=trueuse Laravel\Nightwatch\Records\Mail;
Nightwatch::rejectMail(function (Mail $mail) {
return str_contains($mail->subject, 'Newsletter');
});NIGHTWATCH_IGNORE_MAIL=trueuse Laravel\Nightwatch\Records\Mail;
Nightwatch::rejectMail(function (Mail $mail) {
return str_contains($mail->subject, 'Newsletter');
});NIGHTWATCH_IGNORE_NOTIFICATIONS=trueuse Laravel\Nightwatch\Records\Notification;
Nightwatch::rejectNotifications(function (Notification $notification) {
return $notification->channel === 'database';
});NIGHTWATCH_IGNORE_NOTIFICATIONS=trueuse Laravel\Nightwatch\Records\Notification;
Nightwatch::rejectNotifications(function (Notification $notification) {
return $notification->channel === 'database';
});NIGHTWATCH_IGNORE_OUTGOING_REQUESTS=trueuse Laravel\Nightwatch\Records\OutgoingRequest;
Nightwatch::rejectOutgoingRequests(function (OutgoingRequest $request) {
return str_contains($request->url, 'analytics.example.com');
});NIGHTWATCH_IGNORE_OUTGOING_REQUESTS=trueuse Laravel\Nightwatch\Records\OutgoingRequest;
Nightwatch::rejectOutgoingRequests(function (OutgoingRequest $request) {
return str_contains($request->url, 'analytics.example.com');
});use Laravel\Nightwatch\Records\QueuedJob;
Nightwatch::rejectQueuedJobs(function (QueuedJob $job) {
return $job->name === 'App\Jobs\LowPriorityJob';
});use Laravel\Nightwatch\Records\QueuedJob;
Nightwatch::rejectQueuedJobs(function (QueuedJob $job) {
return $job->name === 'App\Jobs\LowPriorityJob';
});use Illuminate\Support\Facades\Queue;
public function boot(): void
{
Queue::before(fn () => Nightwatch::sample(rate: 0.5));
}use Illuminate\Support\Facades\Queue;
public function boot(): void
{
Queue::before(fn () => Nightwatch::sample(rate: 0.5));
}undefinedundefined
**Redact request payloads** (disabled by default):
```bash
**脱敏请求负载**(默认禁用):
```bash
**Programmatic redaction**:
```php
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);
});
**程序化脱敏**:
```php
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\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\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\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\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\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);
});use Laravel\Nightwatch\Records\OutgoingRequest;
Nightwatch::redactOutgoingRequests(function (OutgoingRequest $outgoingRequest) {
$outgoingRequest->url = preg_replace('/api_key=\w+/', 'api_key=***', $outgoingRequest->url);
});