eccube4でアプリケーションエラーがあった際にメールを送信する


おおまかな手順はSymfonyの公式に記載。

今回はローカルからmailtrapに送信する形で試した。
追記分以外はデフォルトの状態

dev/public/app/config/eccube/packages/dev/monolog.yml
monolog:
    handlers:
        buffered:
            type:     buffer
            handler:  easylog
            channels: ["!event"]
            level:    debug
        easylog:
            type: service
            id:   easycorp.easylog.handler
        console:
            type: console
            process_psr_3_messages: false
            channels: ['!event', '!doctrine', '!console']
        #追記分
        app_error:
            type: fingers_crossed
            action_level: critical
            handler: deduplicated
        deduplicated:
            type: deduplication
            handler: swift
        swift:
            type:       swift_mailer
            from_email: [email protected]
            to_email:   [email protected]
            # to_email:   [' [email protected] ', ' [email protected] ', ...]
            # カンマ区切りで複数に指定できる
            subject:    'エラーを検知しました'
            #メールの件名
            level: error
            #本文に記載するどのレベルのErrorを記載するか
            formatter:  monolog.formatter.html
            content_type: text/html
            #htmlメールで送信する場合に必要

services:
    easycorp.easylog.handler:
        class: EasyCorp\EasyLog\EasyLogHandler
        public: false
        arguments:
            - '%kernel.logs_dir%/%kernel.environment%/site.log'

順番に解説していこう。

app_error:
    type: fingers_crossed
    action_level: critical
    handler: deduplicated

まずはfingers_crossedに実行するための条件を設定する。
action_level別に設定できる。
この場合はlog_levelがcriticalの時にhandlerで設定している処理を呼び出す。
つまりはdeduplicatedを呼び出す。

action_level別条件の詳細
critical error
5xx系のHTTPコードエラー 4xx・5xxレベルのHTTPコードエラー
deduplicated:
    type: deduplication
    handler: swift

公式をgoogle翻訳で直訳するとdeduplicationの役割は重複するメッセージを削除した後に次のhandlerに処理を渡すイメージかな?

今回はswiftにいく

deduplicatedハンドラーは、要求のすべてのメッセージを保持し、それらが特定の期間(デフォルトでは60秒)にわたって一意である場合にのみ、一度にネストされたハンドラーにそれらを渡します。 レコードが重複している場合、それらは破棄されます。 このハンドラーを追加すると、特に重大な障害シナリオでは、通知の量が管理可能なレベルに減少します。 timeオプションを使用して期間を調整できます。

timeオプションはよくわかってない。

swift:
    type:       swift_mailer
    from_email: [email protected]
    to_email:   [email protected]
    # to_email:   [' [email protected] ', ' [email protected] ', ...]
    # カンマ区切りで複数に指定できる
    subject:    '[%%level_name%%][%%datetime%%]エラーを検知しました'
    #メールの件名
    level: error
    #本文に記載するどのレベルのErrorを記載するか
    formatter:  monolog.formatter.html
    content_type: text/html
    #htmlメールで送信する場合に必要

subjectには以下のフォーマットを出力することが出来る。

フォーマット 出力する項目
%%datetime%% 日付
%%channel%% チャネル名
%%level_name%% レベル
%%message%% メッセージ内容
%%context%% コンテキスト情報
%%extra%% 追加情報

最後にメール処理に関する設定を記述すれば完成。
細かい部分は見せられないがこんな感じでメールが届く。

入れ子になってないからイメージしづらいが、fingers_crossedから順に処理をつなげていくイメージでいいかと思う。

slackに飛ばすことも可能なので有料会員であればslackに投げるのもあり。
(無料だとログが残らない)

概念的な理解は以下の記事が非常にわかりやすかった
PHPのロガーMonologを理解しよう
PHPのロギングmonologを理解する