ログ出力をどうするかっていうのは、Go 書くときに常にちょっとした悩みの種でした。 標準の log パッケージはあるものの、実用には機能が不足していると見なす人が多いためです。
かくいう私もその一人で、近年は Kubernetes 界隈でよく使われている以下を組み合わせていました。
logr は所謂 structured logging のための共通インタフェースを提供するパッケージで、uber-go/zap のような著名なログライブラリ向けにアダプタも提供してくれます。 debug, info, warn, error といったいわゆるログレベルも備えていますし、context 経由で logger を渡すこともできるので、便利に活用していました。
ただ、logr は結構使われているとはいえ標準パッケージではないため、logr を使わないライブラリ等と組み合わせるのが難しいのが悩みでした。 そんなこんなの声を受けてか、Go 1.21 で log/slog というパッケージが標準で利用できるようになりそうです。 まだリリース前ですが、万一取り除かれたりしない限りは近い将来使えるようになるでしょう。
で、新規にプログラムを作るにあたって、どうせ Go 1.21 以降でプロダクション開発するだろうなと思うと logr + zap よりはこの slog パッケージにしておきたいです。 幸いなことに、Go 本体に取り込まれたのとほぼ同じコードが golang.org/x/exp/slog として今すぐ利用できます。 前置きが長くなりましたが、そんなわけで slog を使ってみたので以下に特徴を紹介します。
- インタフェースではなく実装なので、他のログライブラリを組み合わせる必要なし
- structured + leveled logging 可能
- さらに、ネストした structure も可能
- slog.SetDefault を呼ぶと標準の log パッケージの出力も slog になる
- テキスト形式のほか、JSON 形式の出力も手軽にできる
- APIトークンなどをログに出さないよう型ベースで設定できる (例)
最後発だけあり、痒い所に手が届く良い設計だと思います。 context 経由での受け渡しはまだないようですが、実装は簡単なので手元で適当に足して使っています。
以上