From 34753ca7d3e13477b153040818400b8d8d831155 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 8 Aug 2016 12:33:58 +0200 Subject: [PATCH] Added logger to classes that catch errors in order to log them --- module/Core/src/Action/RedirectAction.php | 18 +++++++++++++++--- module/Core/src/Service/UrlShortener.php | 2 +- module/Rest/src/Action/AbstractRestAction.php | 12 ++++++++++++ .../Rest/src/Action/CreateShortcodeAction.php | 12 +++++++++--- module/Rest/src/Action/GetVisitsAction.php | 16 ++++++++++++---- .../Rest/src/Action/ListShortcodesAction.php | 14 +++++++++++--- module/Rest/src/Action/ResolveUrlAction.php | 12 ++++++++++-- .../CheckAuthenticationMiddleware.php | 18 +++++++++++++++--- 8 files changed, 85 insertions(+), 19 deletions(-) diff --git a/module/Core/src/Action/RedirectAction.php b/module/Core/src/Action/RedirectAction.php index 626ae27e..8aa3ddb7 100644 --- a/module/Core/src/Action/RedirectAction.php +++ b/module/Core/src/Action/RedirectAction.php @@ -4,6 +4,8 @@ namespace Shlinkio\Shlink\Core\Action; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; use Shlinkio\Shlink\Core\Service\UrlShortener; use Shlinkio\Shlink\Core\Service\UrlShortenerInterface; use Shlinkio\Shlink\Core\Service\VisitsTracker; @@ -21,18 +23,27 @@ class RedirectAction implements MiddlewareInterface * @var VisitsTrackerInterface */ private $visitTracker; + /** + * @var null|LoggerInterface + */ + private $logger; /** * RedirectMiddleware constructor. * @param UrlShortenerInterface $urlShortener * @param VisitsTrackerInterface $visitTracker + * @param LoggerInterface|null $logger * - * @Inject({UrlShortener::class, VisitsTracker::class}) + * @Inject({UrlShortener::class, VisitsTracker::class, "Logger_Shlink"}) */ - public function __construct(UrlShortenerInterface $urlShortener, VisitsTrackerInterface $visitTracker) - { + public function __construct( + UrlShortenerInterface $urlShortener, + VisitsTrackerInterface $visitTracker, + LoggerInterface $logger = null + ) { $this->urlShortener = $urlShortener; $this->visitTracker = $visitTracker; + $this->logger = $logger ?: new NullLogger(); } /** @@ -81,6 +92,7 @@ class RedirectAction implements MiddlewareInterface return new RedirectResponse($longUrl); } catch (\Exception $e) { // In case of error, dispatch 404 error + $this->logger->error('Error redirecting to long URL.' . PHP_EOL . $e); return $this->notFoundResponse($request, $response, $out); } } diff --git a/module/Core/src/Service/UrlShortener.php b/module/Core/src/Service/UrlShortener.php index 356667e1..30b700cd 100644 --- a/module/Core/src/Service/UrlShortener.php +++ b/module/Core/src/Service/UrlShortener.php @@ -99,7 +99,7 @@ class UrlShortener implements UrlShortenerInterface $this->em->close(); } - throw new RuntimeException('An error occured while persisting the short URL', -1, $e); + throw new RuntimeException('An error occurred while persisting the short URL', -1, $e); } } diff --git a/module/Rest/src/Action/AbstractRestAction.php b/module/Rest/src/Action/AbstractRestAction.php index 587e1a93..4acbe2ba 100644 --- a/module/Rest/src/Action/AbstractRestAction.php +++ b/module/Rest/src/Action/AbstractRestAction.php @@ -3,10 +3,22 @@ namespace Shlinkio\Shlink\Rest\Action; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; use Zend\Stratigility\MiddlewareInterface; abstract class AbstractRestAction implements MiddlewareInterface { + /** + * @var LoggerInterface + */ + protected $logger; + + public function __construct(LoggerInterface $logger = null) + { + $this->logger = $logger ?: new NullLogger(); + } + /** * Process an incoming request and/or response. * diff --git a/module/Rest/src/Action/CreateShortcodeAction.php b/module/Rest/src/Action/CreateShortcodeAction.php index 29aa1108..5dd1221e 100644 --- a/module/Rest/src/Action/CreateShortcodeAction.php +++ b/module/Rest/src/Action/CreateShortcodeAction.php @@ -4,6 +4,7 @@ namespace Shlinkio\Shlink\Rest\Action; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Core\Exception\InvalidUrlException; use Shlinkio\Shlink\Core\Service\UrlShortener; use Shlinkio\Shlink\Core\Service\UrlShortenerInterface; @@ -33,14 +34,17 @@ class CreateShortcodeAction extends AbstractRestAction * @param UrlShortenerInterface|UrlShortener $urlShortener * @param TranslatorInterface $translator * @param array $domainConfig + * @param LoggerInterface|null $logger * - * @Inject({UrlShortener::class, "translator", "config.url_shortener.domain"}) + * @Inject({UrlShortener::class, "translator", "config.url_shortener.domain", "Logger_Shlink"}) */ public function __construct( UrlShortenerInterface $urlShortener, TranslatorInterface $translator, - array $domainConfig + array $domainConfig, + LoggerInterface $logger = null ) { + parent::__construct($logger); $this->urlShortener = $urlShortener; $this->translator = $translator; $this->domainConfig = $domainConfig; @@ -75,14 +79,16 @@ class CreateShortcodeAction extends AbstractRestAction 'shortCode' => $shortCode, ]); } catch (InvalidUrlException $e) { + $this->logger->warning('Provided Invalid URL.' . PHP_EOL . $e); return new JsonResponse([ 'error' => RestUtils::getRestErrorCodeFromException($e), 'message' => sprintf( - $this->translator->translate('Provided URL "%s" is invalid. Try with a different one.'), + $this->translator->translate('Provided URL %s is invalid. Try with a different one.'), $longUrl ), ], 400); } catch (\Exception $e) { + $this->logger->error('Unexpected error creating shortcode.' . PHP_EOL . $e); return new JsonResponse([ 'error' => RestUtils::UNKNOWN_ERROR, 'message' => $this->translator->translate('Unexpected error occurred'), diff --git a/module/Rest/src/Action/GetVisitsAction.php b/module/Rest/src/Action/GetVisitsAction.php index 7a911789..0d78bcc1 100644 --- a/module/Rest/src/Action/GetVisitsAction.php +++ b/module/Rest/src/Action/GetVisitsAction.php @@ -4,6 +4,7 @@ namespace Shlinkio\Shlink\Rest\Action; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Common\Exception\InvalidArgumentException; use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Core\Service\VisitsTracker; @@ -27,11 +28,16 @@ class GetVisitsAction extends AbstractRestAction * GetVisitsAction constructor. * @param VisitsTrackerInterface $visitsTracker * @param TranslatorInterface $translator + * @param LoggerInterface $logger * - * @Inject({VisitsTracker::class, "translator"}) + * @Inject({VisitsTracker::class, "translator", "Logger_Shlink"}) */ - public function __construct(VisitsTrackerInterface $visitsTracker, TranslatorInterface $translator) - { + public function __construct( + VisitsTrackerInterface $visitsTracker, + TranslatorInterface $translator, + LoggerInterface $logger = null + ) { + parent::__construct($logger); $this->visitsTracker = $visitsTracker; $this->translator = $translator; } @@ -57,14 +63,16 @@ class GetVisitsAction extends AbstractRestAction ] ]); } catch (InvalidArgumentException $e) { + $this->logger->warning('Provided nonexistent shortcode'. PHP_EOL . $e); return new JsonResponse([ 'error' => RestUtils::getRestErrorCodeFromException($e), 'message' => sprintf( - $this->translator->translate('Provided short code "%s" does not exist'), + $this->translator->translate('Provided short code %s does not exist'), $shortCode ), ], 404); } catch (\Exception $e) { + $this->logger->error('Unexpected error while parsing short code'. PHP_EOL . $e); return new JsonResponse([ 'error' => RestUtils::UNKNOWN_ERROR, 'message' => $this->translator->translate('Unexpected error occurred'), diff --git a/module/Rest/src/Action/ListShortcodesAction.php b/module/Rest/src/Action/ListShortcodesAction.php index 3d0d9613..1cd376bc 100644 --- a/module/Rest/src/Action/ListShortcodesAction.php +++ b/module/Rest/src/Action/ListShortcodesAction.php @@ -4,6 +4,8 @@ namespace Shlinkio\Shlink\Rest\Action; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait; use Shlinkio\Shlink\Core\Service\ShortUrlService; use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface; @@ -28,11 +30,16 @@ class ListShortcodesAction extends AbstractRestAction * ListShortcodesAction constructor. * @param ShortUrlServiceInterface|ShortUrlService $shortUrlService * @param TranslatorInterface $translator + * @param LoggerInterface $logger * - * @Inject({ShortUrlService::class, "translator"}) + * @Inject({ShortUrlService::class, "translator", "Logger_Shlink"}) */ - public function __construct(ShortUrlServiceInterface $shortUrlService, TranslatorInterface $translator) - { + public function __construct( + ShortUrlServiceInterface $shortUrlService, + TranslatorInterface $translator, + LoggerInterface $logger = null + ) { + parent::__construct($logger); $this->shortUrlService = $shortUrlService; $this->translator = $translator; } @@ -50,6 +57,7 @@ class ListShortcodesAction extends AbstractRestAction $shortUrls = $this->shortUrlService->listShortUrls(isset($query['page']) ? $query['page'] : 1); return new JsonResponse(['shortUrls' => $this->serializePaginator($shortUrls)]); } catch (\Exception $e) { + $this->logger->error('Unexpected error while listing short URLs.' . PHP_EOL . $e); return new JsonResponse([ 'error' => RestUtils::UNKNOWN_ERROR, 'message' => $this->translator->translate('Unexpected error occurred'), diff --git a/module/Rest/src/Action/ResolveUrlAction.php b/module/Rest/src/Action/ResolveUrlAction.php index ac703b38..c99e233a 100644 --- a/module/Rest/src/Action/ResolveUrlAction.php +++ b/module/Rest/src/Action/ResolveUrlAction.php @@ -4,6 +4,7 @@ namespace Shlinkio\Shlink\Rest\Action; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException; use Shlinkio\Shlink\Core\Service\UrlShortener; use Shlinkio\Shlink\Core\Service\UrlShortenerInterface; @@ -26,11 +27,16 @@ class ResolveUrlAction extends AbstractRestAction * ResolveUrlAction constructor. * @param UrlShortenerInterface|UrlShortener $urlShortener * @param TranslatorInterface $translator + * @param LoggerInterface $logger * * @Inject({UrlShortener::class, "translator"}) */ - public function __construct(UrlShortenerInterface $urlShortener, TranslatorInterface $translator) - { + public function __construct( + UrlShortenerInterface $urlShortener, + TranslatorInterface $translator, + LoggerInterface $logger = null + ) { + parent::__construct($logger); $this->urlShortener = $urlShortener; $this->translator = $translator; } @@ -58,6 +64,7 @@ class ResolveUrlAction extends AbstractRestAction 'longUrl' => $longUrl, ]); } catch (InvalidShortCodeException $e) { + $this->logger->warning('Provided short code with invalid format.' . PHP_EOL . $e); return new JsonResponse([ 'error' => RestUtils::getRestErrorCodeFromException($e), 'message' => sprintf( @@ -66,6 +73,7 @@ class ResolveUrlAction extends AbstractRestAction ), ], 400); } catch (\Exception $e) { + $this->logger->error('Unexpected error while resolving the URL behind a short code.' . PHP_EOL . $e); return new JsonResponse([ 'error' => RestUtils::UNKNOWN_ERROR, 'message' => $this->translator->translate('Unexpected error occurred'), diff --git a/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php b/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php index 39c670e6..53f6cbe9 100644 --- a/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php +++ b/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php @@ -4,6 +4,8 @@ namespace Shlinkio\Shlink\Rest\Middleware; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; use Shlinkio\Shlink\Rest\Authentication\JWTService; use Shlinkio\Shlink\Rest\Authentication\JWTServiceInterface; use Shlinkio\Shlink\Rest\Exception\AuthenticationException; @@ -25,18 +27,27 @@ class CheckAuthenticationMiddleware implements MiddlewareInterface * @var JWTServiceInterface */ private $jwtService; + /** + * @var LoggerInterface + */ + private $logger; /** * CheckAuthenticationMiddleware constructor. * @param JWTServiceInterface|JWTService $jwtService * @param TranslatorInterface $translator + * @param LoggerInterface $logger * - * @Inject({JWTService::class, "translator"}) + * @Inject({JWTService::class, "translator", "Logger_Shlink"}) */ - public function __construct(JWTServiceInterface $jwtService, TranslatorInterface $translator) - { + public function __construct( + JWTServiceInterface $jwtService, + TranslatorInterface $translator, + LoggerInterface $logger = null + ) { $this->translator = $translator; $this->jwtService = $jwtService; + $this->logger = $logger ?: new NullLogger(); } /** @@ -118,6 +129,7 @@ class CheckAuthenticationMiddleware implements MiddlewareInterface // Return the response with the updated token on it return $response->withHeader(self::AUTHORIZATION_HEADER, 'Bearer ' . $jwt); } catch (AuthenticationException $e) { + $this->logger->warning('Tried to access API with an invalid JWT.' . PHP_EOL . $e); return $this->createTokenErrorResponse(); } }