Golang logrus用法

logrus目前以及不维护了,care的话可以用zap

package xlog

import (
	"bufio"
	"fmt"
	"github.com/sirupsen/logrus"
    rotatelogs "github.com/lestrrat-go/file-rotatelogs"
    "github.com/rifflock/lfshook"
	"os"
	"time"
)

type Config struct {
	Path         string
	FilePrefix   string
	LevelMode    string
	RotationTime int64

	Server string
}

type Logger struct {
	*logrus.Logger

	globalFields logrus.Fields
}

var logger Logger

func Init(c *Config) (err error) {
	if c.Path == "" {
		return fmt.Errorf("log config.Path is nil")
	}

	newLogger := logrus.New()
	newLogger.AddHook(newDefaultLfsHook(c))

	switch c.LevelMode {
	case "debug": // 如果日志级别不是debug就不要打印日志到控制台了
		newLogger.SetLevel(logrus.DebugLevel)
		newLogger.SetOutput(os.Stderr)
	case "info":
		setNull(newLogger)
		newLogger.SetLevel(logrus.InfoLevel)
	case "warn":
		setNull(newLogger)
		newLogger.SetLevel(logrus.WarnLevel)
	case "error":
		setNull(newLogger)
		newLogger.SetLevel(logrus.ErrorLevel)
	default:
		setNull(newLogger)
		newLogger.SetLevel(logrus.InfoLevel)
	}

	// 设置全局fields
	field := logrus.Fields{"server": c.Server}

	logger = Logger{
		Logger:       newLogger,
		globalFields: field,
	}
	return
}

func GetLogger() Logger {
	return logger
}

// New 自定义初始化 logger 服务
func New(c *Config, suffix string) *logrus.Logger {
	newLogger := logrus.New()
	newLogger.AddHook(newLfsHook(c, suffix))

	/*
	   如果日志级别不是debug就不要打印日志到控制台了
	*/
	switch c.LevelMode {
	case "debug":
		newLogger.SetLevel(logrus.DebugLevel)
		newLogger.SetOutput(os.Stderr)
	case "info":
		setNull(newLogger)
		newLogger.SetLevel(logrus.InfoLevel)
	case "warn":
		setNull(newLogger)
		newLogger.SetLevel(logrus.WarnLevel)
	case "error":
		setNull(newLogger)
		newLogger.SetLevel(logrus.ErrorLevel)
	default:
		setNull(newLogger)
		newLogger.SetLevel(logrus.InfoLevel)
	}
	return newLogger
}

// 取消标准输出
func setNull(logger *logrus.Logger) {
	src, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
	if err != nil {
		logger.Errorf("err: %+v", err)
	}
	writer := bufio.NewWriter(src)
	logger.SetOutput(writer)
}

func WithError(err error) *logrus.Entry {
	return logger.Logger.WithFields(logger.globalFields).WithError(err)
}

func WithTime(time time.Time) *logrus.Entry {
	return logger.Logger.WithFields(logger.globalFields).WithTime(time)
}

func WithField(key string, value interface{}) *logrus.Entry {
	return logger.Logger.WithFields(logger.globalFields).WithField(key, value)
}

func WithFields(fields logrus.Fields) *logrus.Entry {
	return logger.Logger.WithFields(logger.globalFields).WithFields(fields)
}

func Tracef(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Tracef(format, args...)
}

func Debugf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Debugf(format, args...)
}

func Infof(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Infof(format, args...)
}

func Printf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Printf(format, args...)
}

func Warnf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Warnf(format, args...)
}

func Warningf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Warningf(format, args...)
}

func Errorf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Errorf(format, args...)
}

func Fatalf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Fatalf(format, args...)
}

func Panicf(format string, args ...interface{}) {
	logger.WithFields(logger.globalFields).Panicf(format, args...)
}

func Log(level logrus.Level, args ...interface{}) {
	logger.WithFields(logger.globalFields).Log(level, args...)
}

func Trace(args ...interface{}) {
	logger.WithFields(logger.globalFields).Trace(args...)
}

func Debug(args ...interface{}) {
	logger.WithFields(logger.globalFields).Debug(args...)
}

func Info(args ...interface{}) {
	logger.WithFields(logger.globalFields).Info(args...)
}

func Print(args ...interface{}) {
	logger.WithFields(logger.globalFields).Print(args...)
}

func Warn(args ...interface{}) {
	logger.WithFields(logger.globalFields).Warn(args...)
}

func Warning(args ...interface{}) {
	logger.WithFields(logger.globalFields).Warning(args...)
}

func Error(args ...interface{}) {
	logger.WithFields(logger.globalFields).Error(args...)
}

