88 lines
2.7 KiB
PHP
88 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use App\Services\Admin\AdminRequestPerformanceMetrics;
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class LogSlowAdminRequests
|
|
{
|
|
public function __construct(private AdminRequestPerformanceMetrics $metrics) {}
|
|
|
|
/**
|
|
* Handle an incoming request.
|
|
*
|
|
* @param Closure(Request): (Response) $next
|
|
*/
|
|
public function handle(Request $request, Closure $next): Response
|
|
{
|
|
if (! config('admin_performance.slow_requests.enabled', true)) {
|
|
return $next($request);
|
|
}
|
|
|
|
$startedAt = microtime(true);
|
|
$this->metrics->start();
|
|
|
|
try {
|
|
$response = $next($request);
|
|
} catch (\Throwable $exception) {
|
|
$this->metrics->stop();
|
|
|
|
throw $exception;
|
|
}
|
|
|
|
$snapshot = $this->metrics->snapshot();
|
|
$this->metrics->stop();
|
|
|
|
$durationMs = (int) round((microtime(true) - $startedAt) * 1000);
|
|
|
|
if ($this->shouldLog($durationMs, $snapshot['database_time_ms'], $snapshot['query_count'])) {
|
|
$this->logger()->warning('Slow admin request detected.', [
|
|
'method' => $request->method(),
|
|
'path' => '/'.$request->path(),
|
|
'route_name' => $request->route()?->getName(),
|
|
'status_code' => $response->getStatusCode(),
|
|
'user_id' => $request->user()?->id,
|
|
'duration_ms' => $durationMs,
|
|
'database_time_ms' => $snapshot['database_time_ms'],
|
|
'query_count' => $snapshot['query_count'],
|
|
'slow_queries' => $snapshot['slow_queries'],
|
|
]);
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
private function shouldLog(int $durationMs, float $databaseTimeMs, int $queryCount): bool
|
|
{
|
|
return $durationMs >= $this->durationThresholdMs()
|
|
|| $databaseTimeMs >= $this->databaseThresholdMs()
|
|
|| $queryCount >= $this->queryCountThreshold();
|
|
}
|
|
|
|
private function logger(): LoggerInterface
|
|
{
|
|
$channel = config('admin_performance.slow_requests.channel') ?: config('logging.default');
|
|
|
|
return Log::channel(is_string($channel) && $channel !== '' ? $channel : 'stack');
|
|
}
|
|
|
|
private function durationThresholdMs(): int
|
|
{
|
|
return (int) config('admin_performance.slow_requests.duration_threshold_ms', 750);
|
|
}
|
|
|
|
private function databaseThresholdMs(): int
|
|
{
|
|
return (int) config('admin_performance.slow_requests.database_threshold_ms', 250);
|
|
}
|
|
|
|
private function queryCountThreshold(): int
|
|
{
|
|
return (int) config('admin_performance.slow_requests.query_count_threshold', 100);
|
|
}
|
|
}
|