game_sync/statistics/tools/logrus_hook.go

96 lines
2.4 KiB
Go

package tools
import (
"fmt"
"runtime"
"strings"
"time"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/writer"
)
// FileLineHook 新增一个字段用来打印文件路径及行号
type FileLineHook struct {
LogLevels []logrus.Level // 需要打印的日志级别
FieldName string // 字段名称
Skip int // 跳过几层调用栈
Num int // Skip后的查找范围
Test bool // 打印所有调用栈信息,找出合适的 Skip 配置
filename string // 文件名
line int // 行号
}
func (e *FileLineHook) Levels() []logrus.Level {
return e.LogLevels
}
func (e *FileLineHook) Fire(entry *logrus.Entry) error {
for i := 0; i < e.Num; i++ {
_, e.filename, e.line, _ = runtime.Caller(e.Skip + i)
if !strings.Contains(e.filename, "logrus") {
break
}
}
entry.Data[e.FieldName] = fmt.Sprintf("%s:%d", e.filename, e.line)
if e.Test {
buf := [4096]byte{}
n := runtime.Stack(buf[:], false)
fmt.Println(string(buf[:n]))
}
return nil
}
// NewFileLineHook 打印文件路径及行号
// levels 指定日志级别
func NewFileLineHook(levels ...logrus.Level) logrus.Hook {
return &FileLineHook{
LogLevels: levels,
FieldName: "source",
Skip: 8,
Num: 2,
}
}
type RotateLogConfig struct {
Levels []string `json:"levels"`
Pattern string `json:"pattern"`
LinkName string `json:"link_name"`
MaxAge int `json:"max_age"`
RotationTime int `json:"rotation_time"`
RotationCount int `json:"rotation_count"`
RotationSize int `json:"rotation_size"`
}
func NewRotateLogHook(config *RotateLogConfig) logrus.Hook {
var levels []logrus.Level
for _, v := range config.Levels {
level, err := logrus.ParseLevel(v)
if err != nil {
panic(err)
}
levels = append(levels, level)
}
if len(levels) == 0 {
levels = logrus.AllLevels
}
l, err := rotatelogs.New(config.Pattern,
rotatelogs.WithLinkName(config.LinkName),
rotatelogs.WithMaxAge(time.Duration(config.MaxAge)*time.Hour),
rotatelogs.WithRotationTime(time.Duration(config.RotationTime)*time.Hour),
rotatelogs.WithRotationCount(uint(config.RotationCount)),
rotatelogs.WithRotationSize(int64(config.RotationSize)),
)
if err != nil {
panic(err)
}
return &writer.Hook{
Writer: l,
LogLevels: levels,
}
}