PHPackages                             hosmelq/laravel-audit-logs - 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. [Logging &amp; Monitoring](/categories/logging)
4. /
5. hosmelq/laravel-audit-logs

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

hosmelq/laravel-audit-logs
==========================

Structured audit logs for Laravel with actors, targets, and request metadata.

v1.1.0(1mo ago)12.2k↑10500%MITPHPPHP ^8.3CI passing

Since Jun 11Pushed 1mo agoCompare

[ Source](https://github.com/hosmelq/laravel-audit-logs)[ Packagist](https://packagist.org/packages/hosmelq/laravel-audit-logs)[ RSS](/packages/hosmelq-laravel-audit-logs/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (44)Versions (3)Used By (0)

Laravel Audit Logs
==================

[](#laravel-audit-logs)

Laravel Audit Logs provides a simple, fluent API for recording application audit events. You may include actors, targets, request metadata, and custom metadata for each event.

Table of Contents
-----------------

[](#table-of-contents)

- [Introduction](#introduction)
- [Installation](#installation)
- [Configuration](#configuration)
    - [Default Attributes](#default-attributes)
    - [Request Metadata](#request-metadata)
    - [Storage Configuration](#storage-configuration)
    - [Environment Variables](#environment-variables)
- [Recording Audit Logs](#recording-audit-logs)
    - [The Audit Log Helper](#the-audit-log-helper)
    - [Fluent Attributes](#fluent-attributes)
    - [Audit Log Identities](#audit-log-identities)
    - [Recording Multiple Logs](#recording-multiple-logs)
    - [Correlating Logs](#correlating-logs)
    - [Defaults &amp; Missing Values](#defaults--missing-values)
- [Enum Values](#enum-values)
- [Reading Audit Logs](#reading-audit-logs)
- [Retention &amp; Pruning](#retention--pruning)
- [Adding a Custom Audit Log Model](#adding-a-custom-audit-log-model)
- [Testing Your Application](#testing-your-application)
    - [Faking Audit Logs](#faking-audit-logs)
    - [Assertions](#assertions)
    - [Inspecting Recorded Logs](#inspecting-recorded-logs)
- [Running the Test Suite](#running-the-test-suite)
- [Changelog](#changelog)
- [Contributing](#contributing)
- [License](#license)

Introduction
------------

[](#introduction)

Audit logs capture meaningful application actions, such as publishing a document, changing account settings, or performing an administrative action. This package provides a clean API to explicitly record those events to a database table with sensible defaults.

Installation
------------

[](#installation)

First, install the package via Composer:

```
composer require hosmelq/laravel-audit-logs
```

Next, publish the configuration and migration files:

```
php artisan audit-log:install
```

If you prefer, you may publish the assets manually:

```
php artisan vendor:publish --tag="audit-log-config"
php artisan vendor:publish --tag="audit-log-migrations"
```

The installer can run the migrations for you. If you skip that prompt, run them manually:

```
php artisan migrate
```

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

[](#configuration)

After publishing the package assets, the configuration file will be located at `config/audit-log.php`. This configuration file allows you to specify default attributes, request metadata capture, retention, and storage.

### Default Attributes

[](#default-attributes)

You may specify the default `bucket` and `source` values using the `audit-log.defaults.bucket` and `audit-log.defaults.source` configuration values. These values are used when an audit log is recorded without explicit values.

### Request Metadata

[](#request-metadata)

HTTP requests may fill missing `remoteIp` and `userAgent` values when request capture is enabled. Capture is enabled for remote IP and user agent by default, but console capture is disabled unless `audit-log.request.capture_in_console` is enabled.

### Storage Configuration

[](#storage-configuration)

Audit logs are written to the configured database table. You may configure the database connection and table name used to store audit logs.

A `null` storage connection uses Laravel's default database connection.

### Environment Variables

[](#environment-variables)

The following environment variables are supported:

- `AUDIT_LOG_DEFAULTS_BUCKET` (default: `application`)
- `AUDIT_LOG_DEFAULTS_SOURCE` (default: `platform`)
- `AUDIT_LOG_REQUEST_CAPTURE_IN_CONSOLE` (default: `false`)
- `AUDIT_LOG_REQUEST_CAPTURE_REMOTE_IP` (default: `true`)
- `AUDIT_LOG_REQUEST_CAPTURE_USER_AGENT` (default: `true`)
- `AUDIT_LOG_RETENTION_DAYS` (default: `null`)
- `AUDIT_LOG_STORAGE_CONNECTION` (default: `null`)
- `AUDIT_LOG_STORAGE_INSERT_CHUNK_SIZE` (default: `500`)
- `AUDIT_LOG_STORAGE_TABLE` (default: `audit_logs`)

Recording Audit Logs
--------------------

[](#recording-audit-logs)

### The Audit Log Helper

[](#the-audit-log-helper)

Call the `audit_log` helper with an event, set the fields you care about, and call `record`:

```
use function HosmelQ\AuditLog\audit_log;

audit_log('document.published')
    ->tenant('org_123')
    ->record();
```

Call `audit_log()` without an event to record prepared logs or run a correlation scope.

### Fluent Attributes

[](#fluent-attributes)

Use the fluent builder to attach common audit log attributes:

```
use function HosmelQ\AuditLog\audit_log;

audit_log('document.published')
    ->tenant('org_123')
    ->actor(type: 'user', id: 'member_123')
    ->target(type: 'document', id: 'doc_123')
    ->metadata(['visibility' => 'public'])
    ->record();
```

Optional fields include `description`, `bucket`, `source`, `occurredAt`, `remoteIp`, `userAgent`, `id`, and `correlationId`. Tenant, actor, and target IDs may be integers or strings.

You may call `toAuditLogData` when you need the data object without recording it immediately:

```
use function HosmelQ\AuditLog\audit_log;

$log = audit_log('document.published')
    ->tenant('org_123')
    ->target(type: 'document', id: 'doc_123')
    ->toAuditLogData();

audit_log()->record($log);
```

You may also record existing `AuditLogData` instances through the facade:

```
use HosmelQ\AuditLog\Facades\AuditLog;

AuditLog::record($log);
```

### Audit Log Identities

[](#audit-log-identities)

Implement `HasAuditLogIdentity` when an object should be usable as an audit log actor or target:

```
use HosmelQ\AuditLog\Contracts\HasAuditLogIdentity;
use HosmelQ\AuditLog\Support\AuditLogIdentity;
use Illuminate\Database\Eloquent\Model;

class User extends Model implements HasAuditLogIdentity
{
    public function auditLogIdentity(): AuditLogIdentity
    {
        return new AuditLogIdentity(
            id: $this->id,
            name: $this->email,
            type: $this->getMorphClass(),
        );
    }
}
```

Pass the object directly to `actor` or `target`:

```
use function HosmelQ\AuditLog\audit_log;

audit_log('auth.sessions.delete')
    ->actor($user)
    ->target($organization)
    ->tenant($organization->id)
    ->record();
```

### Recording Multiple Logs

[](#recording-multiple-logs)

Pass an iterable to record multiple logs at once:

```
use function HosmelQ\AuditLog\audit_log;

audit_log()->record([
    audit_log('document.published')->tenant('org_123')->toAuditLogData(),
    audit_log('notification.sent')->tenant('org_123')->toAuditLogData(),
]);
```

When an iterable contains more than one log, logs without an explicit `correlationId` receive the same generated correlation ID.

### Correlating Logs

[](#correlating-logs)

Use `correlate` when separate `record` calls should share one correlation ID:

```
use function HosmelQ\AuditLog\audit_log;

audit_log()->correlate(function (): void {
    audit_log('document.published')
        ->target(type: 'document', id: 'doc_123')
        ->record();

    audit_log('notification.sent')
        ->target(type: 'document', id: 'doc_123')
        ->record();
});
```

Pass a correlation ID as the second argument when the scope should reuse an existing ID.

### Defaults &amp; Missing Values

[](#defaults--missing-values)

Missing values follow these rules:

- If no actor is set, a system actor is used.
- If no bucket or source is set, the configured default is used.
- If no ID is set, one is generated.
- If no occurrence time is set, the current time is used.
- If request metadata is not provided, request capture may fill it.

Enum Values
-----------

[](#enum-values)

The fluent helper accepts strings or backed enums for events, buckets, sources, actor types, and target types. Backed enum values are stored as strings.

```
use function HosmelQ\AuditLog\audit_log;

enum AuditEvent: string
{
    case DocumentPublished = 'document.published';
}

audit_log(AuditEvent::DocumentPublished)
    ->tenant('org_123')
    ->record();
```

Reading Audit Logs
------------------

[](#reading-audit-logs)

Use the package model to query stored logs:

```
use HosmelQ\AuditLog\Models\AuditLog;

$logs = AuditLog::query()
    ->where('tenant_id', 'org_123')
    ->where('bucket', 'application')
    ->latest('occurred_at')
    ->get();
```

JSON columns such as `metadata`, `actor_metadata`, and `targets` are cast to arrays, while `occurred_at`, `inserted_at`, and `expires_at` are cast to immutable dates.

Retention &amp; Pruning
-----------------------

[](#retention--pruning)

Set `audit-log.retention.days` to expire audit logs after a fixed number of days. A `null` value keeps audit logs indefinitely.

When retention is configured, each row receives an `expires_at` value derived from `occurred_at`. Prune expired rows using Laravel's `model:prune` command:

```
use HosmelQ\AuditLog\Models\AuditLog;
use Illuminate\Support\Facades\Schedule;

Schedule::command('model:prune', [
    '--model' => [AuditLog::class],
])->daily();
```

Adding a Custom Audit Log Model
-------------------------------

[](#adding-a-custom-audit-log-model)

Use a custom model when you need application-specific query scopes or casts. The model must extend the package model:

```
namespace App\Models;

use HosmelQ\AuditLog\Models\AuditLog as BaseAuditLog;

class AuditLog extends BaseAuditLog
{
}
```

Register the model once from a service provider:

```
use App\Models\AuditLog;
use HosmelQ\AuditLog\DatabaseAuditLogManager;

DatabaseAuditLogManager::useModel(AuditLog::class);
```

Testing Your Application
------------------------

[](#testing-your-application)

### Faking Audit Logs

[](#faking-audit-logs)

Call `AuditLog::fake()` to replace the manager with an in-memory fake:

```
use HosmelQ\AuditLog\Facades\AuditLog;

use function HosmelQ\AuditLog\audit_log;

AuditLog::fake();

audit_log('document.published')
    ->tenant('org_123')
    ->record();

AuditLog::assertRecorded('document.published');
```

### Assertions

[](#assertions)

Use fake assertions to verify events by string or backed enum:

```
AuditLog::assertRecorded('document.published');
AuditLog::assertNotRecorded('document.archived');
AuditLog::assertRecordedInCorrelation('document.published', 'notification.sent');
AuditLog::assertRecordedTimes('document.published', 1);
```

Use `assertNothingRecorded` when no logs should have been recorded:

```
AuditLog::assertNothingRecorded();
```

### Inspecting Recorded Logs

[](#inspecting-recorded-logs)

Pass a closure to inspect recorded `AuditLogData` objects:

```
use HosmelQ\AuditLog\Data\AuditLogData;
use HosmelQ\AuditLog\Facades\AuditLog;

AuditLog::assertRecorded(function (AuditLogData $log): bool {
    return $log->event === 'document.published'
        && $log->tenantId === 'org_123'
        && $log->actor->id === 'member_123';
});
```

Retrieve recorded logs as a collection and filter them by event string, backed enum, or closure:

```
use HosmelQ\AuditLog\Data\AuditLogData;
use HosmelQ\AuditLog\Facades\AuditLog;

$all = AuditLog::recorded();
$logs = AuditLog::recorded('document.published');
$filtered = AuditLog::recorded(fn (AuditLogData $log): bool => $log->tenantId === 'org_123');
```

Running the Test Suite
----------------------

[](#running-the-test-suite)

```
composer test
```

Changelog
---------

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md) for a list of changes.

Contributing
------------

[](#contributing)

Pull requests are welcome. Please run the test suite before submitting changes.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance94

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

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 ~14 days

Total

2

Last Release

31d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/97fd048037c6d5ccfeebf11961838d5db2dca1baca14fefa373230b301389a03?d=identicon)[hosmelq](/maintainers/hosmelq)

---

Top Contributors

[![hosmelq](https://avatars.githubusercontent.com/u/1166143?v=4)](https://github.com/hosmelq "hosmelq (6 commits)")

---

Tags

auditaudit-logaudit-trailauditinglaravellaravel-audit-logloggingphpphplaravelloggingAuditauditingaudit-trailaudit-loghosmelqlaravel-audit-log

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/hosmelq-laravel-audit-logs/health.svg)

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

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[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)[api-platform/laravel

API Platform support for Laravel

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

Laravel licensing package with polymorphic assignment to any model, activation keys, expirations/renewals, and seat control via LicenseUsage. Supports offline verification with public-key–signed tokens, a CLI to generate/rotate/revoke keys, and an extensible architecture via config and contracts.

1613.3k4](/packages/masterix21-laravel-licensing)

PHPackages © 2026

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