🎻

[PHP] MonologのログをMailgunでメール送信する

2020/04/16に公開

PHPのロガーのデファクトスタンダードである Monolog は、ハンドラーという部品を交換することで様々な方法でログを送信できます。

Monologの仕組みについては こちらの記事 が参考になります。

拙作のMonologハンドラー ttskch/monolog-mailgun を使えば、Mailgun を使って簡単にログをメールで送信できるので、ご紹介します。

ttskch/monolog-mailgun

使い方は以下のとおりです。

$ composer require ttskch/monolog-mailgun

でインストールして、

$mg = \Mailgun\Mailgun::create('api_key');
$domain = 'mg.example.com';
$from = 'Alice <alice@example.com>';
$to = ['bob@foo.bar.com'];
$subject = '[Monolog] Error Report';
$handler = new \Ttskch\Monolog\Handler\MailgunHandler($mg, $domain, $from, $to, $subject);
$logger = new \Monolog\Logger('mailgun');
$logger->pushHandler($handler);
$logger->critical('Critical Error!');

という感じで使います。簡単でしょ?

Symfonyから使う

symfony/monolog-bundle がインストールされているSymfony4/Symfony5にも簡単に導入できます。

単体で使う場合と同じく

$ composer require ttskch/monolog-mailgun

でインストールすると、依存している mailgun/mailgun-phpレシピ により、以下の config/packages/mailgun.yaml が自動生成されます。

# config/packages/mailgun.yaml
services:
    Mailgun\Mailgun:
        class: Mailgun\Mailgun
        factory: ['Mailgun\Mailgun', create]
        arguments: ['%env(MAILGUN_API_KEY)%']

これに加えて、 config/packages/prod/monolog.yaml を以下のような感じで設定すればOKです。

# config/packages/prod/monolog.yaml
monolog:
    handlers:

        # ...

        email:
            type: fingers_crossed
            action_level: critical
            level: debug
            channels: ["!event"]
            handler: deduplicated
        deduplicated:
            type: deduplication # prevent multiply sending
            handler: mailgun
        mailgun:
            type: service
            id: Ttskch\Monolog\Handler\MailgunHandler

services:
    Ttskch\Monolog\Handler\MailgunHandler:
        arguments:
            - '@Mailgun\Mailgun'
            - mg.example.com # mailgun domain
            - Alice <alice@example.com> # from
            - [bob@foo.bar.com] # to
            - '[Monolog] Error Report' # subject

設定内容の意味

email:
    type: fingers_crossed
    action_level: critical
    level: debug
    channels: ["!event"]
    handler: deduplicated
  • fingers_crossed ハンドラーを使ってハンドラーをラップする
  • critical 以上のログが出力されたときに動作
  • そのとき、実際に出力するのは debug 以上のログ
  • ただし event チャンネルのログは出力しない
  • ラップする対象のハンドラーは deduplicated ハンドラー
deduplicated:
    type: deduplication # prevent multiply sending
    handler: mailgun
mailgun:
    type: service
    id: Ttskch\Monolog\Handler\MailgunHandler
  • deduplication ハンドラーでラップすることで、しばらくの間(デフォルトでは60秒間)同じ内容のログを出力しないように(メールが大量に来ると困るので)
  • ラップする対象のハンドラーは mailgun ハンドラー
  • mailgun ハンドラーを service ハンドラーとして定義
  • 対象のサービスIDは Ttskch\Monolog\Handler\MailgunHandler
services:
    Ttskch\Monolog\Handler\MailgunHandler:
        arguments:
            - '@Mailgun\Mailgun'
            - mg.example.com # mailgun domain
            - Alice <alice@example.com> # from
            - [bob@foo.bar.com] # to
            - '[Monolog] Error Report' # subject
  • Ttskch\Monolog\Handler\MailgunHandler サービスを定義
  • 注入する引数は
    • Mailgun\Mailgun サービス
    • 使用するMailgunのドメイン名
    • メールのFrom
    • メールの送信先(配列)
    • メールのタイトル

SwiftMailerをMailgunで設定済みの場合はこっち

すでにSwiftMailerがセットアップされているSymfonyプロジェクトなら、ttskch/monolog-mailgunを入れるまでもなく以下のような設定を追加するだけでログをメールで受け取れます✋

# config/packages/prod/monolog.yaml
monolog:
    handlers:

        # ...
        
        email:
            type: fingers_crossed
            action_level: critical
            level: debug
            channels: ["!event"]
            handler: deduplicated
        deduplicated:
            type: deduplication # prevent multiply sending
            handler: swift
        swift:
            type: swift_mailer
            from_email: alice@example.com
            to_email: bob@foo.bar.com
            subject: '[Monolog] Error Report: %%message%%'
            formatter: monolog.formatter.html
            content_type: text/html

参考:https://symfony.com/doc/current/logging/monolog_email.html

まとめ

  • Monologハンドラー ttskch/monolog-mailgun を使えば、簡単にMonologのログをMailgunで送信できる
  • Symfony4/Symfony5にも簡単に導入できる
  • Symfonyの場合、SwiftMailerが設定済みなら MonologBundleの設定を書き足すだけでOK
  • プロダクションコードにメール送信機能はないけどエラーログだけはMailgunを使ってメールで送りたい、みたいなときにttskch/monolog-mailgunでサクッと導入してみてください
GitHubで編集を提案

Discussion