アプリケーションのログ記録のためのベストプラクティスを記述する
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2023年03月08日(水)
Table of Contents
ログは、問題のトラブルシューティング、ビジネスインテリジェンス、コンプライアンスの遵守のための重要なデータソースです。ログによって、アプリケーションがいつ何を行ったかが正確に記録されます。
ログの作成は、アプリのコードのどこからでも単純な出力文を使用して実行できます。Heroku では、プラットフォームの他のコンポーネントからのログを集約することもできます。他のソースから集約したログについて、およびログ記録のしくみについては、ログ記録を参照してください。この記事では、アプリケーションコードによって生成されるログを記述するためのベストプラクティスに焦点を当てます。
Premier または Signature Success Plan の Heroku Enterprise の顧客は、Customer Solutions Architecture (CSA) チームに、このトピックに関する詳細なガイダンスを要求できます。ここでエキスパートコーチングセッションについて学習するか、または Salesforce の担当者にお問い合わせください。
ログに記録するイベントを定義する
アプリがどのように動作するかを物語るイベントをログに記録します。常に次のものをログに記録します。
- アプリケーションエラー
- 入力および出力の検証の失敗
- 認証の成功と失敗
- 承認の失敗
- セッション管理の失敗
- 特権の昇格の成功と失敗
- その他のリスクの高いイベント (データのインポートやエクスポートなど)
- ログ記録の初期化
- オプトイン (サービス利用規約など)
次のユースケースに対処するその他のイベントのログ記録を検討してください
- トラブルシューティング
- 監視とパフォーマンスの向上
- テスト
- ユーザー行動の理解
- セキュリティと監査
たとえば監査目的で、ユーザーがアプリ内でプロファイルを更新するたびにイベントをログに記録します。
関連する詳細を含める
Heroku のログ記録インフラストラクチャでは、いつどこで発生したかが記録されます。ログ出力には、タイムスタンプと、ログメッセージが発生した dyno が自動的に追加されます。
timestamp source[dyno]: message
メッセージ内容に次のようなコンテキストを追加します
- 実行されたアクション
- アクションを実行したユーザー
- 失敗の発生理由
- 警告とエラーメッセージについては、可能な場合は修正に関する情報
- HTTP リクエスト ID - 詳細は、「HTTP リクエスト ID」を参照してください。
Open Web Application Security Project (OWASP) には、さらに多くの推奨されるイベント属性の一覧があります。意味のあるコンテキストを必要十分に提供する属性を選択してください。
コンテキストが不十分な例を以下に示します。
2019-06-20T17:21:00.002899+00:00 app[web.1]: INFO: Address removed.
このメッセージはイベントの時刻と場所 (web.1
dyno) を示していますが、発生した内容の大まかな説明しか示されていません。
必要十分なコンテキストは、以下のとおりです。
2019-06-20T17:21:00.002899+00:00 app[web.1]: INFO: Address removed by customer. {"addressid":18344857, "customerid":50333}
このメッセージには、どの顧客がどのレコードを削除したかが記載されています。
個々のメッセージサイズを制限しているログとアドオンプロバイダーもあります。サイズの制限については、ログとアドオンプロバイダーのドキュメントを確認してください。
機密情報を除外する
セキュリティとコンプライアンスの要件を常に念頭に置いてください。
- 機密情報である個人を特定できる情報 (PII) を出力しないでください。
- 暗号化鍵またはシークレットをログに出力しないでください。
- 企業の個人情報保護方針で、ログデータについて扱われていることを確認します。
- ログとアドオンプロバイダーが、コンプライアンスのニーズを満たしていることを確認します。
- データの所在要件を満たしていることを確認します。
Shield Private Space で Private Space Logging を使用する場合を除き、すべてのログデータは、米国リージョンにある Heroku のログ記録インフラストラクチャを通過します。詳細は、「Private Space Logging」および「Logplex」を参照してください。
構造化ロギングの使用
人間に解読可能なログは役立ちますが、構造化ログには付加価値があります。これは特に、アプリケーションのログがますます複雑になったり、リクエストのスループットが増加したりしているためです。構造化ロギングでは明確に定義された形式のログエントリが提供されるため、これらを分析するために解析し、クエリを実行し、処理することが容易になります。
Heroku プラットフォームからのログエントリの構造は、logfmt
と呼ばれ、それぞれの行は密に詰め込まれた単一レベルのキー/値のペアで構成されます。この形式は人間に解読可能で、必要な場合は解析がかなり容易です。
構造化ロギングの事実上の業界標準は JSON ですが、キーと値のペアや XML などの形式をアプリケーションログに使用することを検討してください。アドオンプロバイダーが自動的に解析できるサポートされる形式を確認します。
次の非構造化ログエントリについて検討します。
2019-06-20T17:21:00.002899+00:00 app[email-wrkr.1]: DEBUG: Fetching mailing list 14777
2019-06-20T17:22:00.000098+00:00 app[email-wrkr.1]: DEBUG: User 3654 opted out
構造化 JSON を使用するようにこれらのエントリを変更すると、次のようになります。
2019-06-20T17:21:00.002899+00:00 app[email-wrkr.1]: DEBUG: Fetching mailing list {"listid":14777}
2019-06-20T17:22:00.000098+00:00 app[email-wrkr.1]: DEBUG: User opted out {"userid":3654}
これらのログメッセージの一貫性のある形式によって、選択されたログドレインでこれらを解析し、JSON メタデータを抽出し、検索とフィルター処理のために利用できるようにすることが簡単になります。
正しいレベルのログ
正しいレベルでイベントを記録します。
ログレベル:
INFO
- 障害やエラーを表示しない情報メッセージ。WARN
- 潜在的な問題があるが、ユーザーエクスペリエンスに影響しないことを示します。ERROR
- ユーザーエクスペリエンスにいくらか影響する重大な問題であることを示します。FATAL
- ユーザーエクスペリエンスに大きく影響する致命的なエラーであることを示します。DEBUG
- デバッグに使用されます。メッセージは特にアプリの開発者を対象としています。
たとえば、ERROR
を INFO
としてログ記録すると、トラブルシューティングの妨げになります。また、ある例外の動作が予測され、それが動作の低下を示すものでない場合は、その例外を ERROR
ではなく INFO
としてログ記録することを検討してください。ログレベルについての詳細は、「Art of Logging」(ログ記録の方法) を参照してください。
正しいレベルでログ記録するには、つぎのようにします。
- ログ記録のフレームワーク設定を確認します (特にログレベルを設定していない場合)。
- 例外をドキュメントに記録して確認し、INFO
または ERROR
のどちらでログに記録するかを決定します
- 他のログメッセージを検査し、それらが期待するレベルで記録されているか確認します。
- 開発環境と本番環境で別々のログレベルを設定することを検討します。
追加情報
Open Web Application Security Project (OWASP) では、ログのすべての側面に関するガイダンスを含む優れたログ記録の早見表が提供されています。
Heroku のログ記録インフラストラクチャでは、ログの保持が制限されています。詳細は、「ログ記録」の記事を参照し、ログを保持するためにログ記録アドオンまたはカスタムのログドレインをプロビジョニングしてください。