Sentry : ne ratez plus aucune erreur
Sentry est un outil de monitoring d'erreurs qui capture, agrège et alerte sur les exceptions de votre application en temps réel.
Sans outil de ce type, une erreur en production se découvre de deux façons : un utilisateur la signale, ou quelqu'un finit par lire les logs. Dans les deux cas, il manque l'essentiel du contexte. Sentry change la donne : chaque exception est envoyée avec sa pile d'appels complète, la requête HTTP, l'utilisateur concerné, la version déployée et l'environnement. Les occurrences identiques sont regroupées en un seul issue, ce qui permet de voir immédiatement qu'une erreur touche des centaines d'utilisateurs depuis le dernier déploiement, plutôt que de recevoir des centaines d'e-mails.
Sentry existe en version SaaS et en version auto-hébergée. Le SDK et la configuration présentés ici sont identiques dans les deux cas ; seul le DSN change.
Installation Symfony
composer require sentry/sentry-symfony
Le paquet installe le SDK PHP et le bundle Symfony. Avec Symfony Flex, la recette crée le fichier de configuration et ajoute la variable SENTRY_DSN au fichier .env. Le DSN est l'adresse à laquelle le SDK envoie les événements ; il se trouve dans les paramètres du projet Sentry. Laissez-le vide en développement : sans DSN, aucun événement n'est envoyé.
# .env
SENTRY_DSN=
APP_VERSION=dev
# .env.local sur le serveur de production (ou variables d'environnement)
SENTRY_DSN=https://[email protected]/0
APP_VERSION=1.4.2
Configuration
# config/packages/sentry.yaml
sentry:
dsn: '%env(SENTRY_DSN)%'
options:
environment: '%kernel.environment%'
release: '%env(APP_VERSION)%'
traces_sample_rate: 0.2
profiles_sample_rate: 0.1
Chaque option a un rôle précis :
environmentsépare les erreurs de production, de préproduction et de test dans l'interface, pour filtrer facilement et alerter uniquement sur la production.releaseassocie chaque erreur à la version déployée. C'est ce qui permet à Sentry de signaler qu'une erreur est apparue avec une release donnée, ou qu'une erreur considérée comme résolue réapparaît.traces_sample_ratefixe la proportion de requêtes pour lesquelles une trace de performance est enregistrée :0.2signifie 20 %. Les erreurs, elles, sont toujours toutes envoyées. Sur un site à fort trafic, une valeur basse suffit et préserve votre quota.profiles_sample_rateactive le profilage d'une partie des requêtes tracées. Il nécessite l'extension PHPexcimersur le serveur ; sans elle, l'option n'a aucun effet.
Certaines exceptions ne méritent pas d'alerte : une page introuvable ou un accès refusé font partie du fonctionnement normal. Mieux vaut les ignorer explicitement, en production uniquement :
# config/packages/prod/sentry.yaml
sentry:
options:
ignore_exceptions:
- Symfony\Component\HttpKernel\Exception\NotFoundHttpException
- Symfony\Component\Security\Core\Exception\AccessDeniedException
Contexte utilisateur
Savoir qu'une erreur s'est produite est utile ; savoir qui elle touche l'est encore plus. Cet écouteur ajoute l'utilisateur connecté au scope Sentry à chaque requête :
use Sentry\State\Scope;
class SentryUserListener
{
#[AsEventListener(event: KernelEvents::REQUEST)]
public function onRequest(RequestEvent $event): void
{
$user = $this->security->getUser();
if ($user) {
\Sentry\configureScope(function (Scope $scope) use ($user): void {
$scope->setUser([
'id' => $user->getId(),
'email' => $user->getEmail(),
]);
});
}
}
}
Attention au RGPD : l'adresse e-mail est une donnée personnelle, qui sera stockée chez Sentry. Si l'identifiant suffit pour retrouver le compte dans votre back-office, n'envoyez que lui. Vérifiez aussi l'option send_default_pii, désactivée par défaut, qui contrôle l'envoi automatique d'informations comme l'adresse IP.
Enrichir une erreur capturée manuellement
Toutes les erreurs ne remontent pas sous forme d'exception non gérée. Quand vous interceptez une exception pour afficher un message propre à l'utilisateur, envoyez-la tout de même à Sentry, avec le contexte métier utile au diagnostic :
use Sentry\State\Scope;
try {
$this->paymentGateway->charge($order);
} catch (PaymentException $e) {
\Sentry\withScope(function (Scope $scope) use ($e, $order): void {
$scope->setTag('payment.provider', $order->getProvider());
$scope->setContext('order', [
'id' => $order->getId(),
'amount' => $order->getAmount(),
]);
\Sentry\captureException($e);
});
throw new OrderNotPaidException($order, previous: $e);
}
withScope crée un scope temporaire : le tag et le contexte ne s'appliquent qu'à cet événement, sans polluer les erreurs suivantes. Les tags sont indexés et servent à filtrer ou à regrouper les issues ; le contexte est simplement affiché dans le détail de l'événement.
Alertes et notifications
- Configurez des alertes Slack pour les nouvelles erreurs
- Définissez des seuils de volume d'erreurs
- Utilisez les traces de performance pour identifier les goulots
- Intégrez avec votre workflow GitHub pour le suivi des correctifs
Le piège classique est la fatigue d'alerte : si chaque erreur déclenche une notification, l'équipe finit par les ignorer toutes. Je recommande d'alerter sur les nouvelles issues et les régressions en production, et de réserver les alertes de volume aux flux critiques comme le paiement ou l'authentification.
Performance Monitoring
Au-delà des erreurs, Sentry mesure la durée des requêtes et de leurs étapes. Le bundle Symfony trace automatiquement les requêtes HTTP ainsi que, selon la configuration, les requêtes Doctrine, le cache et les appels HTTP sortants. Pour une opération métier précise, on peut créer sa propre transaction avec les objets de contexte de la version 4 du SDK PHP, et entourer chaque étape d'un span grâce à la fonction \Sentry\trace() :
use Sentry\SentrySdk;
use Sentry\Tracing\SpanContext;
use Sentry\Tracing\TransactionContext;
$transaction = \Sentry\startTransaction(
TransactionContext::make()
->setName('process-order')
->setOp('task')
);
SentrySdk::getCurrentHub()->setSpan($transaction);
try {
$orders = \Sentry\trace(
fn () => $this->orderRepository->findPending(),
SpanContext::make()->setOp('db.query')->setDescription('Commandes en attente'),
);
// ... traitement des commandes
} finally {
$transaction->finish();
}
Le bloc finally garantit que la transaction est clôturée même si une exception survient : une transaction jamais terminée n'est jamais envoyée.
Relier les erreurs aux déploiements
L'option release prend toute sa valeur quand la release est aussi déclarée dans Sentry avec ses commits. Sentry peut alors suggérer le commit probablement responsable d'une erreur. Avec sentry-cli, dans le pipeline de déploiement :
export SENTRY_AUTH_TOKEN=... # jeton d'API, stocké dans les secrets de la CI
export SENTRY_ORG=mon-organisation
export SENTRY_PROJECT=mon-projet
VERSION="$(git rev-parse --short HEAD)"
sentry-cli releases new "$VERSION"
sentry-cli releases set-commits "$VERSION" --auto
sentry-cli releases finalize "$VERSION"
La même valeur doit être passée à l'application via APP_VERSION, sinon les erreurs ne seront pas rattachées à la bonne release.
Checklist de mise en production
- DSN défini uniquement dans les environnements qui doivent remonter des erreurs
environmentetreleaserenseignés à chaque déploiement- Exceptions attendues (404, 403) ignorées
- Données personnelles limitées au strict nécessaire
- Taux d'échantillonnage des traces adapté au trafic et au quota
- Alertes ciblées sur les nouvelles erreurs et les régressions
Sentry ne remplace ni les logs ni le monitoring d'infrastructure : il ne vous dira pas que le disque est plein ou que le serveur ne répond plus. Il reste en revanche l'outil le plus efficace pour savoir, avant vos utilisateurs, qu'une ligne de code pose problème en production.