IT/Go

[Go/Golang] Zap과 시간 기반 파일 로테이션 로깅 수행하기

wookiist 2021. 3. 29. 10:01

본 포스트는 'dhwaneetbhatt'의 Time based log file rotation with zap 글을 번역한 것임을 밝힙니다.

Zap과 시간 기반의 파일 로테이션 로깅

zap은 현재까지도 잘 개발되어오고 있고, 성능 측면에서도 훌륭한 Go의 오픈소스 로깅 라이브러리입니다. 유감스럽게도, 원 글쓴이(이하, 필자)의 조직에서 제공하는 모든 앱들이 12-factor 애플리케이션으로 구성되지 않았으며, 이로인해 물리적으로 파일에 로그를 남기는 작업이 여전히 필요했습니다. 이와 같은 이유로 zap을 사용함과 동시에 파일을 로테이션 할 수 있도록 하는 방법이 필요했습니다. 필자는 Java 진영에서 넘어왔기 때문에 log4j의 매우 다양한 파일 로테이션 옵션을 제공하고 있는 것을 알고 있습니다. 그러나 zap에는 이러한 기능들이 결여되어 있는 것을 알게 되었는데, 이는 컨테이너 세계에선 stdout에 로깅하는 것이 매우 흔한 일이기 때문입니다. (로그를 이벤트 스트림으로 처리 - 12 factor logs)

좀 더 구체적으로 말하자면, 필자는 파일의 크기 기반이 아닌, 시간 기반의 로테이션(디버깅을 돕기 위한 시간당 하나의 파일을 만드는)을 찾고 있었습니다. zap의 FAQ를 보니, lumberjack과의 통합은 되어 있으나, lumberjack은 파일 크기 기반의 로테이션만을 제공하고 있습니다.

이에 필자는 file-rotatelogs라는 시간 기반 로테이션을 제공하는 라이브러리를 찾게 되었고, zap과 함께 사용하게 되었습니다.

zap의 좋은 점은 zap이 어떠한 io.Writer인터페이스든 WriterSyncer로 받을 수 있다는 것과 file-rotatelogs*RotateLogs라는 io.Writer 인터페이스의 구현체를 리턴한다는 점이었습니다.

rotate.logs.WithRotationTime(time.Hour))가 시간당 로테이션을 의미합니다. 그리고 rotatelogs.WithMaxAge(60*24*time.Hour)는 파일이 60일 이후에는 삭제될 것임을 의미합니다.

package main

import (
    "encoding/json"
    "time"

    rotatelogs "github.com/lestrrat-go/file-rotatelogs"
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
)

func main() {
    // initialize the rotator
    logFile := "/var/log/app-%Y-%m-%d-%H.log"
    rotator, err := rotatelogs.New(
        logFile,
        rotatelogs.WithMaxAge(60*24*time.Hour),
        rotatelogs.WithRotationTime(time.Hour))
    if err != nil {
        panic(err)
    }

    // initialize the JSON encoding config
    encoderConfig := map[string]string{
        "levelEncoder": "capital",
        "timeKey":      "date",
        "timeEncoder":  "iso8601",
    }
    data, _ := json.Marshal(encoderConfig)
    var encCfg zapcore.EncoderConfig
    if err := json.Unmarshal(data, &encCfg); err != nil {
        panic(err)
    }

    // add the encoder config and rotator to create a new zap logger
    w := zapcore.AddSync(rotator)
    core := zapcore.NewCore(
        zapcore.NewJSONEncoder(encCfg),
        w,
        zap.InfoLevel)
    logger := zap.New(core)

    logger.Info("Now logging in a rotated file")
}

이 코드를 실행하면 필자가 희망하던 /var/log/app-2021-03-29-10.log 파일을 생성합니다. 그리고 다음 시간에는 새로운 파일에서 로깅을 하게 됩니다.

마무리

만약 이 글이 도움이 되셨다면 글 좌측 하단의 하트❤를 눌러주시면 감사하겠습니다.

혹시라도 글에 이상이 있거나, 이해가 가지 않으시는 부분, 또는 추가적으로 궁금하신 내용이 있다면 주저 마시고 댓글💬을 남겨주세요! 빠른 시간 안에 답변을 드리겠습니다 😊

참고

반응형