Nette: Sentry

4. 2. 2021

Při vývoji a následné údržbě aplikace je nedílnou součástí i její monitoring chování a stavů. Dnes si ukážeme velice jednoduchou implementaci nástroje Sentry pro chytré logování výjimek nad frameworkem Nette. Samotné Sentry podporuje řadu programovacích jazyků a za pomoci jejich SDK knihoven je implementace poměrně snadná.

Jako první krok provedeme instalaci Sentry SDK přes Composer.

$ composer require sentry/sdk

Vytvoříme si dekorátor implementující interface ILogger z Tracy, který nám bude zprostředkovávat zachytávání výjimek a předání přes SDK do Sentry.

namespace App\Logging;

use Tracy\ILogger;

final class SentryDecoratedTracyLogger implements ILogger
{
}

Přes konstruktor si vytáhneme stávající logger z Tracy a inicializujeme Sentry s nastavením - k nastavení se vrátíme později.

use Tracy\ILogger;
use function Sentry\init;

final class SentryDecoratedTracyLogger implements ILogger
{
    /** @var ILogger */
    private $parentLogger;

    public function __construct(array $sentryOptions)
    {
        $this->parentLogger = Debugger::getLogger();

        init($sentryOptions);
    }
}

Připravíme si funkci “getSeverityFromPriority”, která nám zprostředkuje překlad Tracy typů výjímek na Sentry typy.

use Sentry\Severity;
use Tracy\ILogger;

private function getSeverityFromPriority(string $priority): ?Severity
{
    switch ($priority) {
        case ILogger::DEBUG:
            return Severity::debug();

        case ILogger::INFO:
            return Severity::info();

        case ILogger::WARNING:
            return Severity::warning();

        case ILogger::ERROR:
        case ILogger::EXCEPTION:
            return Severity::error();

        case ILogger::CRITICAL:
            return Severity::fatal();

        default:
            return null;
    }
}

Dalším krokem bude vytvoření funkce, která nám zachycenou výjimku zašle do Sentry a k tomu využijeme dvě funkce z SDK Sentry “captureException” a “captureMessage”.

Funkce “captureException” umožňuje zaslat celou instanci Throwable třídy (https://php.net/manual/en/class.throwable.php). Pokud nezískáme instanci třídy Throwable použijeme funkci “captureMessage” pro zaslání simple zprávy.

use function Sentry\captureException;
use function Sentry\captureMessage;

private function logToSentry($value, $priority): void
{
    $severity = $this->getSeverityFromPriority($priority);

    if (! $severity) {
        return;
    }

    if ($value instanceof Throwable) {
        captureException($value);
    } else {
        captureMessage($value, $severity);
    }
}

K dokončení dekorátoru již zbývá pouze funkce zastávající původní logger z Tracy co nám bude obsluhovat jak původní Tracy logger tak i Sentry logger.

public function log($value, $priority = self::INFO): void
{
    // Logging to default Tracy logger
    $this->parentLogger->log($value, $priority);

    // Logging to Sentry
    $this->logToSentry($value, $priority);
}

Jako finální krok zbývá zaregistrování našeho loggeru do konfigurace Nette frameworku a přidání samotné konfigurace Sentry předávané v konstruktoru dekorátoru. Podrobné možnosti konfigurace naleznete v oficiální dokumentaci SDK pro PHP - https://docs.sentry.io/platforms/php/configuration/

# common.neon

tracy.logger: App\Logging\SentryDecoratedTracyLogger(%sentry%)

parameters:
    sentry:
        dsn: ''
        in_app_exclude:
            - %appDir%/../vendor/
            - %appDir%/../temp/
        send_default_pii: true

Celý kód si můžete prohléednout na GutHubu: https://github.com/lukashron/nette-sentry

Nejnovější příspěvky