はまやんはまやんはまやん

hamayanhamayan's blog

ロギングベストプラクティスの個人的所感

LOGGING BEST PRACTICES: THE 13 YOU SHOULD KNOW

  • https://www.scalyr.com/blog/the-10-commandments-of-logging/
  • ロギングに関するプラクティス集
  • 原文はCC BY 4.0であるので、本記事もそれを継承しておく(CCってライセンスの継承義務ってあるんかな?)
  • 日本語訳はしっかりしたやつが2つもあるので、完璧な本文は書かない 1 2
  • 所感を以下に書いていく

所感

基礎的なことが網羅されてた。
ラクティス集の全項目に対しては完全肯定であり、自分の考えを追記していると明記しておく。

1. 自前でログを書くな

  • ライブラリを使え
  • printfは最悪
  • ローテーション機能とかのことも書いてあった。
  • 確かに、printfっぽいやつ使うにしてもラッパは必要。出力先も変わるかもしれないしね

2. ログレベルを入れる

  • TRACE, DEBUG, INFO, NOTICE, WARN, ERROR, FATALが紹介されてる
  • 主要なロガーでは採用されているので、なんとなく理解してるだろう

3. 適切なログカテゴリに入れよ

  • あまり馴染みがない概念だったが、Javaのロギングライブラリだと、com.daysofwonder.rankingのように階層化して定義できる?
  • カテゴリごとにconfigutrationが作れるっぽい
  • 確かにログを追っていく時にグループや包含関係などがあると読みやすくなる
  • jsのログはそんな感じにできたはず

4. 意味のあるログメッセージを書こう

  • そうは言ってもという感じがある
  • これを実現するには、改善するための情報(おそらく状況の改善)を入れたり、操作の目的を入れる
    • 確かにエラーメッセージには、状況とその対処が含まれてることが望ましい
  • 重要なこととして他のメッセージとつながっているように出力しないことが挙げられている
    • ログレベルの違いで同時に出ない、非同期処理だと順番が乱れる可能性があるので、見にくくなる
    • なるほど。確かに

5. 英語でログを書こう

  • 文字コードによらずASCIIは使えるため
  • あと、翻訳も必要ない
  • あと、略語が使えるってのもいいらしい

6. ログメッセージにコンテクストを含める

  • 日本人が良くわからない英単語No.1「コンテクスト」
  • 結果だけを書くなというtips
  • 「Transaction failed」だけじゃ何もわからない
  • 「Transaction 234532 failed: cc number checksum incorrect」とするとコンテクストが分かる
  • 確かにという感じ。Exceptionのスタックトレースを出力すればコンテクストは分かるが、そうじゃないやつは確かに気をつけなくては

7. 機械がパース可能なログを残す

  • ドラゴンクエストXを支える技術」で書かれていたロギングノウハウを思い出す
  • ログは障害修正だけでなく、様々な用途で使用される
  • で、常時出てるログは得てして莫大になる
  • 機械が扱えるようになっているのは当然だろう
  • 疑問だが、ExceptionをToStringそのままで出すとログカチャカチャになるけど、各所どういう対応してるんだろう

8. でも、人間も読みやすく

  • この辺は7との兼ね合いもあるかなとも思うのだが、readableであるというのはどういうことでも重要
  • ただIDを出力するより、ユーザー名を添える方が分かりやすいかもしれない
  • 機械的なIDも必要だが、時にはパット見て分かるような配慮もあって然るべきだろう

9. 多すぎず、少なすぎず

  • それはそうという感じ
  • ログを出力しすぎて問題が発生することもあるし、少ないと障害特定に結びつかないかもしれない
  • 機械によるアシストがあっても、最終的に読むのは人間である。過不足無いデータが最適
  • (とは言っても難しいよね)
  • 個人的にはログローテーションとログを残したい期間を決めて、ちゃんと残る量で最大量出せばいいんじゃないかなと思ってる
    • ランニング試験でログの量を確認する感じ

10. 観客を考える

  • どういった人が読むのかを考える
  • readableと同じような感じであるが、エンドユーザーが読むのか、システム管理者が読むのか、開発者が読むのかでは変わってくる
  • ログといえば、管理者か開発者が読むものというイメージがあるが、こじつけで考えると、エンドユーザーがログイン記録などのログを確認する機会もあるだろう
  • ログレベルとセットで考えていけばいいのではないか

11. ログは障害調査目的だけではない

  • 3つの例が紹介されている
  • 監査目的:例えばログイン記録のようなもの。ActiveDirectoryみたいなやつを運用してたりすると、あれねという感じがする
  • プロファイル目的:性能を確認する目的がある。ログは時間も記録する。この時間を使って性能を見ることもできるだろう
  • 統計目的:ログを見ることでシステム全体の動作状況が把握できる。これを活用すれば、負荷がかかっている時間帯やリクエストの偏りなどの統計情報も得られる
  • ただ、取っていけば上が実現できるというものでもないので、あらかじめ目的がはっきりとしたログを取るべき

12. ベンダーロックインを避ける

  • ログに限ったことではないが、ロギングは広域に渡って使われるので、特にラッパーのようなものを用意しておくべきであるという話だろう

13. センシティブ情報を含めない

  • パスワードがクレジット番号など、ヤバい個人情報はロギングしない
  • デバッグログなどにも含めてはいけない
  • この辺はどこまでOKか難しいよね。IPアドレスは大丈夫か?とか
  • ヤバそうだけどどっかに書いとかないといけない場合は、暗号化してDBに入れよう
  • GDPRへのリンクもあった。そういえばそれもあったな

補足

ロギングの記事を書こうとしていた最中に記事を発見してしまったので、上にかかれていなくて、元々書こうとしていた事項も補足しておく。

ログ出力のオーバーヘッドに注意する

  • ドラゴンクエストXを支える技術」にしくじり先生が書いてある
  • ほんとに開発時だけログを出したいし、スピードを落としたくない場合は、ログのところを#ifdefみたいなやつで根こそぎ抜く技もある
  • Effective C++にゼロコストのログ削除方法が書いてあったような気がするけど、10年以上前の記憶なので定かじゃないな…

クライアント環境で起こった障害ログをどう送るか

  • クラッシュレポートを送ってもらう術がある。iOSだといろんなライブラリを使ったことがあるが、実際のアプリではどれくらい使われているんだろうか
  • winアプリとかだと障害ログを送ってもらう仕組みも含めたりする(クラッシュレポートか、やりすぎな感じもするけど)
  • 必要かどうか。送るまでやらなくても障害情報をまとめる機能があってもいいだろう。QA部門からの障害レポートでも役立つだろう

時間を遡ってログはとれない

  • 場合によってはエラーが発生したときには、重要な情報が失われていることがある
  • 多少の無駄があっても、エラーが発生した時に必要な情報は全てログで出せるようにしておこう
  • 障害発生時に、ここがみたいんだよなぁってのがある

ディスク容量は有限

  • ログでは長期運用が考えられる場合は、ログローテーションなどのログの容量管理を行おう
  • とりあえず出して測定しながら調整するのがよい
  • 何が必要かってのは分かりにくいよね