Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.
github.com/rcsofttech85/AuditTrailBundle
Type:symfony-bundle
pkg:composer/rcsofttech/audit-trail-bundle
Requires
Requires (Dev)
Suggests
This package is auto-updated.
Last update: 2026-06-05 16:36:29 UTC
AuditTrailBundle records Doctrine ORM entity changes in Symfony applications. It captures changes during Doctrine flush, stores audit logs, supports multiple delivery transports, and provides tools for integrity verification, review, export, and recovery.
Full documentation now lives on GitHub Pages:
For older versions, use the README and docs from the matching GitHub tag unless archived public docs are added later.
flush() calls#[Auditable], #[AuditCondition], #[AuditAccess], and #[Sensitive]#[SensitiveParameter] and bundle-level sensitive fieldscomposer require rcsofttech/audit-trail-bundle
Optional packages depend on the features you enable:
composer require symfony/messenger # async database or queue transport composer require symfony/http-client # HTTP transport composer require easycorp/easyadmin-bundle # EasyAdmin dashboard
The database transport is enabled by default. Generate and run a Doctrine migration for the audit log table:
php bin/console make:migration php bin/console doctrine:migrations:migrate
The example uses PHP 8.4 asymmetric property visibility (public private(set)) and constructor property promotion for normal entity fields. Keep the generated ID outside the constructor so callers cannot pass it accidentally.
<?php declare(strict_types=1); namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Rcsofttech\AuditTrailBundle\Attribute\Auditable; #[ORM\Entity] #[Auditable(ignoredProperties: ['internalCode'])] class Product { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] public private(set) ?int $id = null; public function __construct( #[ORM\Column(length: 180)] public private(set) string $name, #[ORM\Column] public private(set) int $priceInCents, #[ORM\Column(length: 40, nullable: true)] public private(set) ?string $internalCode = null, ) { } }
# config/packages/audit_trail.yaml audit_trail: enabled: true ignored_properties: ['updatedAt', 'updated_at'] retention_days: 365 transports: database: enabled: true async: false
ext-mbstringMIT License.