Go에서 로그 사용하기

임태빈·2022년 1월 10일
1

go

목록 보기
9/13

안녕하세요.

이번 포스팅에서는 log 찍는 방법에 대해 작성해보려고 합니다.

로그를 쓰는 이유

로깅의 이점

대부분의 회사에 웹 서비스는 로깅합니다.
그렇다면 로깅은 이 웹 서비스를 운영하는 데 있을까요?

  • 로깅은 개발자가 에러 혹은 퍼포먼스 이슈를 발견하는데 도움을 줍니다.
  • 로그들을 재구성하여 시스템을 파악할 수 있습니다.

기록해야 하는 것은?

버그 발견과 디버깅 과정을 쉽게 만드는 무엇이든 기록하면 됩니다. 로그 메시지에는 타임스탬프, 오류 메시지 등과 같은 디버깅에 유용한 정보가 포함될 수 있습니다.

기록하지 말아야 하는 것은?

보안과 관련된 정보는 특히 실제 서비스 환경에서 권장되지 않습니다.
예시로, 신용카드 정보, 사용자의 개인정보 등이 있습니다.
로그가 유출되면 해커가 이를 악용할 수 있기 때문에 조심해야 합니다.

기본 제공 로그 패키지

기본 예시

다음과 같이 Go의 기본 제공 패키지를 활용해 로그를 찍을 수 있습니다.

package main

import "log"

func main() {
	log.Println("This is logging")
}

이 코드를 실행하면 로그 메시지와 함께 시간 정보를 보실 수 있습니다.

만약 로그를 파일에 남기고 싶으시다면 다음과 같은 코드를 사용하시면 됩니다.

package main
import (
	"log"
	"os"
)
func main() {
	logFile := openLogFile()
	defer logFile.Close()
	log.SetOutput(logFile)
	log.Println("This is logging!")
}
func openLogFile() *os.File {
	f, err := os.OpenFile("access.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatal(err)
	}
	return f
}

이 코드를 실행하면 access.log에 로그 기록이 남겨져 있는 것을 확인하실 수 있습니다.

기본 라이브러리의 문제점

기본 라이브러리에 경우 너무 단순합니다. 개발 환경에서는 빨리 확인할 수 있어 좋지만 실제 서비스 환경에서는 정확하고 체계적인 내용을 봐야하기 때문에 기본 라이브러리는 적합하지 않습니다.

Logging 프레임워크 zap

zap은 Uber에 의해 개발된 오픈소스이며 성능이 정말 좋습니다.
zap은 Debug, Info, Warning, Error, DPanic, Panic, and Fatal 총 7가지 디버깅 레벨을 제공해줍니다.
각각의 레벨의 설명은 다음과 같습니다.

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 사용해보기

zap 라이브러리 설치하기

go get go.uber.org/zap

zap을 활용해 로그 설정하기

package main

import (
	"go.uber.org/zap"
)

func main() {
	logger, _ := zap.NewDevelopment()
	defer logger.Sync()
	logger.Info("Hello Zap!")
	logger.Warn("Beware of getting Zapped! (Pun)")
	logger.Error("I'm out of Zap joke!")
}

위 코드에서 zap.NewDevelopment()는 메시지들을 출력하는 로거의 기본세팅값을 반환해줍니다. 이 코드를 실행하면 다음과 같은 결과를 보실 수 있습니다.

INFO 레벨에 경우 메시지만 출력을 해줍니다. WARN과 ERROR에 경우 stack trace와 메시지를 둘 다 출력해줍니다. 이것을 통해 에러가 어디서 발생했는지 찾는데 유용합니다.

zap에 Conifg 작성해서 적용하기

package main

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

func main() {
	var log *zap.Logger
	var err error
	config := zap.NewProductionConfig()
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.TimeKey = "timestamp"
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.StacktraceKey = ""
	config.EncoderConfig = encoderConfig
	log, err = config.Build(zap.AddCallerSkip(1))
	if err != nil {
		panic(err)
	}

	log.Info("Hello Zap!")
	log.Warn("Beware of getting Zapped! (Pun)")
	log.Error("I'm out of Zap joke!")
}

zap에 경우 Config를 활용해서 나만의 로그를 만들 수 있습니다. 위 코드는 프로덕션환경에서 쓸 수 있는 설정을 제공해주며 추가적으로 변경을 원할 경우, Config를 변경해서 사용하시면 됩니다.
결과는 밑에 그림처럼 나왔습니다.

제가 준비한 내용은 여기까지가 끝이며 다음에도 좋은 내용을 가지고 오겠습니다~~

profile
golang과 서버 개발을 하고 있는 개발자입니다.

0개의 댓글