ソフトウェアを開発する上でしっかりと対応しておきたいのがログの出力ですよね。私は以前、運用しているWebアプリケーションのログ出力が不十分だったため、問題が起きたときに原因の調査ができなかったという経験があります。そのときから、ログの出力について気をつけるようにしています。
この記事ではログの出力を設計する指針について、書き方やフォーマットの例をもとに整理します。ログを設計するときの参考になればうれしいです。
まず、ログとはアプリケーションやサーバ、ソフトウェアなどが出力する、時系列に記録されたデータのことをいいます。アプリケーションが出力するログやデバッグログ、Webサーバのアクセスログやエラーログなどですね。
ログの種類によって、出力の設計指針は変わってくると思います。この記事では、いろんなログに共通する汎用的な内容として、アプリケーションログの出力を例に設計指針について書いていきます。
ログ出力の設計指針は、開発するソフトウェアによっても変わってきます。大切なことは、チームで指針をもってログ出力を行い、しっかりと運用していくことだと思います。
これからログ出力の設計指針について書いていくのですが、そもそもなぜログを出力する必要があるのでしょうか。これは、大きく次の4つがあると思っています。
ひとつずつ見ていきます。
Webアプリケーションを運用していると、サーバがダウンしてしまったり、レスポンスが遅くなったりすることがあります。こういった問題が発生したときに、発生した時間のログを見ることで、原因が分かったりします。
また、ユーザに問題が起きたときにも役立ちます。ユーザから問い合わせがあったときに、ユーザのアカウント情報と突き合わせて調べることで、ユーザに起きた問題の原因が分かることがあります。
問題が起きていなくても、問題が起きる予兆があったりします。たとえば同一のIPアドレスから連続してアクセスを受けることがあります。このときにIPアドレスに対する制限を行うなどすることで、問題の発生を防げることがあります。
ログは、ソフトウェアを改善するためにも役立ちます。ユーザの行動を分析して学習し、機能や施策につなげることでユーザ体験を向上することができます。
たとえばPCI DSSというセキュリティ基準では、監査ログを最低3ヶ月間は保管しなければならないとしています。ソフトウェアによっては、こうした基準を満たすためにログを出力する必要があったりします。
それでは、具体的にどうログ出力を設計すればよいのでしょうか。まず前提として、ログには読み手がいるということを意識します。どういうケースで、どういう読み方を想定しながらログ出力を設計することが大切といえます。
ログ出力は、5W1Hにもとづいて設計するとよいといわれています。たとえば、次のような項目をログに出力するようにします。
項目 | 内容 | 備考 |
---|---|---|
時間 | ログを記録した時間 | 年月日時分秒ミリ秒 |
ID | イベントのID | 一連のイベントを関連づけるために必要 |
ログレベル | ログのレベル | INFOやWARNなど |
ユーザ情報 | リクエストしたユーザの情報 | ユーザIDやIPアドレスなど |
リクエスト対象 | どこにリクエストしたか | URLなど |
処理内容 | どんな処理を行なったか | 参照や更新、削除など |
処理対象 | なにを処理したか | リソースのIDなど |
処理結果 | 処理した結果どうなったか | 成功または失敗、処理件数など |
メッセージ | その他出力したいこと | - |
ログ出力のメッセージは、できるだけシンプルに書くことで読み手に伝わりやすくなります。また、エラーが発生したときはスタックトレースを出力することで調査しやすくなります。
上で書いた項目の中にログレベルというものがあります。これはINFOやWARNなど、そのログのレベルを表します。
ログ出力にはログレベルを書くケースがほとんどだと思います。ログレベルは、読み手がほしい情報を適切に伝えるために役立ちます。ログレベルには、次のような種類があります。
レベル | 概要 | 説明 |
---|---|---|
FATAL | 致命的なエラー | アプリケーション全体が提供できない |
ERROR | エラー | ユーザのリクエストが処理できない |
WARN | 警告 | アプリケーションは提供できるが対応が望まれる |
INFO | 情報 | 記録しておくべき情報 |
DEBUG | デバッグ情報 | 動作に関する情報 |
TRACE | トレース情報 | 動作に関する詳細な情報 |
たとえば、状況を確認するのに必要な情報をDEBUGレベルにしてしまうと、INFO以上を表示するときに表示されなくなってしまいます。INFOを見るときはどういう状況か、DEBUGを見るときはどういう状況かなど、読み手を想定して適切にログレベルを設定すべきだといえますね。
ログ出力のフォーマットについては上で書きましたが、具体的にどのようなイベントを記録すればよいのでしょうか。たとえば、次のようなイベントについてログに出力します。
上で記録すべき情報について書きましたが、逆に記録すべきでない情報もあります。主にセキュリティの観点になるのですが、たとえば次のような情報は記録すべきでありません。あるいはマスク処理を行う必要があります。
ログは問題が発生したときの調査や問題の予防などに役立ちますが、一方でサーバに負荷がかかる行為でもあります。ログを出力することでサーバにパフォーマンス上の問題が起きたときは、出力の設計指針を見直す必要がありそうです。
アプリケーションのログを出力することで、問題が起きたときの調査に役立ったり、問題の予防につなげることができます。
ログ出力を設計するときは、読み手がほしい情報を想定して、適切な情報をふくめるとよいですね。ログ出力はサーバのパフォーマンスに影響するので、サーバの監視もあわせて行うべきといえます。
Webエンジニア&プロダクトマネージャ。 プログラミングで『ひとりで働く』を模索中。 三重の山の中で妻とこども、ネコとのんびり暮らしています。
Follow @zenizhWebエンジニア&プロダクトマネージャ。 プログラミングで『ひとりで働く』を模索中。 三重の山の中で妻とこども、ネコとのんびり暮らしています。
Follow @zenizh共著で『現場で使えるRuby on Rails 5(マイナビ出版)』を書きました。
Amazonでみる