Open11

log/slogの使い方

たまごたまご

key=valueで属性を追加したり、ログレベルの設定、メッセージを持ったログレコードを構造化したログパッケージ

たまごたまご

slogはLogger型を持っており、この方はLogger.InfoLogger.Errorといったメソッドをいくつか持っている

たまごたまご

ログレコードは時刻、ログレベル、メッセージとkey-valueのセットで表現される。
slog.Info("Hello", "count", 3)

2024/01/05 19:59:24 INFO Hello count=3
たまごたまご

デフォルトのハンドラを使うと出力はlogパッケージに渡されるので、もしフォーマットを独自のものにしたい場合はハンドラを自分で定位する必要がある。

テキスト形式でフォーマットする場合

logger := slog.New(slog.NewTextHandler(os.Stderr, nil))
logger.Info("Hello", "count", 2)
time=2024-01-05T20:06:37.485+09:00 level=INFO msg=Hello count=2

JSON形式でフォーマットする場合

jsonLogger := slog.New(slog.NewJSONHandler(os.Stderr, nil))
jsonLogger.Info("Hello", "count", 3)
{"time":"2024-01-05T20:13:26.037274619+09:00","level":"INFO","msg":"Hello","count":3}
たまごたまご

作成したハンドラをデフォルトとして扱いたい場合はslog.SetDefault(logger)を呼ぶことで設定できる

slog.SetDefault(jsonLogger)
slog.Info("default change", "count", 4)
{"time":"2024-01-05T21:15:32.806772913+09:00","level":"INFO","msg":"default change","count":4}
たまごたまご

共通で出力する属性の追加もできる。例えばWEBアプリケーションでリクエストのメソッドをログに常に出しておきたいといった場合は以下のようにLogger.Withを使うことで追加可能

logger2 := jsonLogger.With("method", r.Method)
logger2.Info("request start")
{"time":"2024-01-05T21:22:56.880100509+09:00","level":"INFO","msg":"request start","method":"GET"}
たまごたまご

ログレベルの設定はハンドラ作成時の引数slog.HandlerOptionsのLevelを設定することで行う。
LevelはLevelerというインターフェースで、これはslog.LevelVarのポインタが実装しているのでこの型のポインタ変数を用意することで行える。コードは以下

// ログレベルの設定
var programLevel = new(slog.LevelVar)
h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel})
slog.SetDefault(slog.New(h))
programLevel.Set(slog.LevelDebug)
slog.Debug("display!")
slog.Info("display!")
programLevel.Set(slog.LevelInfo)
slog.Debug("no display!")
slog.Info("display!")
{"time":"2024-01-05T21:45:07.312730299+09:00","level":"DEBUG","msg":"display!"}
{"time":"2024-01-05T21:45:07.312731762+09:00","level":"INFO","msg":"display!"}
{"time":"2024-01-05T21:45:07.312740409+09:00","level":"INFO","msg":"display!"}
たまごたまご

属性をひとまとめにするためにグループというものが存在する。
TextHandlerではグループと属性は.(ドット)で分かれる。JSONHandlerではJSONオブジェクトとして扱われる。

slog.Info("Hell", slog.Group("request", "method", r.Method, "url", r.URL.String()))
# TextHandlerの場合
time=2024-01-05T22:04:21.137+09:00 level=INFO msg=Hello request.method=GET request.url=https://example.com
# JSONHandlerの場合
{"time":"2024-01-05T22:03:14.181568376+09:00","level":"INFO","msg":"Hell","request":{"method":"GET","url":"https://example.com"}}

Logger.Withのように、共通のグループを付与したい場合はLogger.WithGroupで可能

たまごたまご

context.Contextなどから情報を取得したい場合、Logger.InfoContextがある。

たまごたまご

Attrはkey-valueのペア。
Loggerのメソッドはkeys/valueのかわりとしてAttrを受け付ける。
例えば以下は同じコードを意味する

slog.Info("hello", slog.Int("count", 3))
slog.Info("hello", "count", 3)