Open-source project
spatie/laravel-activitylog avatar
spatie/laravel-activitylog

spatie/laravel-activitylog: Audit Trails for Laravel Models

Log activity inside your Laravel app

5,905 stars744 forksPHPMIT

At a glance

What is it?
A package that writes user and model activity into an activity_log table, with automatic model event logging and a fluent API. It is for Laravel teams that need a queryable audit trail without building one.
Who is it for?
Adopt it if you are on Laravel and want a queryable audit trail tied to your Eloquent models, since the migration, Activity model and attribute_changes output are all first class. Do not adopt it if you need automatic logging of every model without touching each class, or if you are not on Laravel at all.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 21 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap spatie/laravel-activitylog fills in a Laravel app

Laravel ships with a logger, but that logger writes application events to files or channels. It does not know which Eloquent model changed, who changed it, or what the previous value was. Teams that need an audit trail usually end up writing their own table, their own observer hooks, and their own serialisation of old and new values. This package is the version of that work that already exists.

The README states the package "provides easy to use functions to log the activities of the users of your app" and that it "can also automatically log model events". Everything lands in one table, activity_log. That single table is the design decision that matters: activity is queryable with Eloquent like any other model, so filtering by user, by subject or by date range costs no extra infrastructure.

The audience is Laravel developers who need to answer questions such as who renamed this record, when did it happen, and what did it look like before. It is less useful as a general purpose application log, because it is built around models and users, not around arbitrary messages.

How the Activity model, causer and subject fit together

The package exposes a global activity() helper. Calling activity()->log('Look, I logged something') writes a row and returns. The richer form chains performedOn(), causedBy(), withProperties() and log(). The README example shows the result being read back from the last row: subject returns an Eloquent model instance, causer returns your user model, getProperty('customProperty') returns the stored value, and description returns the message.

Model event logging works through the same table. The README example assigns a new name to a NewsItem and saves it; the last activity then has description 'updated' and subject set to the saved NewsItem. Reading attribute_changes on that activity returns an array with two keys, attributes and old, each holding the changed fields. That is the mechanism behind the audit trail: the package records the delta, not just the fact that a save happened.

The causer and subject relationships are why the migration matters. The README notes that the default migration assumes integer model IDs, and that with UUIDs or another format you must adjust the format of the subject_id and causer_id fields in the published migration before migrating. Get that wrong and the foreign keys will not hold the values you expect.

Installing spatie/laravel-activitylog and logging your first change

Installation is three steps. The README gives the composer command, and states the package registers itself automatically, so there is no service provider entry to add by hand.

bash
composer require spatie/laravel-activitylog

Next, publish the migration. The provider class and the tag are both given in the README, so copy them exactly.

bash
php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="activitylog-migrations"

If your models use UUIDs, edit the published migration's subject_id and causer_id columns before the next step. Then run the migration, which creates the activity_log table.

bash
php artisan migrate

The README also lists an optional config publish using the tag activitylog-config, which is worth doing if you plan to change defaults.

bash
php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="activitylog-config"

For a first real use, log something explicitly from tinker or a controller. This is the README's advanced example, and it shows the full chain in one call.

php
activity()
   ->performedOn($anEloquentModel)
   ->causedBy($user)
   ->withProperties(['customProperty' => 'customValue'])
   ->log('Look, I logged something');

After running it, query Activity::all() and take the last row. You should see the description you passed, the subject and causer relationships resolved to your models, and customProperty available through getProperty().

Where the package stops being the right tool

Automatic model event logging is not global by default. The README shows the behaviour on a NewsItem, which implies the model opts in, typically through a trait. A team expecting every write in the application to appear in activity_log without touching model classes will be disappointed, and the README does not present a configuration switch that turns logging on for all models at once.

The second constraint is the ID format. Because the default migration assumes integers for subject_id and causer_id, a project on UUID primary keys must edit the migration before running it. That is a one line change in the published file, but it is a change, and it is the kind of thing that surfaces after migrate has already run on a shared environment.

Third, this is a Laravel package. Nothing in the README suggests framework independence. If your application is not on Laravel, there is no path here, and the Activity model, the helper and the migration are all tied to Eloquent and the artisan publish flow.

Finally, consider volume. Every logged activity is a row in one table. The README does not document a retention policy, pruning command or partitioning strategy. A high write volume application will need its own answer for that, and the package does not provide one.

Activity log versus the framework's own logging and event systems

The obvious alternative inside Laravel is the framework logger plus model observers. An observer gives you a hook on created, updated and deleted; the logger gives you a destination. Together they can produce the same information, and the difference is where the work sits. With observers and the logger you write the serialisation of old and new values yourself, you choose a storage format, and you decide how to query it later. Log files are cheap to write and awkward to filter by user or by model instance.

spatie/laravel-activitylog moves that work into a database table with a defined schema and an Eloquent model on top. The trade-off is real: you gain queryability and lose the simplicity of writing to a file. You also take on a migration and a table in your own database, which means your audit trail now lives in the same place as your application data and shares its backup and retention story.

A second alternative is a dedicated audit service outside the application. That removes the table from your database and centralises trails across services, at the cost of a network dependency on every logged action. For a single Laravel application, the table is usually the smaller commitment. For a fleet of services, it is usually the wrong shape.

Maintenance, versioning and the MIT licence

The repository is not archived, and the last push was on 2026-09-08, the same day release 5.1.1 was tagged. Before that, 5.1.0 landed on 2026-08-12 and 5.0.0 on 2026-03-25. The project keeps a CHANGELOG.md and an UPGRADING.md at the repository root, which is the practical signal for upgrade cost: the README points to UPGRADING for details, so a major version bump is a documented event rather than a surprise. The 5.0.0 release in March 2026 is the most recent major, and any application still on the 4.x line should read that file before moving.

Upgrade cost in normal use is low, because the surface is small: a helper, an Activity model, a migration and a config file. The migration is the part to watch. If a future release changes the schema, you will be running a new migration against a table that already holds your audit history, and that table is not something you can casually truncate.

The licence is MIT, stated in the README and present as LICENSE.md. For most teams that means the usual permissive terms: keep the copyright notice, and you can use it in closed source applications. This is a description of the licence identifier, not legal advice, and anything unusual about your distribution model should go to a lawyer rather than to a package README.

Editorial conclusion

Adopt it if you are on Laravel and want a queryable audit trail tied to your Eloquent models, since the migration, Activity model and attribute_changes output are all first class. Do not adopt it if you need automatic logging of every model without touching each class, or if you are not on Laravel at all. Before installing, check the ID format note in the README: the default migration assumes integer model IDs, so with UUIDs you must adjust subject_id and causer_id in the published migration first.

Frequently asked questions

How do I log activity in Laravel with spatie/laravel-activitylog?

Call the global activity() helper. The README's simplest form is activity()->log('Look, I logged something'), and the advanced form chains performedOn(), causedBy(), withProperties() and log() before writing the row.

What does spatie/laravel-activitylog store in the activity_log table?

It stores the description, the causer (usually your user model), the subject (the Eloquent model the activity was performed on), any custom properties you pass, and for model events the attribute_changes with attributes and old keys.

How do I install spatie/laravel-activitylog?

Run composer require spatie/laravel-activitylog, then publish the migration with the activitylog-migrations tag, adjust subject_id and causer_id if you use UUIDs, and run php artisan migrate. The package registers itself automatically.

Does spatie/laravel-activitylog log model changes automatically?

It can. The README shows a NewsItem being saved and the resulting activity having description 'updated', with attribute_changes returning the new and old values of the changed fields.

Can I use spatie/laravel-activitylog with UUID primary keys?

The README states the default migration assumes integers for model IDs, and that with UUIDs or another format you should adjust the format of the subject_id and causer_id fields in the published migration before continuing.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. spatie/laravel-activitylog on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/spatie-laravel-activitylog.svg)](https://hysenlabs.com/projects/spatie-laravel-activitylog)