Installation:
composer require data-dog/audit-bundle
Add to config/bundles.php:
DataDog\AuditBundle\DataDogAuditBundle::class => ['all' => true],
Database Setup: Run migrations or schema update:
php bin/console doctrine:migrations:diff && php bin/console doctrine:migrations:migrate
(or doctrine:schema:update --force)
First Audit:
Perform a CRUD operation on any Doctrine entity (e.g., User):
$user = new User();
$user->setName('Test');
$em->persist($user);
$em->flush(); // Audit log auto-generated
Verify audit logs in the database (audit_entry table) after modifying an entity. Check fields like:
action (e.g., INSERT, UPDATE)entity_class (e.g., App\Entity\User)changes (JSON diff of modified fields)user_id (if authenticated via TokenStorage)Automatic Auditing:
persist(), merge(), remove()) trigger audits on flush().Excluding Entities:
Use entities config to exclude specific entities:
# config/packages/data_dog_audit.yaml
data_dog_audit:
entities:
exclude:
- 'App\Entity\UnimportantEntity'
Customizing Audit Fields:
Extend the AuditEntry entity (e.g., add ip_address):
// src/Entity/AuditEntry.php
use DataDog\AuditBundle\Entity\AuditEntry as BaseAuditEntry;
class AuditEntry extends BaseAuditEntry {
/**
* @ORM\Column(type="string", nullable=true)
*/
private $ipAddress;
}
Linking Users to Audits:
Ensure TokenStorage is configured (e.g., Symfony’s security.token_storage). The bundle auto-links the current user to audits.
Querying Audits: Use Doctrine queries to filter audits:
$audits = $em->getRepository(AuditEntry::class)
->findBy(['entityClass' => User::class, 'action' => 'UPDATE']);
AuditEntry in tests to avoid DB writes:
$this->entityManager->getConnection()->getConfiguration()->setSQLLogger(null);
Direct SQL/DQL Bypasses Audits:
entityManager->createNativeQuery()) or DQL queries are not audited.Circular References in Diffs:
entities.ignore_fields:
data_dog_audit:
entities:
ignore_fields:
- 'App\Entity\Post#comments' # Skip comments collection
User Linking Failures:
TokenStorage is empty (e.g., API requests without auth), audits will lack user_id.$auditEntry->setUser($this->getAnonymousUser());
Schema Updates:
AuditEntry, run migrations after disabling the bundle temporarily:
php bin/console config:dump --env=prod | grep -v data_dog_audit
debug: true in config to log audit events to Symfony’s logger:
data_dog_audit:
debug: true
changes field may contain malformed JSON if entity getters/setters throw exceptions. Validate with:
json_decode($auditEntry->getChanges(), true);
Custom Actions: Trigger audits manually for non-ORM changes:
$auditManager = $this->container->get('data_dog_audit.manager.audit');
$auditManager->audit($entity, 'CUSTOM_ACTION', ['custom_data' => 'value']);
Event Listeners:
Subscribe to data_dog_audit.pre_audit or data_dog_audit.post_audit events to modify audit data:
// src/EventListener/AuditListener.php
public function onPreAudit(AuditEvent $event) {
$event->getAuditEntry()->setIpAddress($this->getClientIp());
}
Async Processing: Offload audit writes to a queue (e.g., Symfony Messenger) to reduce transaction time:
# config/packages/messenger.yaml
framework:
messenger:
transports:
audit: '%env(MESSENGER_TRANSPORT_DSN)%'
routing:
'DataDog\AuditBundle\Message\AuditMessage': audit
How can I help you explore Laravel packages today?