[Go] Go로 logging하는 방법

윤동환·2023년 7월 6일
0

Go

목록 보기
11/18
post-thumbnail

Go에는 기본 log package인 "log"를 지원합니다.

package main
 
import (
   "log"
   "os"
)
 
package main
 
import (
   "log"
   "os"
)
 
func main() {
   // Log to the console
   log.Println("Message to log in the console!")
   // Log in a log file
   file, err := os.OpenFile("log.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
   if err != nil {
       log.Fatal(err)
   }
   defer file.Close()
   log.SetOutput(file)
   log.Println("Message to log in a log file!")
}

log file에 직접 입력하거나, 출력하는 정도의 코드입니다.
Go 표준 로거는 구현하기 쉬운 만큼 로그 수준이 제한되어 있습니다.

그렇기에, 더 다양한 기능 (log를 level단위로 보여주는)을 제공하며 빠른 속도를 지원하는 zap을 사용해 보려고 합니다.

zap?

Go Zap은 Uber의 개발자가 개발하고 유지 관리하고 있으며 빠르고 구조적이며 수준별 로깅을 제공합니다. Zap에는 이벤트 로깅을 위한 두 가지 특징인 zap과 zap(sugared)이 있습니다. 첫 번째 플레이버 ZAP으로, 빠르기 때문에 성능을 우선시하는 애플리케이션에서 주로 사용됩니다.

zap 장점

  1. 다른 package와 비교하여 빠른 속도를 지원합니다.

  2. Debug, Info, Warning, Error, DPanic, Panic 그리고 Fatal이라는 7가지 유형의 로그 수준을 지원합니다.

예시

package main
 
import (
   "encoding/json"
 
   "go.uber.org/zap"
)
 
func main() {
   sampleJSON := []byte(`{
       "level" : "info",
       "encoding": "json",
       "outputPaths":["stdout", "log.log"],
       "errorOutputPaths":["stderr"],
       "encoderConfig": {
           "messageKey":"message",
           "levelKey":"level",
           "levelEncoder":"lowercase"
       }
   }`)
 
   var cfg zap.Config
 
   if err := json.Unmarshal(sampleJSON, &cfg); err != nil {
       panic(err)
   }
 
   logger, err := cfg.Build()
 
   if err != nil {
       panic(err)
   }
   defer logger.Sync()
 
 
   logger.Info("INFO log level message")
   logger.Warn("Warn log level message")
   logger.Error("Error log level message")
}

핵심 포인트는 로그 메시지의 대상을 의미하는 "stdout" 및 "log.log" 를 정의하는 outPutpaths 키입니다.
이 코드를 실행하면 내부에 로그 메시지가 포함된 새 log.log 파일이 생성됩니다.

예시 2

구성을 정의하지 않고 콘솔에 로그온할 수 있습니다.
zap 패키지에서 로그 개체를 만들고 사용을 시작해야 합니다.

package main
 
import "go.uber.org/zap"
 
func main() {
   logger, _ := zap.NewProduction()
 
   logger.Info("INFO log level message")
   logger.Warn("Warn log level message")
   logger.Error("Error log level message")
  }

logger, _ := zap.NewProduction() 명령을 사용하여 zap 개체를 초기화합니다.
로거 개체가 다시 반환되고 로그 수준에 해당하는 메서드를 호출하여 콘솔에 메시지를 기록하는 데 로그 수준을 사용할 수 있습니다.
예를 들어 logger.Info()를 사용하여 정보 로그 수준 메시지를 콘솔에 기록했습니다.
기본 로그 메시지에는 로그 수준, 타임스탬프 및 호출자(main.go 파일)가 포함됩니다.

예시 3

콘솔에서 인쇄하고 동시에 로그 파일에 쓸 수 있으려면 아래와 같이 두 개의 인코더를 추가해야 합니다.

package main

import (
	"os"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func main() {
	filename := "logs.log"
	logger := fileLogger(filename)

	logger.Info("INFO log level message")
	logger.Warn("Warn log level message")
	logger.Error("Error log level message")

}

func fileLogger(filename string) *zap.Logger {
	config := zap.NewProductionEncoderConfig()
	config.EncodeTime = zapcore.ISO8601TimeEncoder
	fileEncoder := zapcore.NewJSONEncoder(config)
	consoleEncoder := zapcore.NewConsoleEncoder(config)
	logFile, _ := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	writer := zapcore.AddSync(logFile)
	defaultLogLevel := zapcore.DebugLevel
	core := zapcore.NewTee(
		zapcore.NewCore(fileEncoder, writer, defaultLogLevel),
		zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), defaultLogLevel),
	)

	logger := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))

	return logger
}

reference

https://www.golinuxcloud.com/golang-zap-logger/

profile
모르면 공부하고 알게되면 공유하는 개발자

0개의 댓글