func Fatal(args ...interface{}) {
	logger.WithFields(logger.globalFields).Fatal(args...)
}

func Panic(args ...interface{}) {
	logger.WithFields(logger.globalFields).Panic(args...)
}

func newDefaultLfsHook(c *Config) *lfshook.LfsHook {
	var bathLogPath, bathLinkPath string
	bathLogPath = c.Path + c.FilePrefix
	bathLinkPath = c.Path + "latest.log"
	/* 日志轮转相关函数
	`WithLinkName` 为最新的日志建立软连接
	`WithRotationTime` 设置日志分割的时间,隔多久分割一次
	WithMaxAge 和 WithRotationCount二者只能设置一个
	 `WithMaxAge` 设置文件清理前的最长保存时间
	 `WithRotationCount` 设置文件清理前最多保存的个数
	*/
	// 下面配置日志每隔 1 分钟轮转一个新文件,保留最近 3 分钟的日志文件,多余的自动清理掉。
	writer, err := rotatelogs.New(
		bathLogPath,
		rotatelogs.WithLinkName(bathLinkPath),
		//rotatelogs.WithMaxAge(time.Duration(180)*time.Second),
		//rotatelogs.WithRotationTime(time.Duration(60)*time.Second),
		rotatelogs.WithRotationTime(time.Duration(c.RotationTime)*time.Second),
	)

	if err != nil {
		logrus.Errorf("config local file system logger error. %+v", err)
	}

	return lfshook.NewHook(
		lfshook.WriterMap{
			logrus.DebugLevel: writer, // 为不同级别设置不同的输出目的
			logrus.InfoLevel:  writer,
			logrus.WarnLevel:  writer,
			logrus.ErrorLevel: writer,
			logrus.FatalLevel: writer,
			logrus.PanicLevel: writer,
		}, &logrus.JSONFormatter{
			TimestampFormat: "2006-01-02T15:04:05Z07:00",
			FieldMap: logrus.FieldMap{
				logrus.FieldKeyLevel: "logLevel",
				logrus.FieldKeyMsg:   "msg",
				logrus.FieldKeyTime:  "@timestamp",
			},
		})
}

func newLfsHook(c *Config, suffix string) *lfshook.LfsHook {
	var bathLogPath, bathLinkPath, bathErrorPath string
	if suffix != "" {
		bathLogPath = c.Path + suffix + "." + c.FilePrefix
		bathLinkPath = c.Path + suffix + ".log"
		bathErrorPath = c.Path + suffix + "_error" + ".log"
	} else {
		bathLogPath = c.Path + c.FilePrefix
		bathLinkPath = c.Path + "go.log"
		bathErrorPath = c.Path + "error.log"
	}
	/* 日志轮转相关函数
	`WithLinkName` 为最新的日志建立软连接
	`WithRotationTime` 设置日志分割的时间,隔多久分割一次
	WithMaxAge 和 WithRotationCount二者只能设置一个
	 `WithMaxAge` 设置文件清理前的最长保存时间
	 `WithRotationCount` 设置文件清理前最多保存的个数
	*/
	// 下面配置日志每隔 1 分钟轮转一个新文件,保留最近 3 分钟的日志文件,多余的自动清理掉。
	writer, err := rotatelogs.New(
		bathLogPath,
		rotatelogs.WithLinkName(bathLinkPath),
		rotatelogs.WithMaxAge(time.Duration(180)*time.Second),
		rotatelogs.WithRotationTime(time.Duration(c.RotationTime)*time.Second),
	)

	if err != nil {
		logrus.Errorf("config local file system logger error. %+v", err)
	}

	errWriter, err := rotatelogs.New(
		bathErrorPath,
		//rotatelogs.WithMaxAge(time.Duration(180)*time.Second),
		rotatelogs.WithRotationTime(time.Duration(c.RotationTime)*time.Second),
	)

	if err != nil {
		logrus.Errorf("config local file system logger error. %+v", err)
	}

	return lfshook.NewHook(
		lfshook.WriterMap{
			logrus.DebugLevel: writer, // 为不同级别设置不同的输出目的
			logrus.InfoLevel:  writer,
			logrus.WarnLevel:  writer,
			logrus.ErrorLevel: errWriter,
			logrus.FatalLevel: errWriter,
			logrus.PanicLevel: errWriter,
		}, &JSONFormatter{
			TimestampFormat: "2006-01-02T15:04:05Z07:00",
			FieldMap: FieldMap{
				logrus.FieldKeyLevel: "logLevel",
				logrus.FieldKeyMsg:   "msg",
				logrus.FieldKeyTime:  "@timestamp",
			},
		})
}
posted @   朝阳1  阅读(93)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示