# Audit Changes Logs

![](https://laraveldaily.com/wp-content/uploads/2019/03/modules-audit-logs-table.png)

&#x20;This module logs all the actions by the users. Every time someone adds/updates/deletes an entry, it will log the action in database table **audit\_logs**, which will be shown in a separate menu item (see above).

![](https://laraveldaily.com/wp-content/uploads/2019/03/modules-audit-logs-database.png)

&#x20;For that, we use [Model Observer](https://laravel.com/docs/5.8/eloquent#observers) functionality of Laravel.

&#x20;Video demo of a module:

{% embed url="<https://www.youtube.com/watch?v=zUIA99xKyJQ>" %}

## How does the result look in QuickAdminPanel code?

&#x20;We create a new database table with migration:

```
Schema::create('audit_logs', function (Blueprint $table) {
    $table->increments('id');
    $table->text('description');
    $table->unsignedInteger('subject_id')->nullable();
    $table->string('subject_type')->nullable();
    $table->unsignedInteger('user_id')->nullable();
    $table->text('properties')->nullable();
    $table->string('host', 45)->nullable();
    $table->timestamps();
});
```

&#x20;Then we create a new model called **app/AuditLog.php**:

```
class AuditLog extends Model
{
    protected $fillable = [
        'description',
        'subject_id',
        'subject_type',
        'user_id',
        'properties',
        'host',
    ];

    protected $casts = [
        'properties' => 'collection',
    ];
}
```

&#x20;Then we create one new **Trait** class, with this code.\
&#x20;**app/Traits/Auditable.php**

```
namespace App\Traits;

use App\AuditLog;
use Illuminate\Database\Eloquent\Model;

trait Auditable
{
    public static function bootAuditable()
    {
        static::created(function (Model $model) {
            self::audit('created', $model);
        });

        static::updated(function (Model $model) {
            self::audit('updated', $model);
        });

        static::deleted(function (Model $model) {
            self::audit('deleted', $model);
        });
    }

    protected static function audit($description, $model)
    {
        AuditLog::create([
            'description'  => $description,
            'subject_id'   => $model->id ?? null,
            'subject_type' => get_class($model) ?? null,
            'user_id'      => auth()->id() ?? null,
            'properties'   => $model ?? null,
            'host'         => request()->ip() ?? null,
        ]);
    }
}
```

&#x20;Then we attach this trait for CRUD model: **app/Project.php:**

```
use App\Traits\Auditable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Project extends Model
{
    use SoftDeletes, Auditable;

    // ...
```

&#x20;Finally, we create a CRUD called **Audit Logs** to just view the table.\
&#x20;**resources/views/admin/auditLogs/index.blade.php**

```
<table class=" table table-bordered table-striped datatable">
<thead>
<tr>
<th>
    {{ trans('global.auditLog.fields.id') }}
</th>
<th>
    {{ trans('global.auditLog.fields.description') }}
</th>
<th>
    {{ trans('global.auditLog.fields.subject_id') }}
</th>
<th>
    {{ trans('global.auditLog.fields.subject_type') }}
</th>
<th>
    {{ trans('global.auditLog.fields.user_id') }}
</th>
<th>
    {{ trans('global.auditLog.fields.host') }}
</th>
<th>
    {{ trans('global.auditLog.fields.created_at') }}
</th>
<th>
 
</th>
</tr>
</thead>
<tbody>
@foreach($auditLogs as $key => $auditLog)
<tr>
    <td>
        {{ $auditLog->id ?? '' }}
    </td>
    <td>
        {{ $auditLog->description ?? '' }}
    </td>
    <td>
        {{ $auditLog->subject_id ?? '' }}
    </td>
    <td>
        {{ $auditLog->subject_type ?? '' }}
    </td>
    <td>
        {{ $auditLog->user_id ?? '' }}
    </td>
    <td>
        {{ $auditLog->host ?? '' }}
    </td>
    <td>
        {{ $auditLog->created_at ?? '' }}
    </td>
    <td>
        @can('audit_log_show')
            <a class="btn btn-xs btn-primary" href="{{ route('admin.audit-logs.show', $auditLog->id) }}">
                {{ trans('global.view') }}
            </a>
        @endcan
        @can('audit_log_edit')
            <a class="btn btn-xs btn-info" href="{{ route('admin.audit-logs.edit', $auditLog->id) }}">
                {{ trans('global.edit') }}
            </a>
        @endcan
        @can('audit_log_delete')
            <form action="{{ route('admin.audit-logs.destroy', $auditLog->id) }}" method="POST" onsubmit="return confirm('{{ trans('global.areYouSure') }}');" style="display: inline-block;">
                <input type="hidden" name="_method" value="DELETE">
                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                <input type="submit" class="btn btn-xs btn-danger" value="{{ trans('global.delete') }}">
            </form>
        @endcan
    </td>

</tr>
@endforeach
</tbody>
</table>
```

&#x20;You can easily customize the module after download by adding more fields or more logic in the files above.

## How to install/use the module?

&#x20;All you need to do is go to your panel's **Modules** menu item, find the module in the list and click **Install**.

![](https://laraveldaily.com/wp-content/uploads/2019/03/modules-audit-logs-install.png)

&#x20;Then for every CRUD you may specify to enable Audit Logs for that CRUD.

![](https://laraveldaily.com/wp-content/uploads/2019/03/modules-audit-logs-crud.png)

## How to Customize the Module

{% embed url="<https://www.youtube.com/watch?v=8L2Jzo0tVpE>" %}

## More information

* [Eloquent Observers](https://laravel.com/docs/master/eloquent#observers)
