PHPackages                             sourcetoad/logger - 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. sourcetoad/logger

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

sourcetoad/logger
=================

Creating an audit of activity throughout an application.

v6.2.0(1y ago)538.9k↓41.5%2MITPHPPHP ^8.2||^8.3||^8.4CI passing

Since Apr 1Pushed 5mo ago16 watchersCompare

[ Source](https://github.com/sourcetoad/Logger)[ Packagist](https://packagist.org/packages/sourcetoad/logger)[ RSS](/packages/sourcetoad-logger/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (8)Versions (28)Used By (0)

Sourcetoad Logger
=================

[](#sourcetoad-logger)

This package allows you to log important events, including what data is viewed or updated by whom. Events include:

- Login Events
- Logout Events
- Locked Events
- Failed login attempt
- Password Change
- Attribute changes (except `created_at`/`updated_at`) for models with `Trackable` trait.
- Retrieval Events (Detecting what models were loaded during a request, of those with `Trackable` trait)
- Viewed Keys (Extracting keys in API requests to identify what could be viewed)

This helps answer questions such as:

- Who accessed what information of this account and when?
- When did this person change their password?
- Who changed the information for this user?
- What IP was responsible for these changes?

This plugin is additionally very slim, which makes installation more difficult than a regular plugin. This is because it is expected for perhaps legal reasons, that these logs may not be allowed to be removed for years. This means that the method for storage must be efficient, unlike other packages which may specialize in auditing/logging, but bloat the database with information.

### Laravel

[](#laravel)

You are reading the documentation for Laravel 11.x and 12.x.

- If you're using Laravel 9 or 10 please see the docs for [4.x](https://github.com/sourcetoad/Logger/releases/tag/v4.2.0).
- If you're using Laravel 6, 7 or 8 please see the docs for [3.x](https://github.com/sourcetoad/Logger/releases/tag/v3.0.1).
- If you're using Laravel 5 or below please see docs for [1.x](https://github.com/sourcetoad/Logger/releases/tag/v1.3.0)

The currently supported database(s): `mysql`, `pgsql`

You can install the package via composer:

```
composer require sourcetoad/logger
```

The package will use Auto Discovery feature of Laravel 5.5+ to register the service provider.

Configs
-------

[](#configs)

You may publish the configuration to make changes via:

```
php artisan vendor:publish --tag=logger
```

This will contain model maps, which can be read about below.

Setup
-----

[](#setup)

#### Morphable Entities

[](#morphable-entities)

Due to the large amount of records anticipated to be created, you must create an integer mapping to models in your system. We give an example as follows:

```
// In config/logger.php...

return [

    'morphs' => [
        1 => App\Models\User::class
    ],

];
```

Caution

`0` is not a valid key for the morph map, as it will get resolved to `false` in Laravel's morphing logic.

This points our `App\Models\User::class` to an enum (integer). This means our database is created with small integers vs large fully qualified namespaces.

Recommended action is creating an enum class to describe all models in your system. If an integer mapping is not detected. The system will error out with an `\InvalidArgumentException`.

This enforces the user to create shorthand notation for all models to cut down on database size. If a numeric morph is not found, the system will fail out. Due to issues with blindly overwriting and applying these morphs globally, they are manually applied. This means that morphs in your application are left untouched.

#### Trackable Trait and Contract

[](#trackable-trait-and-contract)

For models that may contain information that you wish to be notified was accessed or mutated. You may add the `Trackable` trait and contract to these models:

```
use Illuminate\Database\Eloquent\Model;
use Sourcetoad\Logger\Contracts\Trackable as TrackableContract;
use Sourcetoad\Logger\Traits\Trackable;

class TrackedModel extends Model implements TrackableContract {
    use Trackable;

    // Tracked models must implement these functions

    public function getOwnerRelationshipName(): ?string
    {
        //
    }

    public function trackableOwnerResolver(): ?Model
    {
        //
    }
}
```

The issue with this, is a record without an owner association is frankly useless. However, you may access a record that has no foreign key or relation to its owner model. Tracking that makes auditing quite useless.

For this reason, we've developed the notion of custom resolvers. They must be implemented for each Entity tracked, which (if tracked) must be in the `morphs` table in the above settings.

#### HasLoggerRelationships Trait

[](#hasloggerrelationships-trait)

For models with the `Trackable` trait, you may add the `HasLoggerRelationships` trait to them to query retrieval and mutation audit records:

```
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Sourcetoad\Logger\Contracts\Trackable as TrackableContract;
use Sourcetoad\Logger\Models\AuditChange;
use Sourcetoad\Logger\Models\AuditModel;
use Sourcetoad\Logger\Models\Relations\LoggerMorphMany;
use Sourcetoad\Logger\Traits\Trackable;
use Sourcetoad\Logger\Traits\HasLoggerRelationships;

/**
 * @property-read Collection $auditChanges
 * @property-read Collection $auditModels
 */
class TrackedModel extends Model implements TrackableContract {
    use Trackable;
    use HasLoggerRelationships;

    /**
     * Collection of mutation logs of this model
     *
     * @return LoggerMorphMany
     */
    public function auditChanges(): LoggerMorphMany
    {
        return $this->loggerMorphMany(AuditChange::class, 'entity');
    }

    /**
     * Collection of access logs of this model
     *
     * @return LoggerMorphMany
     */
    public function auditModels(): LoggerMorphMany
    {
        return $this->loggerMorphMany(AuditModel::class, 'entity');
    }
}
```

#### Custom Resolvers

[](#custom-resolvers)

#### Cron

[](#cron)

These custom resolvers don't run as items are entered, due to the load increase. This should arguably be queued, but easier on implementations for a command (cron) system. Use the Laravel Scheduler to execute our command.

```
Schedule::command('logger:audit-resolver')
    ->hourly()
    ->withoutOverlapping();
```

This will run taking 200 items of both changes and retrieved models. It will identify the owner associated with the model through the `Trackable` contract. The functions for each individual model should be easy.

```
public function getOwnerRelationshipName(): string
{
    return 'object.relation.owner';
}

public function trackableOwnerResolver(): Owner
{
    return $this->object->relation->owner;
}
```

As you can see, we have to traverse whatever relation/property we need in order to relate the model at hand to an owner.

However, there may be cases where a tracked model is also the owner of that model. In those cases, there is no relation/property to traverse.

```
public function getOwnerRelationshipName(): null
{
    return null;
}

public function trackableOwnerResolver(): TrackedModel
{
    return $this;
}
```

If neither of these scenarios match, you probably shouldn't be logging it.

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance60

Regular maintenance activity

Popularity34

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity87

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 70.7% 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 ~83 days

Recently: every ~29 days

Total

27

Last Release

444d ago

Major Versions

v1.3.2 → v2.0.02020-04-23

v2.1.0 → v3.0.02021-11-01

v3.0.1 → v4.0.02022-08-30

v4.2.0 → v5.0.02024-07-16

v5.1.1 → v6.0.02024-11-19

PHP version history (5 changes)v1.0.0PHP &gt;=7.1.3

v4.0.0PHP &gt;=8.0.2

v4.2.0PHP ^8.0|^8.1

v5.0.0PHP ^8.2|^8.3

v6.2.0PHP ^8.2||^8.3||^8.4

### Community

Maintainers

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

---

Top Contributors

[![iBotPeaches](https://avatars.githubusercontent.com/u/611784?v=4)](https://github.com/iBotPeaches "iBotPeaches (181 commits)")[![rbondoc96](https://avatars.githubusercontent.com/u/17418786?v=4)](https://github.com/rbondoc96 "rbondoc96 (39 commits)")[![NilsDelaguardia](https://avatars.githubusercontent.com/u/69813293?v=4)](https://github.com/NilsDelaguardia "NilsDelaguardia (20 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (5 commits)")[![erik-perri](https://avatars.githubusercontent.com/u/46399654?v=4)](https://github.com/erik-perri "erik-perri (4 commits)")[![Jasonej](https://avatars.githubusercontent.com/u/43227214?v=4)](https://github.com/Jasonej "Jasonej (3 commits)")[![MOFFROUGH](https://avatars.githubusercontent.com/u/20206597?v=4)](https://github.com/MOFFROUGH "MOFFROUGH (2 commits)")[![charlesreffett](https://avatars.githubusercontent.com/u/59833910?v=4)](https://github.com/charlesreffett "charlesreffett (1 commits)")[![benjie-wd](https://avatars.githubusercontent.com/u/54299748?v=4)](https://github.com/benjie-wd "benjie-wd (1 commits)")

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/sourcetoad-logger/health.svg)

```
[![Health](https://phpackages.com/badges/sourcetoad-logger/health.svg)](https://phpackages.com/packages/sourcetoad-logger)
```

###  Alternatives

[spatie/laravel-activitylog

A very simple activity logger to monitor the users of your website or application

5.8k45.4M309](/packages/spatie-laravel-activitylog)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[aedart/athenaeum

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

245.2k](/packages/aedart-athenaeum)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[spatie/laravel-health

Monitor the health of a Laravel application

86910.0M83](/packages/spatie-laravel-health)[yadahan/laravel-authentication-log

Laravel Authentication Log provides authentication logger and notification for Laravel.

416632.8k5](/packages/yadahan-laravel-authentication-log)

PHPackages © 2026

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