Golang zap和lumberjack实现日志存储和自动管理

期望实现功能

按不同的日志级别存储到不同的日志文件中(这里只实现了info和error级别)

控制最多保留的日志文件及保留最近多少天的日志文件(控制日志的最大磁盘使用量)

控制每个日志文件的大小

 

我们使用zap和lumberjack框架实现

go get -u go.uber.org/zap
go get gopkg.in/natefinch/lumberjack.v2

 

lumberjack的Logger结构体如下
type Logger struct {
	//写日志的文件名称
	Filename string `json:"filename" yaml:"filename"`


	//每个日志文件长度的最大大小,默认100M。
	MaxSize int `json:"maxsize" yaml:"maxsize"`


	//日志保留的最大天数(只保留最近多少天的日志)
	MaxAge int `json:"maxage" yaml:"maxage"`


	//只保留最近多少个日志文件,用于控制程序总日志的大小
	MaxBackups int `json:"maxbackups" yaml:"maxbackups"`


	//是否使用本地时间,默认使用UTC时间
	LocalTime bool `json:"localtime" yaml:"localtime"`


	// 是否压缩日志文件,压缩方法gzip
	Compress bool `json:"compress" yaml:"compress"`

	size int64   //记录当前日志文件的字节数
	file *os.File  //当前的日志文件
	mu   sync.Mutex

	millCh    chan bool
	startMill sync.Once
}

lumberjack的使用及源码可参考:https://mp.csdn.net/console/editor/html/107142274

 

示例

package applog

import(
	"strings"
	"path/filepath"

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

	"gopkg.in/natefinch/lumberjack.v2"
)

var (
	infoLevel = "info"
	errorLevel = "error"
	debugLevel = "debug"
)


func NewLog(dir, prefix,level  string,maxSize,maxBackups,maxAge int) (*zap.Logger, func(),error) {

	if maxSize < 0 {
		maxSize = 0
	}
	if maxBackups < 0 {
		maxBackups = 0
	}
	if maxAge < 0 {
		maxAge = 0
	}

	infoLog := &lumberjack.Logger{
		Filename:   getFilePath(dir, prefix, infoLevel),
		MaxSize:    maxSize,
		MaxBackups: maxBackups,
		MaxAge:     maxAge,
		LocalTime:  true,
		Compress:   false,
	}

	errLog := &lumberjack.Logger{
		Filename:   getFilePath(dir, prefix, errorLevel),
		MaxSize:    maxSize,
		MaxBackups: maxBackups,
		MaxAge:     maxAge,
		LocalTime:  true,
		Compress:   false,
	}

	cronLogger := &lumberLog{
		dir:dir,
		prefix: prefix,
		level: level,
		infoLog: infoLog,
		errLog: errLog,
	}

	return cronLogger.getLoggerWithCron(), func() {cronLogger.StopLogger()},nil
}

func (l *lumberLog) rotate()  {
	if l.infoLog != nil {
		l.infoLog.Rotate()
	}
	if l.errLog != nil {
		l.errLog.Rotate()
	}
}

type lumberLog struct {
	dir string
	prefix  string
	level   string
	infoLog  *lumberjack.Logger
	errLog *lumberjack.Logger
}

func (l *lumberLog) StopLogger() {
	l.infoLog.Close()
	l.errLog.Close()
}

func (l *lumberLog)getLoggerWithCron()  (*zap.Logger) {
	highPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool{
		return lev >= zap.ErrorLevel
	})

	lowLevel := zap.InfoLevel
	if  strings.EqualFold(l.level,debugLevel) {
		lowLevel = zap.DebugLevel
	}

	lowPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
		return lev < zap.ErrorLevel && lev >= lowLevel
	})

	prodEncoder := zap.NewProductionEncoderConfig()
	prodEncoder.EncodeTime = zapcore.ISO8601TimeEncoder
	prodEncoder.CallerKey = ""

	highCore := zapcore.NewCore(zapcore.NewJSONEncoder(prodEncoder),zapcore.AddSync(l.errLog),highPriority)
	lowCore := zapcore.NewCore(zapcore.NewJSONEncoder(prodEncoder),zapcore.AddSync(l.infoLog),lowPriority)

	return zap.New(zapcore.NewTee(highCore,lowCore))
}



func getFilePath(dir, prefile, level string) string  {
	return filepath.Join(dir,level,prefile+"-"+level)+".log"
}

 

你可能感兴趣的:(go小程序)