<?php
declare(strict_types=1);
namespace App\EventListener\Api;
use App\Application\Service\Api\Integration\Factory\ApiResponseTimeFactory;
use App\Application\Service\Helper\LogWriterService;
use App\Manager\System\ApiResponseTimeManager;
use App\Service\EnvironmentService;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\Security\Core\Security;
class ApiResponseTimeListener
{
private const ACCEPTED_RESPONSE_CODES = [Response::HTTP_OK, Response::HTTP_CREATED];
protected ApiResponseTimeManager $apiDateCallManager;
protected LogWriterService $loggerService;
protected ApiResponseTimeFactory $apiDateCallEndpointFactory;
protected RequestStack $requestStack;
protected EnvironmentService $environmentService;
private Security $security;
public function __construct(
ApiResponseTimeManager $apiDateCallManager,
LogWriterService $loggerService,
ApiResponseTimeFactory $apiDateCallEndpointFactory,
RequestStack $requestStack,
Security $security,
EnvironmentService $environmentService
) {
$this->apiDateCallManager = $apiDateCallManager;
$this->loggerService = $loggerService;
$this->apiDateCallEndpointFactory = $apiDateCallEndpointFactory;
$this->requestStack = $requestStack;
$this->environmentService = $environmentService;
$this->security = $security;
}
public function onKernelResponse(ResponseEvent $event): void
{
$request = $event->getRequest();
$url = $request->server->get('REQUEST_URI');
$isSubrequest = $this->requestStack->getParentRequest();
if (
!$this->environmentService->isDev()
|| $isSubrequest
|| \str_contains($url, 'doc')
|| \str_contains($url, 'monitor')
|| !$this->environmentService->isApi()
|| !\in_array($event->getResponse()->getStatusCode(), self::ACCEPTED_RESPONSE_CODES)
) {
return;
}
try {
$requestTime = $request->server->get('REQUEST_TIME_FLOAT');
$requestTimeAsArray = \explode('.', (string)$requestTime);
$dateStartAsDate = \date('Y-m-d H:i:s', (int)\current($requestTimeAsArray));
$dateWithMicroTime = $dateStartAsDate.'.'.$requestTimeAsArray[1];
$dateStartDateTime = new \DateTime($dateWithMicroTime);
$dateEndDateTime = new \DateTime();
$diff = $dateStartDateTime->diff($dateEndDateTime);
$requestTimeAsArray = \explode('.', (string)$diff->f);
$diffInSeconds = \round((float)((($diff->i * 60) + $diff->s).'.'.$requestTimeAsArray[1]), 1);
$memoryPeakMb = (int)ceil(\memory_get_peak_usage(true) / 1024 / 1024);
$methodType = $request->getMethod();
$token = $this->security->getToken();
if (!$token || $token->getUser() === null) {
return;
}
$apiDateCall = $this->apiDateCallEndpointFactory->create($url, $dateStartDateTime, $dateEndDateTime, $diffInSeconds, $memoryPeakMb, $methodType, $token->getUser());
$this->apiDateCallManager->save($apiDateCall);
} catch (\Throwable $e) {
$this->loggerService->logApiMain(
LogWriterService::API_LOG_INFO,
'Exception found in ApiResponseTimeListener->onKernelResponse(): '.$e->getMessage(),
__METHOD__,
$request,
null
);
}
}
}