後輩よりログの出力と監視の正解がわからないという話を受けたので、私なりの考え方をまとめてみます。
ここは、個人、プロジェクトの趣向もあると思いますが、、、、経験上多かったもの、良かったパターンを記載してみることとします。
ログ出力
パフォーマンスに影響する部分だと思っており、極力出力したくない。
下記の観点から、出力対象を限定する
1.エラー発生時の原因調査ができること
2.ユーザ問い合わせ時にトランザクションが追えること
3.性能的問題が発生した場合原因調査できること
1.エラー発生時の原因調査ができること
エラーと名のつくものすべて出します。(チェックエラー、業務エラー、検査例外、非検査例外)
Javaの話になりますが、例外に関しては基底クラスでcatchし、ログ出力の実装箇所を1つにまとめることが多いです。
もしくは、ErrorHandlerやAOPを実装し、例外発生を捉え一律規定のフォーマットでログ出力できるよう標準化を行えばよいかと思います。
チェックエラーや業務エラーはチェック処理自体が個別になりがちなので、基本個別出力にしています。
基底クラスで~~~のくだりはこんなイメージです。
ログ出力部分は基底クラスのみに実装し、各クラスは例外をthrowすればOKな作りとしてます。(適当なので文法ミスあればすみません、、、
public class BaseService {
abstract public void execute(); // 各クラスではBaseServiceを継承してexecuteを実装する
public void main() {
try {
execute();
} catch (Exception e) {
// 基底クラスの中でexecuteが投げた例外をcatchしハンドリングする。各クラスはexecuteから例外をthrowするだけでよい
logger.error(e);
}
}
}
2.ユーザ問い合わせ時にトランザクションが追えること
HTTPのInとOutを基本出すようにしています。
HTTPリクエストのクエリパラメータ、リクエストボディ、認証情報(例えばCookie)は出力することが多いです。
HTTPレスポンスはサイズが大きくなりがちなのであまり出力しません。HTTPステータスコードやレスポンスサイズ、レスポンスタイムはもちろん出します。
SQLのトレースログなども、あれば大助かりですが性能への影響が大きいので私はOFFします。
3. 性能的問題が発生した場合原因調査できること
上記のログが整っていれば十分かと思います。
レスポンスタイムから遅いものを特定 → クエリパラメータ、リクエストボディからリクエストの再現。と手順を踏めばローカルや開発環境で原因調査ができるかと思います。
その他
アクセスログ系とエラーログ系で出力するファイルは別にしています。
また、ログレベルはもちろん出すのですが、それとは別にメッセージコードを採番することが多いです。
口述する監視に関わってきます(例えばFATALを一律エラーとして検知してしまうと運用が面倒になったり、、、)
最近だとSPAの構成も多いですが、Javascriptのエラー(ブラウザのconsole)はログ出力できないため、
ErrorHandlerを実装し、Javascriptで例外発生 → catch → ログ送信APIを呼んで例外内容を送り付ける → サーバサイドで受け取った内容をファイルに出力する。というやり方もやってます。
ログ出力まとめ
基本、機能 × 非機能で問題が発生した際に原因調査できるよう情報を整理すればよいかと思います。
私は今まで上記の考え方で困ったことはないですが、サービスの特性によって必要な情報は変わってくると思います。
(例えばBtoCサービスならもう少しセキュリティ関連のログを出したほうが良い。とか)
ログ監視
監視対象はエラーログ系のファイルのみです。
検知したい対象はユーザ業務が止まる可能性のあるエラーと、想定外のエラーとすることが多いです。
つまり、チェックエラーと業務エラー以外すべて。となります。
いろいろ考え方はあると思いますが監視定義はホワイトリスト方式が良いかと思います。
検知の除外対象としてチェックエラーと業務エラーをホワイトリストに追加し、それ以外の出力はすべて検知対象とみなします。
運用しているうちに、このエラーは検知しなくても問題ないな。とかそういった切り分けができてきます。
検知しなくて良いエラーはそのエラーメッセージコードをホワイトリストに追加し、エラーとして検知しないよう対応します。
なので、最初はエラーとして扱わなくて良いものもエラーとして検知してしまいますが、徐々に収束していくことになります。
私はFalsePositive的思考なので、エラーを誤検知して、結果問題なかったなら良いじゃん。って考えですね。
それよりもエラーの見逃しのほうが怖いので少し広めに検知しておきたい気持ちです。
まとめるとこんな感じです。
ログファイル | 中文類 | 小分類 | 監視有無 | 検知有無 |
---|---|---|---|---|
アクセスログ | × | × | ||
エラーログ | チェックエラー | 〇 | × | |
業務エラー | 〇 | × | ||
例外 | ホワイトリスト対象 | 〇 | × | |
その他 | 〇 | 〇 |
だいたい、こんな考えで普段運用設計を進めています。
違う考え方や、イマドキはこうだよ!というのがあればぜひ教えてください。