Fall in IT.

Go 로깅라이브러리 Logrus Hook에 대하여 본문

프로그래밍언어/Golang

Go 로깅라이브러리 Logrus Hook에 대하여

D.Y 2024. 3. 3. 21:12

안녕하세요.

오늘은 Go 로깅라이브러리인 Logrus의 Hook 기능에 대하여 알아보겠습니다.

 

Logrus란?

Go 언어용으로 널리 사용되는 로깅 라이브러리이다. 확장성과 유연성을 제공하기 위해 Hook 기능을 사용할 수 있다.

 

Hook이란?

훅 시스템을 통해 개발자는 로깅 프로세스에 추가적인 동작을 주입할 수 있다.

예를들어, 로그 메시지를 파일에 기록하는 동시에 오류 메시지를 Slack으로 전송하거나 로그 데이터를 Elasticsearch 같은 검색 엔진에 인덱싱할 수 있다.

 

Hook 인터페이스

// logrus에 정의된 Hook 인터페이스 

package logrus

// A hook to be fired when logging on the logging levels returned from
// `Levels()` on your implementation of the interface. Note that this is not
// fired in a goroutine or a channel with workers, you should handle such
// functionality yourself if your call is non-blocking and you don't wish for
// the logging calls for levels returned from `Levels()` to block.
type Hook interface {
	Levels() []Level
	Fire(*Entry) error
}
// logrus에 정의된 LevelHooks 구조체 

package logrus

// Internal type for storing the hooks on a logger instance.
type LevelHooks map[Level][]Hook

// Add a hook to an instance of logger. This is called with
// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
func (hooks LevelHooks) Add(hook Hook) {
	for _, level := range hook.Levels() {
		hooks[level] = append(hooks[level], hook)
	}
}

// Fire all the hooks for the passed level. Used by `entry.log` to fire
// appropriate hooks for a log entry.
func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
	for _, hook := range hooks[level] {
		if err := hook.Fire(entry); err != nil {
			return err
		}
	}

	return nil
}

Hook 인터페이스는 두 가지 메서드를 정의한다.

  • Levels() []Level
  • File(*Entry) error

Levels() []Level

이 훅이 활성화되어야 하는 로그 레벨을 반환한다. 예를들어, levels 메서드가 [ErrorLevel, FatalLevel, PanicLevel]을 반환하면, 이 훅은 에러, 치명적 오류, 패닉 레벨의 로그에 대해서만 실행된다.

 

Fire(*Entry) error

로그 엔트리가 생성될때 호출되는 메서드이다. Entry는 로그 메시지와 관련 데이터를 포함한다. 여기서 개발자는 로그 데이터를 처리하고 필요한 경우 외부 시스템으로 전송하는 등의 작업을 수행할 수 있다.

 

LevelHooks 구조체

LevelHooks는 로그 레벨별로 훅 리스트를 관리하는 맵이다. 각 로그 레벨에 대해 하나 이상의 훅을 연결할 수 있다.

 

Add 메서드

Add 메서드는 LevelHooks 맵에 새로운 훅을 추가하는 메서드이다. 이 메서드는 훅이 활성화될 로그 레벨을 Levels() 메서드를 통해 조회하고 해당 레벨의 훅 리스트에 추가한다.

 

Fire 메서드

Fire 메서드는 특정 로그 레벨에 대해 모든 관련 훅을 실행한다. 로그 엔트리가 생성될때, 해당 엔트리의 레벨에 대해 등록된 모든 훅의 Fire 메서드를 호출한다.

 

Hook 연동 방법

  1. Hook 인터페이스를 구현하는 사용자 정의 훅을 개발한다. 이때, Levels와 Fire 메서드를 정의해야한다.
  2. 로거 인스턴스에 이 훅을 추가한다. 이는 log.AddHook(new(MyHook)) 과 같이 추가한다. MyHook은 사용자가 구현한 훅이다.
  3. 로깅이 발생할때 Logrus는 등록된 모든 훅을 검사하고 현재 로그 레벨에 해당하는 훅의 Fire 메서드를 호출한다.

 

예제코드

package main

import (
	"fmt"
	log "github.com/sirupsen/logrus"
	"os"
)

type Person struct {
	Name string
	Age  int
}

func (p Person) String() string {
	return fmt.Sprintf("%s: %d", p.Name, p.Age)
}

type CustomHook struct {
}

func (c CustomHook) Levels() []log.Level {
	return log.AllLevels
}

func (c CustomHook) Fire(*log.Entry) error {
	fmt.Println("[hook] custom hook fired.")

	// DO SOMETHING...

	return nil
}

func init() {
	// SET LOG CONFIGURATION
	log.SetFormatter(&log.JSONFormatter{})
	log.SetOutput(os.Stdout)
	log.SetLevel(log.TraceLevel)

	log.AddHook(CustomHook{})
}

func main() {
	people := []Person{
		{"Kaye", 35},
		{"Jade", 44},
	}

	log.Debugf("%+v", people)
}

 

참고

https://github.com/sirupsen/logrus

Comments