Nette: Sentry
4. 2. 2021Př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