nazolabo

フリーランスのWebエンジニアが近況や思ったことを発信しています。

ワンポイントTwelve-Factor App(11) : ログ

この記事は、The Twelve-Factor Appを補足し、実際に現代的なWebアプリケーションで適用する場合の注意点などを紹介するシリーズです。下記の原文を読んだ上でのワンポイント解説になります。

12factor.net

概要

  • ログは全て標準出力に出す
  • (通常は)1行を1イベントとする
  • 標準出力に出したログはログルーターが適切に取り扱う

これは何を表しているか

ほとんどのWebアプリケーションフレームワークは、ログはデフォルトではファイルに出力するようになっています。しかし、「9. 廃棄容易性」といった点から、ファイルに出力してしまった場合は廃棄された場合の取り扱いが困難になってしまいます。

標準出力を唯一のログ出力先にしておくことで、そのアプリケーションがどのように動いているかに関わらず、共通でログを取り扱うことができます。標準出力に出したログはfluentdなどのログルーター(ログコレクター)で扱うことで、アプリケーションとは別にログの取り扱い方を決めることができます。特にDockerでは標準出力に出したログをDockerロギングドライバ経由で柔軟に取り扱うことができます。

実際に運用する場合

Webに限らずアプリケーションでログの取り扱いは最重要です。特に運用段階に入ると、ログのわかりやすさで障害時の対応の速さが大きく変わります。

ログをファイルに出力してしまうと、環境によって取り扱い難易度が変わってしまいます。fluendで取るという理由で一時出力先をファイルにするという場合もなくはないですが、基本的には標準出力に出しておくことでどの環境でも共通で取り扱うことができます。特にDocker環境では標準出力に出しておかないとDocker側のロギングドライバで取り扱うことができないので、必ず標準出力に出すようにしましょう。

設定で標準出力にログを出す仕組みがないログシステムでも、 /dev/stdout に送ることで標準出力に出すことが可能です。

開発環境ではターミナルにログが出ていれば通常は十分だと思いますので、標準出力をそのままターミナルに流しておきましょう。

1行1イベントとなると、CSV/TSVのような形式だとそのログの各項目が何かを判定することができなくなってしまいます。ヘッダ情報を足すにはLTSVでもいいですが、階層構造などを考えるとJSON形式で出しておくことで様々なプラットフォームでの取り扱いが簡単になります。nginxなどのログも含め、基本的にはJSON形式で出力するのが良いでしょう。

本項とは直接関係ありませんが、セキュリティの観点からパスワードなどをログに出さないようにする・問い合わせから追跡しやすいようにユーザーIDやエラーのスタックトーレスをログに出しておく、などの細かい点を抑えておくと良いです。