Laravelで監査ログを実装する

f:id:kazuhei0108:20210418191338j:plain
ログハウス

こんにちは、かずへいです。

M&Aクラウドサービスで管理画面に監査ログの記録機能を追加しましたので、その実装方法について紹介致します。

監査ログとは

f:id:kazuhei0108:20210418191637j:plain
実際の監査ログ画面

監査ログは監査証跡として、システム監査人が追跡するために、操作内容やそれに伴うデータの移り変わりが時系列に沿って記録されているログのことです。

システム監査人とは、システムが正しく動いているか、問題が合っても追跡できるか等を確認する人で、公民情報システム監査人という資格もあるようです。

cisa.jp.net

Laravel Auditingの活用

Laravelでの監査ログの記録にはLaravel Auditingというライブラリが便利です。Githubのスター数も2,000件を超えており、実質的にデファクトみたいになっているようです。

github.com

ドキュメントもしっかりしています。

www.laravel-auditing.com

Laravel Auditingの導入

以下でLaravel Auditingをインストール出来ます。

composer require owen-it/laravel-auditing

その上で、設定ファイルをライブラリ側からコピーして自分のプロジェクトに持ってきます。

php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="config"
php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="migrations"

必要に応じて設定は変更してください。

あとはOwenIt\Auditing\Auditable.phpというトレイトが用意されているので、監査ログを入れたいEloquentを継承しているモデルに use Auditable すれば終わりです。簡単ですね。

Eloquentを使っていない部分の対応

弊社のシステムではEloquentを使わずにQuery Builderを使っている箇所もあり、そちらはTraitをuseするだけで実装することが出来ませんでした。

Laravel AuditableにはAuditorという監査ログを記録するクラスがあり、それを直接呼び出す事もできるので、クエリビルダーを継承し、insertやupdateが呼び出される度に一緒にAuditorも呼ばれるように実装を変更しました。

<?php
declare(strict_types=1);

use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Query\Grammars\Grammar;
use Illuminate\Database\Query\Processors\Processor;
use OwenIt\Auditing\Contracts\Auditor;

class QueryBuilderWithAudit extends Builder
{
    /**
     * @var Auditor
     */
    private Auditor $auditor;

    public function __construct(Auditor $auditor, ConnectionInterface $connection, Grammar $grammar = null, Processor $processor = null)
    {
        parent::__construct($connection, $grammar, $processor);
        $this->auditor = $auditor;
    }

    public function newQuery(): self
    {
        return new static($this->auditor, $this->connection, $this->grammar, $this->processor);
    }

    public function insert(array $values)
    {
        $result =  parent::insert($values);
        $this->auditor->execute(new CreatedAudible(null, $this->from, $values));

        return $result;
    }

    public function insertGetId(array $values, $sequence = null)
    {
        $result = parent::insertGetId($values, $sequence);
        $this->auditor->execute(new CreatedAudible($result, $this->from, $values));

        return $result;
    }

    …省略…

このQuery Builderを継承したクラスを使いさえすれば、後の実装はいつものとおりにするだけで、監査ログが記録されるようになります。

まとめ

LaravelではLaravel Auditingを活用することで簡単に監査ログを導入することが出来ます。 これによりシステムが正常に動いているか、問題が起きたときに、システム上で誰が何を変更していたのか等を追跡できるようになりました。

Laravel Auditingはドキュメントもしっかりしていて、簡単に導入できるのでぜひ使ってみて下さい。

おわりに

M&Aクラウドではデザイナーやエンジニアを募集中です! 少しでも興味を持っていただけましたら、是非お気軽にご連絡ください。

www.wantedly.com

www.wantedly.com

www.wantedly.com