17
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

Organization

【Golang】zapを用いたロギング

概要

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
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
17
Help us understand the problem. What are the problem?