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

Laravel Auditing Laravel Package

owen-it/laravel-auditing

Audit Eloquent model changes in Laravel with a simple trait. Automatically record create/update/delete events, track who/when/what changed, and retrieve audit history for reports, compliance, and anomaly detection. Flexible drivers and rich metadata support.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require owen-it/laravel-auditing
    

    Publish the migration and config:

    php artisan vendor:publish --provider="OwenIt\Auditing\AuditingServiceProvider" --tag="migrations"
    php artisan vendor:publish --provider="OwenIt\Auditing\AuditingServiceProvider" --tag="config"
    

    Run the migration:

    php artisan migrate
    
  2. Enable Auditing on a Model: Use the Auditable trait in your Eloquent model:

    use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
    use OwenIt\Auditing\AuditingTrait;
    
    class User extends Model implements AuditableContract
    {
        use AuditingTrait;
    }
    
  3. First Use Case: Trigger a model update to generate an audit log:

    $user = User::find(1);
    $user->name = 'Updated Name';
    $user->save(); // Audit log created automatically
    
  4. Retrieve Audit Logs:

    $audits = $user->audits; // Collection of Audit models
    $audits->each(function ($audit) {
        echo $audit->created_at->diffForHumans();
        echo $audit->getChanges();
    });
    

Implementation Patterns

Core Workflows

  1. Model-Level Auditing:

    • Use AuditingTrait for automatic auditing on created, updated, and deleted events.
    • Customize events via getAuditEvents():
      public function getAuditEvents()
      {
          return ['created', 'updated', 'deleted', 'restored'];
      }
      
  2. Dynamic Attribute Handling:

    • Exclude attributes from auditing via getAuditableAttributes():
      public function getAuditableAttributes()
      {
          return ['*']; // Audit all attributes
          // OR
          return ['name', 'email']; // Audit specific attributes
          // OR
          return ['*', '!password']; // Audit all except password
      }
      
  3. Resolver Integration:

    • Resolve dynamic metadata (e.g., IP, user agent) using built-in resolvers:
      // Config: config/auditing.php
      'resolvers' => [
          'user' => \OwenIt\Auditing\Resolvers\UserResolver::class,
          'ip' => \OwenIt\Auditing\Resolvers\IpResolver::class,
      ],
      
  4. Multi-User Auditing:

    • Track changes by multiple users with setAuditUser():
      $user->setAuditUser($currentUser)->update(['name' => 'New Name']);
      
  5. Querying Audits:

    • Filter audits via the Audit model:
      $audits = Audit::where('auditable_type', User::class)
          ->where('event', 'updated')
          ->with('user')
          ->get();
      

Integration Tips

  • Laravel Policies: Use auditing to log policy violations:

    public function delete(User $user, Post $post)
    {
        if (!$user->can('delete', $post)) {
            $post->audits()->create([
                'event' => 'access_denied',
                'changes' => json_encode(['action' => 'delete']),
            ]);
            abort(403);
        }
    }
    
  • API Versioning: Tag audits by API version:

    $audit = $user->audits()->create([
        'event' => 'updated',
        'changes' => $changes,
        'tags' => ['api_v1'],
    ]);
    
  • Custom Drivers: Extend AuditDriver for non-database storage (e.g., Elasticsearch):

    class ElasticsearchDriver extends AuditDriver
    {
        public function log($model, $event, $changes)
        {
            // Custom logic to index audits in Elasticsearch
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Performance Overhead:

    • Auditing adds database writes. Disable for high-frequency models:
      protected $auditDisabled = true;
      
    • Use audit() method to manually trigger audits (avoids event overhead):
      $user->audit('manual_event', ['key' => 'value']);
      
  2. Attribute Serialization:

    • Complex attributes (e.g., relationships, JSON) may not serialize correctly. Use getAuditableValue() to customize:
      public function getAuditableValue($key)
      {
          return $key === 'relationship' ? $this->relationship->id : parent::getAuditableValue($key);
      }
      
  3. Event Ordering:

    • Auditing runs after model events. Override bootAuditing() to adjust:
      protected static function bootAuditing()
      {
          static::updated(function ($model) {
              // Custom logic before auditing
          });
          parent::bootAuditing();
      }
      
  4. Soft Deletes:

    • Soft-deleted models generate deleted audits. Use restored for restore():
      public function getAuditEvents()
      {
          return ['created', 'updated', 'deleted', 'restored'];
      }
      
  5. Resolver Conflicts:

    • Custom resolvers must implement OwenIt\Auditing\Contracts\Resolver. Avoid naming collisions:
      // config/auditing.php
      'resolvers' => [
          'custom' => \App\Resolvers\CustomResolver::class,
      ],
      

Debugging Tips

  1. Audit Logs:

    • Enable debug mode in config/auditing.php:
      'debug' => env('AUDITING_DEBUG', false),
      
    • Check storage/logs/laravel.log for audit-related errors.
  2. Missing Audits:

    • Verify model implements AuditableContract and uses AuditingTrait.
    • Check for auditDisabled or skipAuditing() calls.
  3. Resolver Issues:

    • Test resolvers in isolation:
      $resolver = app(\OwenIt\Auditing\Resolvers\UserResolver::class);
      $resolver->resolve($model);
      
  4. Database Conflicts:

    • Ensure the audits table exists and matches the migration schema. Common issues:
      • Missing updated_at column (added in v4.1.0).
      • Incorrect auditable_id casting (fixed in v8.0.3).

Extension Points

  1. Custom Audit Models:

    • Extend OwenIt\Auditing\Models\Audit:
      class CustomAudit extends Audit
      {
          protected $casts = [
              'changes' => 'array',
              'options' => 'json',
          ];
      }
      
    • Update config:
      'audit_model' => \App\Models\CustomAudit::class,
      
  2. Dynamic Exclusions:

    • Use getAuditableExclusions() for context-aware exclusions:
      public function getAuditableExclusions()
      {
          return $this->isAdmin() ? ['password'] : [];
      }
      
  3. Event-Specific Logic:

    • Override getAuditEvent() to customize events dynamically:
      public function getAuditEvent()
      {
          return $this->isForceUpdating() ? 'force_updated' : parent::getAuditEvent();
      }
      
  4. Attribute Redaction:

    • Redact sensitive data using AttributeRedactor:
      $redactor = new AttributeRedactor();
      $redacted = $redactor->redact($model->toArray(), ['password']);
      
  5. Batch Auditing:

    • Disable auditing during bulk operations:
      \OwenIt\Auditing\Facades\Auditing::disable();
      User::where('active', false)->update(['active' => true]);
      \OwenIt\Auditing\Facades\Auditing::enable();
      
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony