エンジニア版ベストキッド
— magnoliak🍧 (@magnolia_k_) 2022年4月10日
師匠
「ログを出す!ログを読む!」「syslogに出す! loggerで出す!」「ログレベルアップ!ダウン!アップ!ダウン!」
生徒
「クラウドネイティブなマイクロサービスの作り方を教えてくれる約束だ!」
プロダクション環境にて…
生徒「ログが…有る!これだ!」
アプリケーションログの重要性について、実運用を経験した人なら誰も異論は無いでしょう。
一方で、言語やフレームワークが用意するロギングライブラリの使い方について、ログをターミナルや、ログファイルへ出力する方法までは解説されていても、実際の監視設定や、監視運用と組み合わせて、アプリケーション側がどのような設計をすべきかは個々のプロジェクトの事情に合わせて検討していく必要があります。
一般的に、ロギングライブラリには、その順序づけられたログレベルが定義されています。
例えば、Javaの代表的なロギングライブラリである、logback-classic
には、TRACE
、DEBUG
、INFO
、WARN
、ERROR
という5種類のログレベルがあり、左から右に行くほどレベルが高くなると定義されています。
実際のログの出力は、このレベルを対象にコントロールされ、例えば先ほどのlogback-classic
であればデフォルトではDEBUG
以上のレベルがログとしてメッセージに出力されます。ログレベルにはそれぞれ用途を決めやすい名前が予め付けられてはいますが、実際にアプリケーションの中で何を基準に出力するかは、あくまでアプリケーション側の設計次第です。
じゃあ、どうすればいいか?となる訳ですが、監視システムでそのログレベルを検知した時の初動で決めるものだと思っています。
ログレベル、開発者が使うDEBUGと、後から遡って挙動を確認するためのINFOと定期的に棚卸するWARNと、今すぐ血相変えて確認すべきERRORの4種類くらいしか運用できなくない?って思うけど、どうだろう
— magnoliak🍧 (@magnolia_k_) 2022年9月11日
DEBUG
や、TRACE
は開発中しか出力されないように設定すると思いますが、逆にプロダクション環境のログに出ていたら、設定の誤りを疑うか、解析のための一時的に有効にしている状態かのどちらかですね。
また、同じログの出力先に対してアプリケーション自身と、そのアプリケーションで使っているライブラリの両方がログを出す可能性があり、出力する基準が違う可能性があります。こんな時は、ログレベルに加えて、オブジェクト名などで区別する必要が出てきます。
ライブラリ作者にとってのINFOはライブラリ利用者にとってDEBUGに相当するだろうしエンドユーザー目線だと、とか一瞬考えてみたけどそんなの正しく想像しながら実装するのは無理ゲーな気もしたのでやはり運用無理そう。 https://t.co/FkEd8337x5
— 武田 憲太郎 (@KentarouTakeda) 2022年9月13日
その他、例えばERROR
が出ているログだけだと分からないので、前後のログを一緒に見るためにプロセスIDや、DBのキーなどをログに出力することで一連のログを、ログレベルに関係なく関連づけて見る場面もあり得ます。
どちらにしても、「そのログが出た後、何をするのか?」を考えて設計する必要があります。
また、ログレベルは、ロギングライブラリごとにバラついていて、DEBUG
、INFO
、WARN
、ERROR
くらいは割と同じですが、TRACE
が無かったり、ERROR
の更に上にCRITICAL
が有ったりします。
さらに、JDKの標準ライブラリであるjava.util.logging
は、割と独特の表記で、以下のようなログレベルになっています。また、環境のLocaleの設定によっては、そのロケールに合わせて翻訳されて出力されるなど、なかなか独特ですね...
SEVERE (highest value)
WARNING
INFO
CONFIG
FINE
FINER
FINEST (lowest value)
色々な議論の経緯を踏まえて決定されたのだと思いますが......思いますが、FINE
、FINER
、FINEST
じゃなくても良かったんじゃないかなーとは思います。
java.util.loggingのログレベル、全然意味が分からないんだけど、AirFrame-Logは全部きれいにラッピングされてた
— magnoliak🍧 (@magnolia_k_) 2022年8月30日
SEVEREからFINE、FINER、FINESTって全然どれを読むべきなのか判断つかないんだけど、どうしてこうなったんだろう…https://t.co/YxQtFalooL
最近は、ログもベタっと1行のテキストで出力するのではなく、最初から構造化ログで出すことが増えてきていて、以前のような「エラーログは別ファイルに出しておいて、ログファイルの行数が増えたらアラート」みたいな仕組みではなくて、もっと最初から中身を見て判定できる仕組みになってきているそうですが、結局は監視設計に合わせて出力する、というところは変わらないですね。