ログ設定は初期化コードではなく、運用契約として設計する
ログ設定は、最初はただの初期化コードに見える。
logger.info("started")
それでよいと思う。最初から完璧なログ設計を作ろうとすると、たぶんアプリ本体が進まない。
問題は、その小さな初期化コードが、あとから「どこへ出すのか」「どう残すのか」「何を失敗として扱うのか」という運用契約になっていくことだ。
ここでは、ログ設定を便利な初期化処理ではなく、あとから運用要求を受け止める境界として考える。
呼び出し箇所は広がる
ログの呼び出しは、アプリケーションのあちこちに散っていく。
logger.info("job started")
logger.warning("retrying")
logger.exception("failed")
一度広がった呼び出し箇所を後から総入れ替えするのはつらい。
だから、ログ運用を強くしたいときに最初に考えるのは、呼び出し箇所を変えることではない。ここでいう呼び出し箇所は、アプリケーションコード中にある logger.info(...) や logger.warning(...) の場所を指している。
起動時の方針として、出力形式、出力先の切り替え、ハッシュ、伏せ字化、環境変数による上書きを足せないかを考える。
設定は便利機能ではなく契約になる
開発中のログ設定は、ちょっとした便利機能に見える。
でも本番に近づくと、設定は契約になる。
- どこへ出すのか
- どの形式で出すのか
- いつファイルを切り替えるのか
- 何を伏せるのか
- どの環境変数で変えられるのか
- どんな設定ミスは起動時に落とすのか
ここを曖昧にすると、障害時に「ログがあるはずなのにない」「設定したつもりだった」が起きる。
早めに止まる方が親切なことがある
ログ設定は、多少間違っていてもアプリ本体が動いてしまうことがある。
でも、それは優しさではない。
ログは障害時に見に行くものだ。障害時に初めて設定ミスが分かるくらいなら、起動時に落ちてほしい。
D-SafeLogger では、効果を持てない設定の組み合わせを、起動時に止める方向へ寄せている。
たとえば、構造化出力と独自フォーマッタの衝突、出力先の切り替えなしで保存期間の制御を期待する設定、ハッシュやアーカイブと出力先の切り替えの矛盾などだ。
柔軟さより、間違った期待で進まないことを優先した。
3 レイヤーで考える
自分はログ設定を 3 つの層で考えるのがしっくり来ている。
| レイヤー | 役割 |
|---|---|
| コード | アプリケーションの既定値 |
| 設定ファイル / dict | 配置先ごとの差分 |
| 環境変数 | 一時的な運用上書き |
D-SafeLogger もこの方向で作っている。
3 行で始められて、既存のログ呼び出しを壊しにくく、設定で運用要求を後から足せて、環境変数で運用時の上書きもできる。自分にとって D-SafeLogger はそういう位置づけだ。
from dsafelogger import ConfigureLogger, GetLogger
ConfigureLogger(
log_path="./logs",
pg_name="MyApp",
routing_mode="daily",
structured=True,
)
logger = GetLogger(__name__)
logger.info("Application started")
呼び出し箇所は小さく保ち、運用上の契約は設定側で育てる。
何でも外から変えればよいわけではない
環境変数による上書きは便利だ。
ただし、何でも外から変えられるようにすると危ない。
診断モードのように情報量が増える機能は、明示的に有効化する前提にした方がよい。由来不明の設定ファイルで勝手に有効化されるべきではない。
運用時に変えたいものと、変えられては困る境界を分ける。ここもログ設計の一部だと思っている。
ケーススタディとして見ると、主役は境界になる
D-SafeLogger は、この考え方を実装した一例にすぎない。
大事なのは、特定のライブラリを使うことではなく、ログ設定を「あとから育つ運用契約」として扱うことだ。
最初は logger.info("started") でよい。
でも、その呼び出しを将来の運用要求に耐えられる形で残すには、呼び出し箇所と実行時の方針の境界を早めに意識した方がいい。
関連記事
Zenn 連載:
- #1 ログファイルの切り替えは、rename ではなく「次の書き先の選択」として設計する
- #2 ログ設定は初期化コードではなく、運用契約として設計する(本記事)
- #3 ログ欠落は、防ぐものではなく「説明できるもの」として設計する
- #4 「ログは stdout に出しておけば OK」で済まない場合の話
Qiita の関連回:
Discussion