presseportale/app/Http/Middleware/LogSlowAdminRequests.php
Kevin Adametz 5b8bdf4182
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
12-05-2026 Frontend dev
2026-05-12 18:32:33 +02:00

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);
}
}