go1.21から公式の構造ロガー「slog」が標準搭載されましたが、シンプルにログを出すことができなかったので、工夫したことをブログにします。
やりたいこと
1.ログレベルを指定できる
2.以下のように時間、レベル、メッセージがテキストで印字できる
[2024-01-04 18:20:47.234] [ INFO] メッセージ
slogだけだと何が駄目か?
パッケージにある関数を直接呼び出す slog.Info("info msg")
という方法だと、レベル指定ができない
TextHandler だと、レベルを指定できが、印字される文字が以下のようにキー=バリュー
という以下のような文字列になり、読みにくい
time=2024-01-04T18:20:16.149+09:00 level=INFO msg=メッセージ
他の言語にあるFormatterなどを用いた指定もできない。
どうしたか
シンプルにログを出せる SimpleHandler
を作った
以下、作ったコードです。そのまま動きます。
package main
import (
"context"
"fmt"
"io"
"log"
"log/slog"
"os"
)
type SimpleHandler struct {
slog.Handler
logger *log.Logger
}
func NewSimpleHandler(out io.Writer, level slog.Level) *SimpleHandler {
prefix := ""
h := &SimpleHandler{
Handler: slog.NewJSONHandler(out, &slog.HandlerOptions{
Level: level,
}),
logger: log.New(out, prefix, 0),
}
return h
}
func (h *SimpleHandler) Handle(_ context.Context, record slog.Record) error {
ts := record.Time.Format("[2006-01-02 15:04:05.000]")
level := fmt.Sprintf("[%5s]", record.Level.String())
h.logger.Println(ts, level, record.Message)
return nil
}
func main() {
handler := NewSimpleHandler(os.Stdout, slog.LevelInfo)
logger := slog.New(handler)
logger.Debug("debug msg")
logger.Info("info msg")
logger.Warn("warning msg")
logger.Error("error msg")
}
実行結果は以下のようにレベルを指定して、時間、レベル、メッセージを出すことができました!
[2024-01-04 18:20:47.234] [ INFO] info msg
[2024-01-04 18:20:47.235] [ WARN] warning msg
[2024-01-04 18:20:47.235] [ERROR] error msg