Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Activity Log Laravel Package

givanov95/laravel-activity-log

Laravel package for recording activity logs and audit trails. Track user actions and model changes to see who did what and when, with a simple, configurable logging layer for your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package, publish its config and migrations, then run php artisan migrate. Look first at:

  • the package config file for actor resolver, masking, retention, and model/table settings;
  • the generated activity_log_entries migration for indexes used by the query scopes;
  • the ActivityLogEntry model and its scopes;
  • the ActivityLog facade/builder API and Changes/Actor value objects.

The first practical use case is auditing a model change with an explicit actor, subject, action, and changeset:

use ActivityLog\ActivityLog;
use ActivityLog\Actor;
use ActivityLog\Changes;

ActivityLog::record()
    ->by(Actor::user($user, role: 'admin'))
    ->subject($post, label: $post->title)
    ->action('updated')
    ->changes($changes)
    ->save();

On Laravel 12, build the changeset after saving with Changes::fromModel($post) so it can use Model::getPrevious(). On Laravel 11, use Changes::snapshot($post)->diff($before) instead. If no explicit ->by() is supplied, the configured actor resolver records the signed-in user, or system when nobody is signed in.

Implementation Patterns

Explicit actors. Use Actor::user($user, role: '...', label: '...') for human actions, Actor::model($model) when another model caused the change, Actor::guest() for anonymous activity, and Actor::system() for jobs, commands, and integrations. Always pass an actor explicitly for queued jobs and console commands; the default resolver cannot reliably identify the actor there.

Actor resolver fallback. Configure the resolver once for web requests where the signed-in user is the actor. Keep explicit ->by() calls for impersonation, admin actions, API clients, and background work.

Subject and related models. Attach the primary subject with a stored label via ->subject($model, label: '...'), and attach related models when an entry spans multiple records. Stored labels keep history readable after the subject is renamed or deleted.

Changesets. Use Changes::fromModel($model) after save on Laravel 12, Changes::created($model) / Changes::deleted($model) for lifecycle events, and Changes::snapshot($model)->diff($before) on Laravel 11. Use only, except, mask, and merge to shape payloads for domain-specific audit needs. Hidden and configured attributes are masked automatically; encrypted casts are treated like hidden attributes.

Transactions. ActivityLog::record() writes synchronously on the caller’s connection, so it joins the caller’s transaction. Wrap business writes and their audit entries in the same transaction when the log must be atomic with the change. For audit records that must survive a rollback, write them outside the transaction or on a separate connection.

Querying. Use the ActivityLogEntry scopes for day-to-day reads: inScope, forSubject, involving, byActor, byRole, action, and between. A batch UUID is generated per request or job; use it to group all entries produced by one operation.

GDPR and retention. ActivityLog::scrub($model) anonymizes entries about the model and removes its IP from entries it made. ActivityLog::forgetScope() removes scope metadata where applicable. The activity-log:prune command is available but disabled by default; enable it via retention_days only after confirming your compliance requirements.

Gotchas and Tips

  • Laravel 11 limitation: Changes::fromModel() throws a LogicException because it depends on Model::getPrevious() from Laravel 12. Use snapshot()->diff() there.
  • Timing matters: Changes::fromModel() is intended to run after save. Calling it before save will not produce the previous/current diff you expect.
  • Rollbacks remove logs: because entries join the caller’s transaction, rolling back the business write also rolls back the activity entry. Do not assume the log is an independent audit trail unless you deliberately write it elsewhere.
  • Default actor can misattribute: without ->by(), the resolver falls back to the signed-in user or system. In jobs, commands, and service-to-service calls, pass Actor::system() or a model actor explicitly.
  • Hidden and unchanged fields: hidden attributes are masked; unchanged hidden fields are not reported. Encrypted casts follow the same masking behavior. Check your only/except/mask configuration before relying on payload completeness.
  • Scrub is targeted, not a delete: scrub() removes the model’s fields from entries about it and its IP from entries it made. It does not necessarily delete every entry involving the model, so verify your GDPR interpretation.
  • Prune is off by default: retention_days must be configured before activity-log:prune does anything. Treat pruning as a destructive compliance operation and test it on a copy first.
  • Batch UUIDs are per request/job: they are useful for grouping but are not a replacement for domain correlation IDs. Store your own correlation ID in properties when you need cross-system tracing.
  • Indexes matter: the provided scopes are convenient, but high-volume tables need indexes on subject, actor, action, timestamps, and batch UUID. Review the migration before production traffic.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console