株式会社CINC 開発本部(旧:開発部) エンジニアブログ

開発部→開発本部!!ビッグデータ取得/分析・自然言語処理・人工知能(AI)を用いた開発を軸に、マーケティングソリューションの開発や、DX推進を行っている、株式会社CINCの開発本部です。

LaravelでModelを監視してアクションログを実装する

LaravelでModelを監視してアクションログを実装する こんにちは、株式会社CINC開発本部です。

今回は、Laravelでのデータベース操作を確実に追跡・監視するための実装テクニックをご紹介します。

はじめに

LaravelはPHPのWebアプリケーションフレームワークとして広く採用されており、弊社でも多くのプロジェクトで活用しています。

アプリケーションの運用において、データベースの変更履歴を追跡することは重要な要件の一つです。

例えばこんなユースケースがあります。

  • ユーザーデータの更新履歴
  • 重要な設定変更の記録
  • セキュリティ監査のためのログ
  • データの削除・アーカイブの追跡

本記事では、Laravelの機能を活用して、こういった操作時のログを効率的かつ確実に記録する方法を解説します。

具体的には、Eloquentモデルのイベントフックを使用して、データベースの変更を自動的に検知し記録する手法について、実装例とともに詳しく説明していきます。

なぜモデルを監視するのか

今回、なぜモデルを監視してアクションログを記録しようと考えたのか。その理由は以下のメリットにあります。

  1. アクションログの関数を都度記載する必要がない
  2. 処理の抜け漏れが防げる

1. アクションログの関数を都度記載する必要がない

アクションログの関数をミドルウェア層やコントローラに配置すると、処理パターンが増えるたびにアクションログの設定を追加する必要があります。

しかし、モデルを監視する形にすることで、処理を一箇所に集約でき、管理が容易になります。

2. 処理の抜け漏れが防げる

理由は上記の1と同じですが、処理を一箇所にまとめることで、アクションログの記録漏れを防ぐことができます。

コントローラごとにアクションログを追加する場合と異なり、全体的な管理がしやすくなります。

モデルの監視方法

では、具体的にどのように実装すれば良いのでしょうか。

LaravelのORMであるEloquentのドキュメントには、クロージャを使用してアクションログを登録する方法が記載されています。

公式ドキュメント

ドキュメントでは created イベントしか記載されていませんが、updateddeleted イベントも利用可能です。

これらのイベントにアクションログの生成処理を記載することで、モデルの作成、更新、削除時のログを自動的に記録できます。

以下に実装例を示します。

protected static function boot()
{
    parent::boot();

    // 新規作成時のイベント処理
    static::created(function ($user) {
        ActionLog::create([
            'user_id' => $user->id,
            'action' => 'created',
            'data' => json_encode($user->toArray())
        ]);
    });

    // 更新時のイベント処理
    static::updated(function ($user) {
        $before = $user->getOriginal();
        $after = $user->toArray();
        $changes = $user->getChanges();
        
        // パスワード変更の検知
        $passwordStatus = array_key_exists('password', $changes) 
            ? '変更あり' 
            : '変更なし';

        $updated_at = $user->updated_at;

        // タイムスタンプを除外
        unset(
            $before['updated_at'], 
            $after['updated_at'], 
            $before['created_at'], 
            $after['created_at']
        );

        ActionLog::create([
            'user_id' => $user->id,
            'action' => 'updated',
            'data' => json_encode([
                'before' => $before,
                'after' => $after,
                'password' => $passwordStatus,
                'updated_at' => $updated_at
            ])
        ]);
    });

    // 削除時のイベント処理
    static::deleting(function ($user) {
        \Log::info('Deleting user ID: ' . $user->id);
        
        // アーカイブデータの作成
        UserArchive::create([
            'user_id' => $user->id,
            'email' => $user->email,
            'password' => $user->password,
            'name' => $user->name,
            'role' => $user->role,
            'deleted_at' => now()
        ]);
        
        // 削除ログの記録
        ActionLog::create([
            'user_id' => $user->id,
            'action' => 'deleted',
            'data' => json_encode($user->toArray())
        ]);
    });
}

この実装では、アクションログのデータをJSON形式で保存しています。

この方式により、モデルの構造が変更された場合でも、ログ記録の仕組みへの影響を最小限に抑えることができます。

まとめ

モデル監視によるアクションログの実装は、このような利点があります。

  • コードの保守性向上
  • ログ記録の確実性確保
  • 柔軟なデータ構造の対応

この手法を活用することで、より堅牢なログ管理システムを構築できます。

以上、Laravelのテーブルに対するアクションログのテクニックをご紹介しました!