A package to log activity in a Laravel app
In your apps there's probably a lot going on. Users log in and out, they create, update and delete content, mails get sent and so on. For an administrator of an app these events provide useful insights. In almost every project we make at Spatie we log these events and show them in the admin-section of our site. Here's how that looks like in our Laravel template called Blender.
We made a new package called laravel-activitylog
that makes logging activities in a Laravel app a cinch. In this blogpost I'd like to walk you through it.
Basic logging
This is the most basic way to log some activity:
activity()->log('Look mum, I logged something');
This will write a record in the activity_log
table. You can retrieve activity using the Spatie\Activitylog\Models\Activity
model that the package provides.
$lastActivity = Activity::all()->last(); //returns the last logged activity
$lastActivity->description; //returns 'Look mum, I logged something';
You can specify on which object the activity is performed by using performedOn
:
activity()
->performedOn($someContentModel)
->log('edited');
$lastActivity = Activity::all()->last(); //returns the last logged activity
$lastActivity->subject; //returns the model that was passed to `performedOn`;
You can set who or what caused the activity by using causedBy
:
activity()
->causedBy($userModel)
->performedOn($someContentModel)
->log('edited');
$lastActivity = Activity::all()->last(); //returns the last logged activity
$lastActivity->causer; //returns the model that was passed to `causedBy`;
If you're not using causedBy
the package will automatically use the logged in user.
Automatic model event logging
A neat feature of this package is that it can automatically log events such as when a model is created, updated and deleted. To make this work all you need to do is let your model use the Spatie\Activitylog\Traits\LogsActivity
-trait.
As a bonus the package will also log the changed attributes for all these events when setting $logAttributes
property on the model.
Here's an example:
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
class NewsItem extends Model
{
use LogsActivity;
protected $fillable = ['name', 'text'];
protected static $logAttributes = ['name', 'text'];
}
Let's see what gets logged when creating an instance of that model.
$newsItem = NewsItem::create([
'name' => 'original name',
'text' => 'Lorum'
]);
//creating the newsItem will cause an activity being logged
$activity = Activity::all()->last();
$activity->description; //returns 'created'
$activity->subject; //returns the instance of NewsItem that was created
$activity->changes; //returns ['attributes' => ['name' => 'original name', 'text' => 'Lorum']];
Now let's update some that $newsItem
.
$newsItem->name = 'updated name'
$newsItem->save();
//updating the newsItem will cause an activity being logged
$activity = Activity::all()->last();
$activity->description; //returns 'updated'
$activity->subject; //returns the instance of NewsItem that was created
Calling $activity->changes
will return this array:
[
'attributes' => [
'name' => 'original name',
'text' => 'Lorum',
],
'old' => [
'name' => 'updated name',
'text' => 'Lorum',
],
];
Pretty cool, right?
Now, what happens when you call delete?
$newsItem->delete();
//deleting the newsItem will cause an activity being logged
$activity = Activity::all()->last();
$activity->description; //returns 'deleted'
$activity->changes; //returns ['attributes' => ['name' => 'updated name', 'text' => 'Lorum']];
Read the documentation on event logging to learn how to choose the events that must be logged, how to customize the description for an event, and how to specify the attributes of which the changes must be logged.
Using multiple logs
When not specify a log name the activities will be logged on the default log.
activity()->log('hi');
$lastActivity = Spatie\Activitylog\Models\Activity::all()->last();
$lastActivity->log_name; //returns 'default', this value can be changed in the config file ;
You can specify the log on which an activity must be logged by passing the log name to the activity
function:
activity('other-log')->log("hi");
Activity::all()->last()->log_name; //returns 'other-log';
Like mentioned before Activity
model is just a regular Eloquent model that you know and love. So you can just use a where
on it.
Activity::where('log_name' , 'other-log')->get(); //returns all activity from the 'other-log'
The package also provides an inLog
scope you can use:
Activity::inLog('other-log')->get();
//you can pass multiple log names to the scope
Activity::inLog('default', 'other-log')->get();
//passing an array is just as good
Activity::inLog(['default', 'other-log'])->get();
This concludes the tour of laravel-activitylog. Want to know more about the package, then head over to the documentation to learn all the options. If you find this package useful, be sure to take a look at the Laravel packages we previous made.
What are your thoughts on "A package to log activity in a Laravel app"?