『誰がいつ、データをいじったか知りたい』というデータの監視が必要な時に、Laravel Auditingが便利です。
概要
Laravel Auditingはデータベース上の指定した監視対象のテーブルに追加・更新・削除などの変更が行われた場合に、誰がどのような変更を行ったかを自動でログ保存するパッケージです。
インストール & 設定
インストール
composerで行います。
composer require owen-it/laravel-auditing
設定
インストール後、config/app.php
にプロバイダーを追加します。
'providers' => [
+ OwenIt\Auditing\AuditingServiceProvider::class,
],
追加したら、Laravel Auditing用の設定ファイルを作成するために以下のコマンドを実行します。
php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="config"
実行すると、config/audit.php
というファイルが作成されます。特にカスタマイズする必要がなければそのまま、データベースのマイグレーションファイルを以下のコマンドで作成します。
php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="migrations"
実行すると、auditsテーブルを作成するためのdatabase/migrations/yyyy_mm_dd_nnnnnn_create_audits_table.php
というファイルが作成されます。作成後にマイグレーションしてauditsテーブルを作成します。
php artisan migrate
監視
基本的な設定
設定が完了したら、監視したいデータのモデルに追記します。例えばitemsテーブルのデータを監視したい場合は、
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
+ use OwenIt\Auditing\Contracts\Auditable;
+
+ class Item extends Model implements Auditable
- class Item extends Model
{
+ use \OwenIt\Auditing\Auditable;
ちょっとややこしいのですが、インターフェイスはOwenIt\Auditing\Contracts\Auditable
、traitは\OwenIt\Auditing\Auditable
を指定します。これらを追記するだけで、監視対象となります。
実際に監視
では、このテーブルに対して新規登録・変更・削除を行ってみましょう。これらを実行すると、auditsテーブルに以下のようなデータが追加されます。
id | user_type | user_id | event | auditable_type | auditable_id | old_values | new_values | url | ip_address | user_agent | tags | created_at | updated_at |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | NULL | NULL | updated | App\Item | 2 | {"name":"\u8ffd\u52a01"} | {"name":"\u8ffd\u52a02"} | http://localhost:8000/items/2 | 127.0.0.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15 | NULL | 2020-03-23 12:20:34 | 2020-03-23 12:20:34 |
2 | App\User | 1 | created | App\Item | 3 | [] | {"name":"\u307b\u3052","stock":"10","id":3} | http://localhost:8000/items | 127.0.0.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15 | NULL | 2020-03-23 12:21:39 | 2020-03-23 12:21:39 |
3 | App\User | 1 | deleted | App\Item | 3 | {"id":"3","name":"\u307b\u3052","stock":"10"} | [] | http://localhost:8000/items/3 | 127.0.0.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15 | NULL | 2020-03-23 12:51:57 | 2020-03-23 12:51:57 |
監視対象のデータは以下のような内容が蓄積されます。
フィールド名 | 蓄積内容 |
---|---|
id | 監視データのID |
user_type | ユーザモデルのクラス名 |
user_id | ユーザID |
event | 実行したイベント |
auditable_type | 更新したデータモデルのクラス名 |
auditable_id | 更新したデータのID |
old_values | 更新前のデータ |
new_values | 更新後のデータ |
url | 実行されたURL |
ip_address | IPアドレス |
user_agent | ユーザエージェント |
tags | タグ |
created_at | 作成日時(= データが更新された日時) |
updated_at | 更新日時 |
あまりないと思いますが、ログインせずにデータを更新した場合は、user_type
, user_id
がNULLになります。
監視データの取得
監視データは監視対象のモデルに関連しています。
<?php
$item = Item::find(1);
// 該当データの全ての監視データ
$audits = $item->audits;
// 該当データの最初の監視データ
$first = $item->audits()->first();
// 該当データの直近の監視データ
$latest = $item->audits()->latest()->first();
// 該当データの監視データのID指定
$audit = $item->audits()->find(1);
監視データもEloquentモデルなので、直接取得できます。
<?php
use OwenIt\Auditing\Models\Audit;
// 全件取得
$audits = Audit::all();
// ID指定
$audit = Audit::find(1);
カスタマイズ
コンソールコマンドでの実行も監視したい
デフォルトでは、コンソールコマンドやジョブの更新は監視対象外となっています。監視したい場合は、config/audit.php
で設定を変更します。
- 'console' => false,
+ 'console' => true,
監視するフィールドを絞り込みたい
デフォルトでは、登録・更新日時以外を対象とします。監視するフィールドを絞り込みたい場合は監視対象モデルに設定を追記します。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;
class Item extends Model implements Auditable
{
use \OwenIt\Auditing\Auditable;
+ protected $auditInclude = [
+ 'name',
+ ];
逆に除外したい場合は、$auditExclude
に指定することで、除外できます。
蓄積するデータを変えたい
蓄積するデータをカスタマイズしたい場合は、独自のResolverを作成します。Laravel Auditingでは以下のResolver用インターフェイスが用意されています。
インターフェイス | 概要 |
---|---|
OwenIt\Auditing\Contracts\IpAddressResolver | IPアドレス用I/F |
OwenIt\Auditing\Contracts\UrlResolver | URL用I/F |
OwenIt\Auditing\Contracts\UserAgentResolver | ユーザエージェント用I/F |
OwenIt\Auditing\Contracts\UserResolver | ユーザモデル用I/F |
これらを実装することで、蓄積するデータを変えることができます。
<?php
namespace App\Resolvers;
use Illuminate\Support\Facades\Request;
class IpAddressResolver implements \OwenIt\Auditing\Contracts\IpAddressResolver
{
/**
* {@inheritdoc}
*/
public static function resolve(): string
{
return Request::header('HTTP_X_FORWARDED_FOR', '0.0.0.0');
}
}
独自Resolverはconfig/audit.php
で設定することで反映されます。
return [
'resolver' = [
'user' => OwenIt\Auditing\Resolvers\UserResolver::class,
- 'ip_address' => OwenIt\Auditing\Resolvers\IpAddressResolver::class,
+ 'ip_address' => App\Resolvers\IpAddressResolver::class,
'user_agent' => OwenIt\Auditing\Resolvers\UserAgentResolver::class,
'url' => OwenIt\Auditing\Resolvers\UrlResolver::class,
],
];
マスクしたい
監視データは変更前・後の値をそのまま保存しますが、場合によってはマスクして保存したい時もあります。その場合は、監視対象のモデルに設定することで、マスクできます。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;
+use OwenIt\Auditing\Redactors\LeftRedactor;
class Item extends Model implements Auditable
{
use \OwenIt\Auditing\Auditable;
+ protected $attributeModifiers = [
+ 'title' => LeftRedactor::class,
+ ];
LeftRedactor
は左から90%マスクし残り10%はそのまま、RightRedactor
は右から90%マスクします。マスク部分は#####
で保存されます。
特定のイベントのみ監視したい
デフォルトは追加・更新・削除を監視しますが、設定によりイベントを絞り込むことができます。例えば削除のみ監視したい場合は以下のように設定します。
全体
'events' => [
- 'created',
- 'updated',
'deleted',
- 'restored',
],
特定の監視対象のみ
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;
class Item extends Model implements Auditable
{
use \OwenIt\Auditing\Auditable;
+ protected $auditEvents = [
+ 'deleted',
+ ];
監視ログの上限を設ける
デフォルトでは監視ログは延々と蓄積され続けます。上限を設けたい場合は以下のように設定するこで、上限を超えた古いデータが削除されていきます。
全体
- 'threshold' => 0, // 0だと上限なし
+ 'threshold' => 10,
特定の監視対象のみ
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;
class Item extends Model implements Auditable
{
use \OwenIt\Auditing\Auditable;
+ protected $auditThreshold = 10;