composer require shkiper/laravel-activity-log
php artisan vendor:publish --provider="Shkiper\ActivityLog\ActivityLogServiceProvider"
mysql):
php artisan migrate
Add the LogsActivity trait to a model (e.g., User):
use Shkiper\ActivityLog\Traits\LogsActivity;
class User extends Model
{
use LogsActivity;
protected static $logAttributes = ['name', 'email']; // Fields to log
protected static $logName = 'user'; // Log entry identifier
}
Now, any created, updated, or deleted events on User will auto-log to the activity_log table.
$logAttributes to specify fields (e.g., ['name', 'email']).$logEvents = ['created', 'updated']).$logOnlyDirty = true to log only changed fields.Override getActivityLogDescription() for custom descriptions:
public function getActivityLogDescription(): string
{
return "User {$this->name} updated their email to {$this->email}";
}
Configure queue settings in config/activity-log.php:
'driver' => 'queue',
'queue' => 'activity-log',
Dispatch logs via ActivityLog::dispatch() in observers/events.
Switch storage backends (e.g., MongoDB/ClickHouse) by updating config/activity-log.php:
'driver' => 'mongodb',
'connection' => 'mongodb',
Use the ActivityLog facade to fetch logs:
// Get all logs for a model
ActivityLog::query()
->where('subject_type', User::class)
->where('subject_id', 1)
->get();
Pair with Laravel observers for granular control:
class UserObserver
{
public function saved(User $user)
{
if ($user->wasChanged('email')) {
ActivityLog::log($user, 'custom_event', ['old_email' => $user->getOriginal('email')]);
}
}
}
php artisan migrate after publishing will break logging.activity-log queue for failures.$logAttributes = ['*']) can bloat storage. Use $logOnlyDirty to optimize.mongodb) matches your setup.activity_log table or MongoDB collection.php artisan queue:work --queue=activity-log --verbose to debug async issues.saved vs updating).password or api_token fields.$logExtra:
protected static $logExtra = ['ip_address', 'user_agent'];
deleted_at is logged if using soft deletes:
protected static $logAttributes = ['*'];
ActivityLog in tests:
$this->partialMock(ActivityLog::class, ['log']);
Shkiper\ActivityLog\Contracts\ActivityLogDriver for new storage backends.ActivityLog::formatLog() to modify log structure.ActivityLog::afterLog().How can I help you explore Laravel packages today?