2回めましてこんばんわ。 @kalibora です。 焼き鳥のカシラは塩、シロはタレ派です。
さてさて、みなさまはプログラム中でログを吐くときのログレベルをどのように使い分けておりますでしょうか。
error
一択?
error
info
debug
くらい?
そうだとして、それってどう使い分けていますか?
そしてそれをどのように気づき、どう対処していますか?
ログレベルの種類
まず、ログレベルはどのようなものが定義されているのか確認したいと思います。
PHP のデファクトスタンダートである PSR-3 で定義されているログレベルは下記の通りです。
ログレベル | 説明 | 例 |
---|---|---|
emergency |
System is unusable. システムが使用不可能な状態 |
- |
alert |
Action must be taken immediately. 直ちになんらかの対処の必要がある |
Entire website down, database unavailable, etc. This should trigger the SMS alerts and wake you up. 完全にWebsiteがダウンした、データベースが使用不可能など。SMSで通知して起きる必要がある |
critical |
Critical conditions. 危機的な状態 |
Application component unavailable, unexpected exception. アプリケーションコンポーネントが使用不可能、予期しない例外。 |
error |
Runtime errors that do not require immediate action but should typically be logged and monitored. 直ちに対処する必要のない実行時エラーだが、通常はログに記録して監視すべき |
- |
warning |
Exceptional occurrences that are not errors. エラーではない例外的な出来事 |
Use of deprecated APIs, poor use of an API, undesirable things that are not necessarily wrong. 廃止予定のAPI、中途半端なAPI、必ずしも間違っていないが望ましくないものの使用 |
notice |
Normal but significant events. 正常だが、重要な事象 |
- |
info |
Interesting events. 興味深い事象 |
User logs in, SQL logs. ユーザーのログインやSQLログ |
debug |
Detailed debug information. 詳細なデバッグ情報 |
- |
この定義をベースとして、サービスやシステム、チーム単位などで具体的にどう使うかや通知方法をあらかじめ決めておくと便利ですよね。
一例として
一例として弊社のあるサービスでは下記のように定義しています。
ログレベル | 定義 | 使用例 | 本番環境でのロギング | 通知方法 |
---|---|---|---|---|
emergency |
基本的に使わない | - | する | Slackのalertチャンネルに通知 |
alert |
1回発生したら必ずなにかしらの対応が必要なもの | ここには使用例が書いてある | する | Slackのalertチャンネルに通知 |
critical |
基本的には1回発生したら対応や調査が必要なもの | ここには使用例が書いてある | する | Slackのerrorチャンネルに通知 |
error |
システムが原因で正常に処理ができないが、頻発しなければ未対応でもいいもの | ここには使用例が書いてある | する | Slackのerrorチャンネルに通知 |
warning |
ユーザー起因で正常に処理ができなかったようなもの | ここには使用例が書いてある | する | 通知しない |
notice |
正常に処理しているが、記録しておきたい重要なもの | ここには使用例が書いてある | する | 通知しない |
info |
そこまで重要じゃないが記録しておきたいもの | ここには使用例が書いてある | 一部する | 通知しない |
debug |
開発のデバッグ時に必要な情報 | ここには使用例が書いてある | しない | 通知しない |
このように決めておけば、
ここでエラーが起きたら必ずデータのリカバリ作業が必要になるから alert
だな。
とか、
ここでのエラーは問題だけど一時的な原因の可能性もあるし、再実行可能だから error
だな。
とか、
正常なルートじゃないけど、システムには問題なくエンドユーザー起因だから warning
だな。
などと判断できると思います。
そしてちゃんとレベルが定義できていれば、レベルごとに通知方法もわけられるので、 即対応が必要なものもすぐに気づくことができますよね。
ここで重要なのは定義をして各人での意識を合わせておく。ということで、この定義が正解だと言っているわけではないです。念のため。
おまけ: monolog の processor の話
ほとんどの phper のみなさんはロギングに Monolog を使っているかと思いますが、その際に Processor は使ってますでしょうか?
あらかじめちょっと定義・設定しておくだけでログに各種の付加情報を記録できる便利なやつです。
デフォルトでは
- GitProcessor
- git のブランチ名
- IntrospectionProcessor
- ファイル名, 行番号, クラス名, メソッド名
- MemoryPeakUsageProcessor
- メモリの最大使用量
- MemoryUsageProcessor
- メモリ使用量
- ProcessIdProcessor
- プロセスID(これがないとどのログが1つのリクエストなのか分からず混ざっちゃって大変ですね)
- PsrLogMessageProcessor
- TagProcessor.php
- UidProcessor.php
- WebProcessor.php
- URL, IP, リファラーなど
が用意されています。
デフォルトで用意されていないもので必要になりそうなものとしては、ユーザーを特定するIDなどがあると思いますが、
そういったものも自前で Processor を定義することで簡単に付加できるので、Monolog を使っているのであれば是非使ってみるといいんじゃないでしょうか。
それではまた。