Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Auditor Bundle Laravel Package

alli-govender/auditor-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require alli-govender/auditor-bundle
    

    Ensure your composer.json aligns with the package's requirements (PHP ≥7.2, Symfony ≥3.4).

  2. Enable the Bundle: Add to config/bundles.php:

    return [
        // ...
        AlliGovender\AuditorBundle\AlliGovenderAuditorBundle::class => ['all' => true],
    ];
    
  3. Configure Basic Auditing: Edit config/packages/auditor.yaml (auto-generated):

    alli_govender_auditor:
        connection: default # Your Doctrine connection name
        logger: true       # Enable logging to Doctrine audit logs
        log_entry_class: AlliGovender\AuditorBundle\Entity\AuditEntry # Default entity
        log_entry_manager: true # Auto-manage audit entries
    
  4. Mark an Entity as Auditable: Add @Auditable annotation to your entity:

    use AlliGovender\AuditorBundle\Annotation\Auditable;
    
    /**
     * @Auditable
     */
    class User
    {
        // ...
    }
    
  5. Run Migrations:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    

    This creates the audit_entry table and sets up auditing for all @Auditable entities.


First Use Case: Debugging a User Update

  1. Update a user via a form/controller:
    $user->setEmail('new@example.com');
    $entityManager->persist($user);
    $entityManager->flush();
    
  2. Check audit logs in the database:
    SELECT * FROM audit_entry WHERE object_class = 'App\Entity\User' ORDER BY id DESC;
    
    You’ll see a record of the email field change, including:
    • Old value (new@example.comold@example.com).
    • Timestamp, user (if authenticated), and action type (UPDATE).

Implementation Patterns

Workflow: Auditing CRUD Operations

  1. Create: Automatically logs the initial state of all fields for new entities.

    $user = new User();
    $user->setName('John Doe');
    $entityManager->persist($user);
    $entityManager->flush();
    

    Audit log: Records the creation with all field values.

  2. Update: Logs only changed fields (delta tracking).

    $user->setName('Jane Doe');
    $entityManager->flush();
    

    Audit log: Shows name changed from John Doe to Jane Doe.

  3. Delete: Logs the deletion with the last known state.

    $entityManager->remove($user);
    $entityManager->flush();
    

    Audit log: Marks action as DELETE with pre-deletion data.


Integration Tips

  1. Custom Audit Entries: Extend the default AuditEntry entity to add metadata (e.g., ipAddress, userAgent):

    namespace App\Entity;
    
    use AlliGovender\AuditorBundle\Entity\AuditEntry as BaseAuditEntry;
    
    class CustomAuditEntry extends BaseAuditEntry
    {
        private $ipAddress;
        // Add getters/setters and DB column (via ORM annotations).
    }
    

    Update auditor.yaml:

    alli_govender_auditor:
        log_entry_class: App\Entity\CustomAuditEntry
    
  2. Conditional Auditing: Use the on option to audit only specific actions (e.g., CREATE and UPDATE):

    /**
     * @Auditable(on={"CREATE", "UPDATE"})
     */
    class Product {}
    
  3. Excluding Fields: Skip auditing sensitive fields (e.g., passwords):

    /**
     * @Auditable(exclude={"password", "apiToken"})
     */
    class User {}
    
  4. Event Listeners: Attach custom logic to audit events (e.g., log to an external service):

    namespace App\EventListener;
    
    use AlliGovender\AuditorBundle\Event\AuditEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class CustomAuditSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                AuditEvent::PRE_AUDIT => 'onPreAudit',
            ];
        }
    
        public function onPreAudit(AuditEvent $event)
        {
            // Add custom logic (e.g., log to Slack).
        }
    }
    

    Register the subscriber in services.yaml:

    services:
        App\EventListener\CustomAuditSubscriber:
            tags: ['kernel.event_subscriber']
    
  5. Querying Audits: Use Doctrine queries to fetch audit trails:

    $auditEntries = $entityManager->getRepository(AuditEntry::class)
        ->findBy(['objectClass' => User::class], ['id' => 'DESC']);
    

Performance Considerations

  1. Batch Processing: For bulk operations (e.g., imports), disable auditing temporarily:

    $entityManager->getConnection()->getConfiguration()->setSQLLogger(null);
    // Perform bulk operations...
    $entityManager->getConnection()->getConfiguration()->setSQLLogger($logger);
    
  2. Indexing: Add indexes to the audit_entry table for frequently queried fields:

    CREATE INDEX idx_audit_object_class ON audit_entry(object_class);
    CREATE INDEX idx_audit_timestamp ON audit_entry(logged_at);
    
  3. Asynchronous Logging: Offload audit logging to a queue (e.g., Symfony Messenger) for high-traffic apps:

    alli_govender_auditor:
        logger: false # Disable direct DB logging
    

    Implement a custom AuditLogger service to handle async writes.


Gotchas and Tips

Pitfalls

  1. Schema Updates:

    • Running doctrine:schema:update --force without migrations may break audit tables.
    • Always use migrations for schema changes:
      php bin/console make:migration
      php bin/console doctrine:migrations:migrate
      
  2. Circular References: Auditing entities with bidirectional relationships (e.g., UserOrder) may log redundant data.

    • Fix: Use exclude or on to limit audited actions:
      /**
       * @Auditable(on={"CREATE"}, exclude={"orders"})
       */
      class User {}
      
  3. Transaction Rollbacks: Audit logs are committed after the main transaction.

    • If the main transaction rolls back, audit logs may still persist.
    • Workaround: Use a transaction listener to roll back audit logs on failure.
  4. Large Entities: Auditing entities with many fields (e.g., JSON columns) can bloat the database.

    • Tip: Use serialize for complex fields or exclude them:
      /**
       * @Auditable(exclude={"metadata"})
       */
      class Config {}
      
  5. Symfony Cache: Clear the cache after changing auditor.yaml:

    php bin/console cache:clear
    

Debugging

  1. Enable Verbose Logging: Add to config/packages/dev/auditor.yaml:

    alli_govender_auditor:
        logger: true
        debug: true # Logs audit events to Symfony's logger
    

    Check logs with:

    php bin/console debug:config alli_govender_auditor
    
  2. Check Audit Events: Listen for AuditEvent in development to inspect payloads:

    use AlliGovender\AuditorBundle\Event\AuditEvent;
    
    $eventDispatcher->addListener(AuditEvent::POST_AUDIT, function (AuditEvent $event) {
        \Symfony\Component\Debug\Debug::dump($event->getAuditEntry());
    });
    
  3. Common Issues:

    • No audit logs: Verify @Auditable is on the entity and the connection is correct in auditor.yaml.
    • Missing fields: Check for typos in exclude or on annotations.
    • Performance lag: Audit logs may slow down writes. Consider async logging or disabling for non-critical entities.

Extension Points

  1. Custom Audit Strategies: Implement AlliGovender\AuditorBundle\Strategy\AuditStrategyInterface to define custom logic (e.g., log only changes to specific fields):
    namespace App\Strategy;
    
    use AlliGovender\AuditorBundle\Strategy\AuditStrategyInterface;
    
    class CustomFieldStrategy implements AuditStrategyInterface
    {
        public function shouldAudit($entity, $field, $action)
        {
            return in_array($field, ['name', 'email']) && $
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky