I’ve been working on a new service for the last month or so that enables people to log, track and share walks in the UK’s hills and mountains. The service is based on Laravel, and one of the things I wanted to include on the site was an “activity feed”.
There are two types of feed I wanted to create. The first was for my own benefit. I wanted to see a simple timeline of activity on the site as usage builds up. Secondly, I wanted to be able to log data so that I can create public timelines in the future.
This is all pretty simple to build from scratch, but it turns out that the team at Spatie have already got this covered with a general package for logging activity on a Laravel application.
Log activity inside your Laravel app
https://github.com/spatie/laravel-activitylog
742 forks.
5,749 stars.
0 open issues.
Recent commits:
- Update CHANGELOG, github-actions[bot]
- fix tapActivity being called twiceThe tapActivity method was being called both in LogsActivity trait andin ActivityLogger::log(). Since log() already handles calling tapActivitywhen a subject is set, the duplicate call in LogsActivity is removed.Fixes #1440Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>, Freek Van der Herten
- fix subject() throwing exception for non-SoftDeletes modelsWhen `subject_returns_soft_deleted_models` config is true, the subject()method was calling withTrashed() which throws an exception for modelsthat don't use the SoftDeletes trait.Changed to use withoutGlobalScope(SoftDeletingScope::class) which safelyremoves the soft delete scope only if it exists.Fixes #456Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>, Freek Van der Herten
- check for empty logs after pipeline runsThe check for empty logs was happening before the pipeline ran, so if apipe removed all changes, an empty log entry would still be created.Moved the empty log check to after the pipeline has processed the changes.Fixes #1430Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>, Freek Van der Herten
- fix logUnguarded() to respect Model::unguard()When Model::unguard() is called globally, the $guarded property stillcontains its default value but isUnguarded() returns true. The code wasonly checking $guarded, not the unguarded state.Now checks isUnguarded() to properly detect globally unguarded models.Fixes #1123Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>, Freek Van der Herten
You can easily log custom activity events wherever you like, it’s as easy as:
activity()->log('My custom message here');
Even better though is that you can get it to log changes to Eloquent models automatically using the handy LogsActivity trait. If you add the trait to your model, then creating, updating or deleting a model will automatically create a log entry. The log entries include the item affected, and the “causer” (normally a user).
Going beyond the basics, you can also define custom messages, choose what data to store along with log events.
The activities are logged as normal Eloquent models, so once you have your data logged it’s easy to pull out the information you need using standard Laravel querying, and views.