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",
},
})
}
标签:...,logrus,args,用法,Golang,func,logger,newLogger
From: https://www.cnblogs.com/qcy-blog/p/17778981.html