概要
Golangのロギングのライブラリであるzapのロギング例を示す。本記事では、以下のようなJSON形式のログを想定している。内容は、ログレベル、時刻、呼ばれた場所、メッセージである。
{"level":"debug","time":"2020-02-02T23:24:13.185+0900","caller":"logger/utils_test.go:31","msg":"test msg"}
{"level":"info","time":"2020-02-02T23:24:13.186+0900","caller":"logger/utils_test.go:32","msg":"test msg"}
{"level":"error","time":"2020-02-02T23:24:13.186+0900","caller":"logger/utils_test.go:34","msg":"test error"}
zapライブラリは、Readmeのパフォーマンス表では、Golangのロギングライブラリとして有名なlogrusより高速らしいです。
logrusは、Golang logrusによるロギングにて、記事にしましたが、zapの方が高速ということで、今回記事にしました。
プログラム
以下に、初期化のプログラムを示します。基本的には、出力方法やログレベルを環境変数から読み込み、それに合わせて初期化しているだけです。呼び出し時に初期化され、logger.Log.Info()などで使用できる。
package logger
import (
"fmt"
"go.uber.org/zap/zapcore"
"go.uber.org/zap"
)
/*zap
https://github.com/uber-go/zap#performance
*/
var (
Log *zap.Logger
)
func init() {
envVals, err := getEnv()
if err != nil {
fmt.Println(err)
panic(err)
}
outputPaths := []string{}
if envVals.filePath != "" {
outputPaths = append(outputPaths, envVals.filePath)
}
if envVals.stdout {
outputPaths = append(outputPaths, "stdout")
}
logConfig := zap.Config{
OutputPaths: outputPaths,
Level: zap.NewAtomicLevelAt(envVals.level),
Encoding: "json",
EncoderConfig: zapcore.EncoderConfig{
LevelKey: "level",
TimeKey: "time",
MessageKey: "msg",
CallerKey: "caller",
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
},
}
if Log, err = logConfig.Build(); err != nil {
panic(err)
}
}
以下プログラムに使用する環境変数取得など、、、
package logger
import (
"os"
"strconv"
"strings"
"go.uber.org/zap/zapcore"
)
type envVals struct {
filePath string
stdout bool
level zapcore.Level
}
//getEnv ログに関する環境変数を設定
func getEnv() (*envVals, error) {
res := envVals{}
res.filePath = os.Getenv("LOGGER_FILE_PATH")
var err error
res.stdout, err = strconv.ParseBool(os.Getenv("LOGGER_STDOUT"))
if err != nil {
res.stdout = true
}
level := os.Getenv("LOGGER_LEVEL")
switch level {
case "debug":
res.level = zapcore.DebugLevel
case "error":
res.level = zapcore.ErrorLevel
default:
res.level = zapcore.InfoLevel
}
return &res, nil
}