Laravelでエラー発生時にSlackやメールに通知する方法!初心者向け完全ガイド
生徒
「本番環境でエラーが起きたとき、ファイルを開いてログを確認するのが面倒です。エラーが起きた瞬間に通知を受け取る方法はありますか?」
先生
「ありますよ。LaravelのログチャンネルにSlackやメールを設定しておくと、重大なエラーが発生した瞬間に自動で通知が届くようになります。」
生徒
「それは便利ですね。難しい設定が必要ですか?」
先生
「基本的な設定はとてもシンプルです。順番に説明しますね!」
1. エラー通知の仕組みと必要性を理解しよう
Webサービスを公開していると、利用者がいる間もバックグラウンド(画面の裏側)でプログラムが動き続けています。そのため、自分がパソコンの前にいない夜中や休日にエラーが起きることもあります。
ログファイルは記録を残してくれますが、自分で定期的に確認しなければエラーの発生に気づけません。これを解決するのがエラー通知の仕組みです。エラーが起きた瞬間にSlack(チャットツール)やメールに自動でメッセージが届くようにしておけば、素早く対応できます。
Laravelではログチャンネル(ログをどこへ送るかの設定)を使ってこの通知機能を実現します。チャンネルとは、ログの送り先や形式を定義した設定のまとまりのことです。ファイルに書き込むチャンネルのほかに、Slackやメールに送るチャンネルも用意されています。
2. SlackへのエラーログにはWebhook URLが必要
LaravelからSlackにエラーを通知するためには、Slackが発行するWebhook URLというものが必要です。WebhookとはWebサービス同士が特定の出来事をきっかけに自動でデータをやり取りする仕組みのことです。
Slack Webhook URLの取得手順はSlack公式サイトから「Incoming Webhooks」アプリを設定することで入手できます。取得したURLは以下のように.envファイルに保存します。
// .envファイルに追加する設定
LOG_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXXXX/YYYYY/ZZZZZ
LOG_SLACK_USERNAME=LaravelErrorBot
LOG_SLACK_EMOJI=:fire:
.envファイルとは、データベースのパスワードや外部サービスのURLなど、環境ごとに変わる設定値をまとめた特別なファイルです。このファイルに書いた値はenv('キー名')という形でプログラムから読み込めます。URLは他人に知られないよう、.envファイルをGitなどのバージョン管理ツールに含めないよう注意しましょう。
3. config/logging.phpにSlackチャンネルを設定する
Webhook URLを用意したら、config/logging.phpにSlack用の設定を追加します。このファイルはLaravelのログ全体を管理する設定ファイルです。
<?php
// config/logging.phpの設定例
return [
'default' => env('LOG_CHANNEL', 'stack'),
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily', 'slack'], // ファイルとSlack両方に送る
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => env('LOG_SLACK_USERNAME', 'LaravelBot'),
'emoji' => env('LOG_SLACK_EMOJI', ':boom:'),
'level' => 'critical', // criticalより重大なものだけSlackに通知
],
],
];
stackチャンネルは複数のチャンネルをまとめて使うためのものです。'channels' => ['daily', 'slack']と書くことで、ログが書き込まれるたびにdaily(ファイル)とslack(Slack通知)の両方に送られます。Slackチャンネルの'level' => 'critical'は「critical以上の重大なエラーだけSlackに通知する」という意味です。debugなどの細かい情報まで通知すると大量のメッセージが届いてしまうため、レベルを絞ることが重要です。
4. メールでエラー通知を受け取る設定方法
Slackを使っていない場合や、メールでもエラーを受け取りたい場合はMonologのNativeMailerHandlerを使う方法があります。ただしLaravelの標準ログチャンネルには直接「mail」チャンネルは用意されていないため、カスタムチャンネルとして自分で定義します。
まずconfig/logging.phpにカスタムチャンネルを追加します。
<?php
use Monolog\Handler\NativeMailerHandler;
use Monolog\Logger;
// config/logging.phpのchannelsに追加する
'error_mail' => [
'driver' => 'monolog',
'level' => 'error',
'handler' => NativeMailerHandler::class,
'with' => [
'to' => env('LOG_MAIL_TO', 'admin@example.com'),
'subject' => 'Laravelエラー通知',
'from' => env('LOG_MAIL_FROM', 'noreply@example.com'),
'level' => Logger::ERROR,
],
],
NativeMailerHandlerはMonologが提供するメール送信用のハンドラーです。ハンドラーとは、ログをどこに・どう送るかを処理する担当者のようなものです。'to'には通知を受け取るメールアドレス、'from'には送信元のアドレスを指定します。これらも.envファイルで管理することで環境ごとに切り替えが可能です。
5. Handler.phpのreportable()でカスタム通知を送る方法
ログチャンネルでの設定以外に、app/Exceptions/Handler.phpのreportable()メソッドを使って特定の例外が起きたときだけ通知を送る方法もあります。reportable()とは、例外が発生したときに実行する報告処理を登録するメソッドです。
たとえば独自に作った決済エラーの例外が起きたときだけ、Laravelのメール送信機能(Mail)を使って通知する例は以下のとおりです。
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Facades\Mail;
use App\Exceptions\PaymentException;
class Handler extends ExceptionHandler
{
public function register(): void
{
$this->reportable(function (PaymentException $e) {
// 決済エラーが起きたときだけメールで通知する
Mail::raw(
'決済エラーが発生しました。詳細: ' . $e->getMessage(),
function ($message) {
$message->to('admin@example.com')
->subject('緊急: 決済エラー通知');
}
);
});
}
}
Mail::raw()はテキスト形式のメールをその場で送る方法です。$e->getMessage()は例外に設定されたエラーメッセージを取り出すメソッドです。このようにすることで「この種類のエラーだけ特別に通知する」という細かい制御ができます。
6. Slackへの通知をテストする方法
設定が正しくできているかどうかは、実際にエラーを発生させて確認する方法が確実です。しかし本番環境でわざとエラーを起こすのは危険なため、TinkerというLaravelの対話型ツールを使ってテストするのがおすすめです。
Tinkerとはターミナル上でLaravelのコードをそのまま実行できる開発ツールです。以下のようにしてSlackへの通知が届くかテストできます。
// ターミナルでTinkerを起動する
php artisan tinker
// Tinker内で実行するコード(criticalレベルでログを書き込んでSlack通知をテスト)
Log::channel('slack')->critical('テスト通知: Slackへの通知設定が正しく動いています。');
このコマンドを実行して設定したSlackのチャンネルに「テスト通知」のメッセージが届けば、設定が正しく完了していることが確認できます。Log::channel('slack')は特定のチャンネルを指定してログを送るための書き方です。通常のLog::critical()はデフォルトチャンネルに送りますが、channel()を使うことで送り先を明示的に指定できます。
7. 通知が多すぎる場合のレート制限と注意点
エラー通知を設定するときに注意したいのが、通知が大量に届いてしまう問題です。たとえば繰り返し同じエラーが発生する状況では、1分間に何十件もSlackに通知が届くことがあります。これを通知の嵐(アラートストーム)と呼び、かえって重要な情報を見逃す原因になります。
この問題を防ぐためにapp/Exceptions/Handler.phpのthrottleUsing()メソッドや、ログレベルの設定を工夫することが大切です。Slackチャンネルのレベルをcriticalまたはalertに絞っておくことで、本当に深刻なエラーのときだけ通知が届くようになります。
また、通知メールが迷惑メールフォルダに振り分けられないようにするための設定も重要です。Laravelのメール送信にはSendGridやMailgunなどのメール配信サービスを使うのがおすすめです。これらは信頼性の高いサーバーからメールを送ってくれるため、到達率が高くなります。.envファイルのMAIL_MAILERなどの設定を適切に行ったうえで通知メールを運用しましょう。