Support des queues
L'enregistrement des journaux d'audit implique des écritures en base de données — incluant le calcul du hash et une transaction verrouillée en mode complet. Par défaut, AuditChain dispatche ces écritures vers un job en queue afin qu'elles ne ralentissent pas les requêtes HTTP. La queue est activée par défaut ; cette page explique son fonctionnement et les cas où vous pourriez vouloir modifier les paramètres par défaut.
Configuration
// config/audit-chain.php 'queue' => [ 'enabled' => true, 'connection' => null, 'queue' => 'default', ],
| Clé | Défaut | Description |
|---|---|---|
queue.enabled |
true |
Dispatcher l'enregistrement d'audit vers un job en queue |
queue.connection |
null |
Connexion de queue (null = valeur par défaut de l'application) |
queue.queue |
default |
Nom de la queue pour les jobs d'audit |
Fonctionnement
Lorsque la queue est activée, la création des journaux d'audit suit ce flux :
- L'événement Eloquent se déclenche (created, updated, deleted, etc.)
- Le payload d'audit est construit de manière synchrone (anciennes/nouvelles valeurs, utilisateur, IP, user agent, contexte, UUID de batch)
- Un job
RecordAuditLogest dispatché vers la queue - Le worker de queue prend en charge le job et écrit le journal d'audit en base de données
Le job RecordAuditLog implémente ShouldQueue et inclut des valeurs par défaut raisonnables :
- 3 tentatives en cas d'échec
- 5 secondes de délai entre les tentatives
- 30 secondes de timeout
Queue dédiée
Pour éviter que l'enregistrement d'audit ne rivalise avec d'autres jobs en queue (e-mails, notifications, exports), utilisez une queue dédiée :
'queue' => [ 'enabled' => true, 'connection' => 'redis', 'queue' => 'auditing', ],
Puis lancez un worker dédié pour les jobs d'audit :
php artisan queue:work redis --queue=auditing
La propriété isChained
Le job RecordAuditLog utilise une propriété isChained pour distinguer entre le mode léger (journal d'activité) et le mode complet (journal d'audit) :
class RecordAuditLog implements ShouldQueue { public function __construct( public readonly array $auditData, public readonly bool $isChained = false, ) {} }
Cette propriété est intentionnellement nommée isChained plutôt que chained pour éviter un conflit avec le trait Queueable de Laravel, qui définit sa propre propriété $chained pour le chaînage de jobs. Si la propriété s'appelait chained, elle entrerait en collision avec le trait et causerait un comportement inattendu.
Lorsque isChained est true, le job appelle DatabaseDriver::storeChained() qui exécute le calcul de la chaîne de hash dans une transaction verrouillée. Lorsqu'il est false, il appelle DatabaseDriver::store() pour une simple insertion avec des hash nuls.
Quand désactiver la queue
Définissez queue.enabled à false pour enregistrer les journaux d'audit de manière synchrone :
'queue' => [ 'enabled' => false, ],
Désactivez la queue lorsque :
- Vous n'exécutez pas de worker de queue — Si aucun worker ne traite les jobs, les journaux d'audit resteront dans la queue indéfiniment et ne seront jamais enregistrés.
- Vous avez besoin d'une visibilité immédiate des audits — Certains workflows exigent que le journal d'audit existe en base de données avant l'envoi de la réponse HTTP (par exemple, une API de conformité qui retourne l'identifiant du journal d'audit).
- Tests — L'enregistrement synchrone est plus simple à tester. La suite de tests d'AuditChain fonctionne avec la queue désactivée.
- Applications à faible trafic — Si le coût d'une écriture synchrone en base de données est négligeable pour votre cas d'utilisation, la simplicité de l'enregistrement synchrone peut être préférable.
Quand activer la queue
Gardez la queue activée (le comportement par défaut) lorsque :
- Applications à fort trafic — Décharger les écritures vers un worker de queue maintient des temps de réponse HTTP constants.
- Mode Audit Trail avec verrouillage —
HasAuditTrailutiliselockForUpdate()pour maintenir l'ordre de la chaîne. Sous forte concurrence, ce verrou peut brièvement retarder les requêtes. Une queue sérialise naturellement ces écritures. - Connexions de base de données séparées — Si votre base de données d'audit est sur un serveur différent, le temps de trajet réseau est mieux absorbé par un worker en arrière-plan que par le cycle de la requête.
Échecs de la queue
Le job RecordAuditLog implémente une méthode failed() qui journalise un Log::critical() lorsque le job échoue définitivement après toutes les tentatives :
public function failed(\Throwable $exception): void { Log::critical('Audit log recording failed permanently', [ 'audit_data' => $this->auditData, 'exception' => $exception->getMessage(), ]); }
Cela garantit que les échecs d'enregistrement d'audit sont visibles dans vos journaux applicatifs, même si vous ne surveillez pas activement la table failed_jobs.
Si un job d'audit en queue échoue après toutes les tentatives, il atterrit dans la table failed_jobs de Laravel. Surveillez cette table (ou utilisez Laravel Horizon pour les queues Redis) pour détecter les échecs d'enregistrement d'audit.
Des journaux d'audit manquants dans une chaîne de hash feront que audit:verify signalera des ruptures de chaîne. La vérification planifiée avec --notify vous alertera de ces lacunes. Consultez Notifications pour les détails de configuration.