Closed6
GoのロギングライブラリZapについて調べる

以下を参考に試してみる。

Logger
と SugaredLogger
が存在する。
違いは以下の通り。
- Logger
- 高速
- 型に厳しい
- 構造化ロギングのみ可能
- SugaredLogger
- 少し低速
- 型に甘い(Sugar だけに)
- 構造化ロギングが可能
- printf スタイルのロギングが可能
Logger
package main
import (
"time"
"go.uber.org/zap"
)
func main() {
url := "http://hogefuga.com"
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("failed to fetch URL",
// Structured context as strongly typed Field values.
zap.String("url", url),
zap.Int("attempt", 3),
zap.Duration("backoff", time.Second),
)
}
{"level":"info","ts":1645599225.7300081,"caller":"zap-example/main.go:14","msg":"failed to fetch URL","url":"http://hogefuga.com","attempt":3,"backoff":1}
SugaredLogger
構造化パターンとprintfパターンを利用できる。
package main
import (
"time"
"go.uber.org/zap"
)
func main() {
url := "http://hogefuga.com"
logger, _ := zap.NewProduction()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
// 構造化パターン
sugar.Infow("failed to fetch URL",
// Structured context as loosely typed key-value pairs.
"url", url,
"attempt", 3,
"backoff", time.Second,
)
// printfパターン
sugar.Infof("Failed to fetch URL: %s", url)
}
{"level":"info","ts":1645598932.287895,"caller":"zap-example/main.go:15","msg":"failed to fetch URL","url":"http://hogefuga.com","attempt":3,"backoff":1}
{"level":"info","ts":1645598932.288001,"caller":"zap-example/main.go:21","msg":"Failed to fetch URL: http://hogefuga.com"}

ログレベル
const (
// DebugLevel logs are typically voluminous, and are usually disabled in
// production.
DebugLevel = zapcore.DebugLevel
// InfoLevel is the default logging priority.
InfoLevel = zapcore.InfoLevel
// WarnLevel logs are more important than Info, but don't need individual
// human review.
WarnLevel = zapcore.WarnLevel
// ErrorLevel logs are high-priority. If an application is running smoothly,
// it shouldn't generate any error-level logs.
ErrorLevel = zapcore.ErrorLevel
// DPanicLevel logs are particularly important errors. In development the
// logger panics after writing the message.
DPanicLevel = zapcore.DPanicLevel
// PanicLevel logs a message, then panics.
PanicLevel = zapcore.PanicLevel
// FatalLevel logs a message, then calls os.Exit(1).
FatalLevel = zapcore.FatalLevel
)

ログのフォーマット
zap.NewProduction
を使用するとログはjsonフォーマットになり
zap.NewDevelopment
を使用するとログがより人間がわかりやすいフォーマットになる。
package main
import (
"go.uber.org/zap"
)
func main() {
url := "http://hogefuga.com"
logger, _ := zap.NewDevelopment()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
// printfパターン
sugar.Infof("Failed to fetch URL: %s", url)
}
2022-02-23T16:50:32.434+0900 INFO zap-example/error.go:15 Failed to fetch URL: http://hogefuga.com

エラーログ
スタックトレースが出力されて良さげですね。
package main
import (
"go.uber.org/zap"
)
func main() {
url := "http://hogefuga.com"
logger, _ := zap.NewDevelopment()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
// printfパターン
sugar.Errorf("Failed to fetch URL: %s", url)
}
2022-02-23T16:55:01.433+0900 ERROR zap-example/error.go:15 Failed to fetch URL: http://hogefuga.com
main.main
/Users/***/Documents/repos/go-survey-coding/zap-example/error.go:15
runtime.main
/usr/local/Cellar/go/1.17.6/libexec/src/runtime/proc.go:255

ログパッケージでラップしたときにcallerがずれる
通常、以下のように独自でログをラップしたときに、ログパッケージのcallerが出力される。
2022-02-23T17:04:16.801+0900 DEBUG log/log.go:18 hogehoge
そんなときは AddCallerSkip
を使用する。
logger, err := zap.NewDevelopment(zap.AddCallerSkip(1))
2022-02-23T17:13:39.287+0900 DEBUG controller/hoge.go:182 hoge
このスクラップは2023/01/08にクローズされました