Sentry Performance, PHP a GraphQL
Jak využít Sentry Performance pro monitoring výkonu PHP aplikace včetně výkonu GraphQL API.
Sentry je vynikající nástroj pro monitoring a logování chybových stavů aplikace. Lze velmi snadno využívat jak SaaS službu, tak i na vlastní infrastruktuře díky dostupnému Docker image.
Přidání podpory do Symfony projektu je díky composeru velmi snadné
composer require sentry/sentry-symfony
V tomto zápisku popisuji jak nastavit Sentry jako monitor výkonu PHP Symfony aplikace včetně nastavení pro přehledné monitorování GraphQL API implementovaném pomocí Overblog GraphQL Bundle. Pro úplně základní nastavení aplikace stačí jednoduchá úprava souboru config/packages/sentry.yaml
a to následujícím způsobem
sentry:
dsn: '%env(SENTRY_DSN)%'
options:
traces_sample_rate: '%env(float:SENTRY_PERFORMANCE_RATIO)%'
Kde
traces_sample_rate
v sekcioptions
- poměr měřených transakcí jako číslo mezi 0 a 1 (0.2 pak znamená, že 20% transakcí je měřených). Na devel stage dáváme klidně 1.0, v produkčním prostředí pak třeba 0.02. 0 měření výpíná.
V dodatečném nastavení lze upřesnit co vše má být monitorováno (dbal, twig, cache, http_client, console, viz nastavení pro Symfony), proto zapnutí/vypnutí konkrétního měření je závislé od konkrétního projektu a jeho potřeb. Nyní už jenom zbývá doplnit env proměnné do .env souborů, např. takto
SENTRY_DSN=https://sentry.io/dsn-vaseho-projektu
SENTRY_PERFORMANCE_RATIO=0.05
Pokud je vše dobře nastavené, tak by se vám již s prvními requesty do aplikace měly zobrazovat výkonové charakteristiky měřených transakcí identifikované http metodou a url requestu, např. GET https://www.id-sign.com/poradna. Toto může být dostačující pro klasické stránky, kdy každý obsah má svojí vlastní URL. Pokud však chceme monitorovat výkon GraphQL API, které má pro veškerý obsah jeden endpoint, potřebujeme jednotlivá volání API pojmenovat dle volané query. A ideálně si k tomu doplnit i autentikovaného uživatele, přesný zápis query použité proměnné.
V našich projektech využíváme Overblog GraphQL Bundle, který lze pro toto doplnění velmi snadno upravit. Stačí využít jednu z jeho událostí a to graphql.pre_executor
. Připravíme si tedy patřičný EventListener, pojmenovaný např. GraphQLListener:
<?php
namespace App\EventListener;
use App\Entity\User;
use Overblog\GraphQLBundle\Event\ExecutorArgumentsEvent;
use Sentry\Breadcrumb;
use Sentry\SentrySdk;
use Sentry\State\Scope;
use Symfony\Bundle\SecurityBundle\Security;
use function Sentry\addBreadcrumb;
use function Sentry\captureException;
use function Sentry\configureScope;
readonly class GraphQLListener
{
public function __construct(private Security $security)
{
}
public function onPreExecutor(ExecutorArgumentsEvent $event): void
{
$name = $event->getOperationName() ?? 'Unknown operation';
$sentryTransaction = SentrySdk::getCurrentHub()->getTransaction();
$sentryTransaction?->setName($name);
$authUser = $this->security->getUser();
if ($authUser instanceof User) {
configureScope(function (Scope $scope) use ($authUser): void {
$scope->setUser([
'id' => $authUser->getId(),
]);
});
}
try {
addBreadcrumb(
new Breadcrumb(
Breadcrumb::LEVEL_INFO,
Breadcrumb::TYPE_DEFAULT,
'GraphQL',
'query',
[
'userId' => $authUser?->getId(),
'operationName' => $name,
'query' => $event->getRequestString(),
'variables' => json_encode($event->getVariableValue(), JSON_THROW_ON_ERROR),
]
)
);
} catch (\JsonException $exception) {
captureException($exception);
}
}
}
a v config/services.yaml
si jej zaregistrujeme tak, aby byl volán pro výše uvedenou událost
App\EventListener\GraphQLListener:
tags:
- { name: kernel.event_listener, event: graphql.pre_executor, method: onPreExecutor }
Tímto jednoduchým rozšířením máme jednotlivé transakce
- pojmenované dle volané query - viz
$sentryTransaction?->setName(...)
- doplněné o informaci o přihlášeném uživateli - viz
$scope->setUser(...)
- a v breadcrumbs k celé transakci vidíme i přesné znění query a použité proměnné - viz
addBreadcrumb(...)
Možností konfigurací je mnohem více, pro další konkrétní informace doporučuji si projít oficiální dokumentaci.
Nakonec zmíním důležitou informaci plynoucí z podstaty PHP a jeho synchronnosti. Veškeré měření a komunikace se Sentry (nejspíše ve většině případů) probíhá ve stejném procesu jako zpracování měřeného requestu. Z toho plyn ovlivnění rychlosti zpracování vlastního requestu. Sentry nabízí řešení, které tento vliv snižuje téměř k nule - vytvoření lokální proxy skrze Relay, viz. opět oficiální dokumentace.
Mohlo by vás také zajímat
PHP8.1, Enum třídy a Doctrine
Jednou z novinek PHP8.1 je i podpora Enum tříd. Tento zápisek vznikl jako stručné intro k tomu, jak lze tuto novinku používat ve spojení s Doctrine.
Číst víceSymfony, lokální server a důvěryhodný SSL certifikát v Chrome
Nastavte si důvěryhodný certifikát v Chrome i pro vývoj Symfony aplikací
Číst víceNGINX, PHP-FPM a memory_limit
Nastavení memory limitu pro PHP v konfiguraci NGINX a PHP-FPM
Číst vícePotřebujete více informací?
Zpráva byla úspěšně odeslána.
Děkujeme
Omlouváme se, ale zprávu se nepovedlo odeslat.
Budeme rádi, když nám o tomto dáte vědět na info@id-sign.com