PHPackages                             aw3r1se/laravel-audit-core - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. aw3r1se/laravel-audit-core

ActiveLibrary[Database &amp; ORM](/categories/database)

aw3r1se/laravel-audit-core
==========================

Eloquent model &amp; relation change auditing for Laravel, with a pluggable transport

v1.2.3(1w ago)153↓32.5%1MITPHPPHP ^8.3

Since Jun 4Pushed 1w agoCompare

[ Source](https://github.com/aw3r1se/laravel-audit-core)[ Packagist](https://packagist.org/packages/aw3r1se/laravel-audit-core)[ Docs](https://github.com/aw3r1se/laravel-audit-core)[ RSS](/packages/aw3r1se-laravel-audit-core/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (32)Versions (7)Used By (1)

laravel-audit-core
==================

[](#laravel-audit-core)

Eloquent model **and relation** change auditing for Laravel, with a pluggable delivery transport. Records create/update/delete state plus relation mutations (`attach`/`detach`/`sync`/`toggle`/`associate`/`pivot` updates) into a request-scoped buffer, then dispatches a single event per request.

It is **Octane/RoadRunner safe**: the buffer is a scoped singleton and is always resolved inside the recording closures, never captured at model boot.

What this package does *not* do
-------------------------------

[](#what-this-package-does-not-do)

It does not talk to any storage or message broker, and it has no read API. The buffer is handed to a `transport` you provide. The read side (querying past audit logs, presentation, localization) stays in your application — this package is purely the recording engine.

Install
-------

[](#install)

```
composer require aw3r1se/laravel-audit-core
php artisan vendor:publish --tag=audit-config
```

The service provider is auto-discovered.

Usage
-----

[](#usage)

### 1. Make a model auditable

[](#1-make-a-model-auditable)

```
use Aw3r1se\Audit\Concerns\InteractsWithAudit;
use Aw3r1se\Audit\Contracts\Auditable;

class Post extends Model implements Auditable
{
    use InteractsWithAudit;

    // Optional per-model tweaks — just declare the properties:
    /** Added on top of the global config('audit.ignored_fields'). */
    protected array $auditIgnoredFields = ['remember_token'];

    /** Relation mutations on these are not recorded. */
    protected array $auditIgnoredRelations = ['lastUpdateUser'];
}
```

`$auditIgnoredFields` is merged with the global `config('audit.ignored_fields')`, so you only list the extras. For computed values, override `getAuditIgnoredFields()` / `getAuditIgnoredRelations()` instead.

The trait overrides the Eloquent relation factory methods, so relation changes on `belongsTo`, `hasOne/Many`, `morphOne/Many`, `belongsToMany` and `morphToMany` are audited automatically. No changes to your relation definitions are needed.

#### Weak entities (no primary key)

[](#weak-entities-no-primary-key)

Some child records have no key of their own (`$incrementing = false`, no surrogate id). For those, `getKey()` is `null`, so a recorded id would be meaningless. The engine detects this and falls back to a **filtered attribute snapshot** of the row (honouring `getHidden()` and the ignored fields), both in the relation payload (`attached`/`detached`) and in a model's own `model_id`. You get the actual state of the change instead of `null`.

### Recording strategy: diff vs snapshot

[](#recording-strategy-diff-vs-snapshot)

By default each model event is recorded as a **diff** — new attributes on create, changed attributes on update, the original row on delete. You can instead record a **snapshot**: the model's full filtered attributes plus a recursive snapshot of selected relations.

Pick the default for every model in config, and override it per model:

```
// config/audit.php
'strategy' => 'snapshot', // 'changes' (default) | 'snapshot' | any AuditStrategy class
```

```
class Order extends Model implements Auditable
{
    use InteractsWithAudit;

    // Override just for this model (a config key or an AuditStrategy class).
    protected string $auditStrategy = 'snapshot';

    // Relations embedded in the snapshot — dot-notation for nesting.
    protected array $auditSnapshotRelations = ['customer', 'lines.product'];
}
```

A snapshot entry's `state` looks like:

```
{
  "attributes": { "status": "paid", "total": 4200 },
  "relations": {
    "customer": { "name": "ACME" },
    "lines": [ { "qty": 2, "relations": { "product": { "sku": "A1" } } } ]
  }
}
```

Relations are queried fresh at capture time (honouring `getHidden()` and the ignored fields, same as attributes), so the snapshot reflects current persisted state. Deletions are captured on `deleting`, while relations are still attached.

This only shapes a model's own create/update/delete entry; relation-mutation recording (`attach`/`detach`/`sync`) is independent and runs under either strategy. To add your own strategy, implement `Aw3r1se\Audit\Contracts\AuditStrategy` and register it under `config('audit.strategies')` (or reference it by class-string).

### 2. Attach the middleware

[](#2-attach-the-middleware)

Add `Aw3r1se\Audit\Http\Middleware\AuditActions` to the route group you want audited (typically your API). It records every `POST/PUT/PATCH/DELETE` and dispatches `Aw3r1se\Audit\Events\UserActionEvent` carrying an immutable `AuditEvent`. Pass route arguments to exclude request keys from the captured body, e.g. `->middleware(AuditActions::class.':password')`.

### 3. Provide a transport

[](#3-provide-a-transport)

Implement `Aw3r1se\Audit\Contracts\AuditTransport` and point config at it:

```
// config/audit.php
'transport' => App\Audit\RabbitMqTransport::class,
```

```
final class RabbitMqTransport implements AuditTransport
{
    public function send(AuditEvent $event): void
    {
        // publish $event->toArray() to your broker / service
    }
}
```

The package ships `NullTransport` (default, no-op) and `LogTransport` (PSR-3). Delivery runs through the queued `ForwardAuditToTransport` listener, so it never blocks the request — configure your queue accordingly.

Configuration
-------------

[](#configuration)

keydefaultpurpose`strategy``'changes'`default recording strategy (`changes` / `snapshot`)`strategies``changes`/`snapshot` mapkey → `AuditStrategy` class, for per-model selection`transport``NullTransport::class`who receives each `AuditEvent``user_id_attribute``audit_user_id`request attribute used to resolve a logged-out actor`auditable_methods``['POST','PUT','PATCH','DELETE']`HTTP methods that trigger an audit`ignored_fields``['created_at','updated_at']`attributes stripped from every recorded stateTesting
-------

[](#testing)

```
composer install
composer test
```

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance98

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~8 days

Total

6

Last Release

10d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e6ea307b87fb93d67f2da48db1a86aa97f0a3a55f96d7e6ffd664355ab7fea04?d=identicon)[aw3r1se](/maintainers/aw3r1se)

---

Top Contributors

[![aw3r1se](https://avatars.githubusercontent.com/u/80489373?v=4)](https://github.com/aw3r1se "aw3r1se (7 commits)")

---

Tags

laraveleloquentAuditactivity-log

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/aw3r1se-laravel-audit-core/health.svg)

```
[![Health](https://phpackages.com/badges/aw3r1se-laravel-audit-core/health.svg)](https://phpackages.com/packages/aw3r1se-laravel-audit-core)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)[moonshine/moonshine

Laravel administration panel

1.3k253.1k86](/packages/moonshine-moonshine)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.6k](/packages/simplestats-io-laravel-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
