|
|
package golog
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
"fmt"
|
|
|
"github.com/sirupsen/logrus"
|
|
|
"go.dtapp.net/gotime"
|
|
|
"go.dtapp.net/gotrace_id"
|
|
|
"io"
|
|
|
"log"
|
|
|
"os"
|
|
|
"path"
|
|
|
)
|
|
|
|
|
|
type LogRusLogConfig struct {
|
|
|
LogPath string // 日志文件路径
|
|
|
LogInConsole bool // 是否同时输出到控制台
|
|
|
}
|
|
|
|
|
|
type LogRusLog struct {
|
|
|
config *LogRusLogConfig // 配置
|
|
|
logger *logrus.Logger // 日志服务
|
|
|
entry *logrus.Entry // 日志
|
|
|
level logrus.Level // 日志等级
|
|
|
}
|
|
|
|
|
|
func NewLogRusLog(config *LogRusLogConfig) *LogRusLog {
|
|
|
|
|
|
lr := &LogRusLog{config: config}
|
|
|
lr.logger = logrus.New()
|
|
|
|
|
|
// 设置为json格式
|
|
|
lr.logger.SetFormatter(&logrus.JSONFormatter{
|
|
|
TimestampFormat: gotime.DateTimeFormat,
|
|
|
})
|
|
|
|
|
|
// 需要保存到文件
|
|
|
if lr.config.LogPath != "" {
|
|
|
lr.logger.SetReportCaller(true)
|
|
|
}
|
|
|
|
|
|
return lr
|
|
|
}
|
|
|
|
|
|
// 跟踪编号
|
|
|
func (lr *LogRusLog) withTraceId(ctx context.Context) *LogRusLog {
|
|
|
lr.entry = lr.logger.WithField("trace_id", gotrace_id.GetTraceIdContext(ctx))
|
|
|
return lr
|
|
|
}
|
|
|
|
|
|
// Print 打印
|
|
|
func (lr *LogRusLog) Print(ctx context.Context, args ...interface{}) {
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Print(args...)
|
|
|
}
|
|
|
|
|
|
// Printf 打印
|
|
|
func (lr *LogRusLog) Printf(ctx context.Context, format string, args ...interface{}) {
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Printf(format, args...)
|
|
|
}
|
|
|
|
|
|
// Println 打印
|
|
|
func (lr *LogRusLog) Println(ctx context.Context, args ...interface{}) {
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Println(args...)
|
|
|
}
|
|
|
|
|
|
// Panic 记录日志,然后panic
|
|
|
func (lr *LogRusLog) Panic(ctx context.Context, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Panic(args...)
|
|
|
}
|
|
|
|
|
|
// Panicf 记录日志,然后panic
|
|
|
func (lr *LogRusLog) Panicf(ctx context.Context, format string, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Panicf(format, args...)
|
|
|
}
|
|
|
|
|
|
// Fatal 有致命性错误,导致程序崩溃,记录日志,然后退出
|
|
|
func (lr *LogRusLog) Fatal(ctx context.Context, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Fatal(args...)
|
|
|
}
|
|
|
|
|
|
// Fatalf 有致命性错误,导致程序崩溃,记录日志,然后退出
|
|
|
func (lr *LogRusLog) Fatalf(ctx context.Context, format string, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Fatalf(format, args...)
|
|
|
}
|
|
|
|
|
|
// Error 错误日志
|
|
|
func (lr *LogRusLog) Error(ctx context.Context, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Error(args...)
|
|
|
}
|
|
|
|
|
|
// Errorf 错误日志
|
|
|
func (lr *LogRusLog) Errorf(ctx context.Context, format string, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Errorf(format, args...)
|
|
|
}
|
|
|
|
|
|
// Warn 警告日志
|
|
|
func (lr *LogRusLog) Warn(ctx context.Context, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Warn(args...)
|
|
|
}
|
|
|
|
|
|
// Warnf 警告日志
|
|
|
func (lr *LogRusLog) Warnf(ctx context.Context, format string, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Warnf(format, args...)
|
|
|
}
|
|
|
|
|
|
// Info 核心流程日志
|
|
|
func (lr *LogRusLog) Info(ctx context.Context, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Info(args...)
|
|
|
}
|
|
|
|
|
|
// Infof 核心流程日志
|
|
|
func (lr *LogRusLog) Infof(ctx context.Context, format string, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Infof(format, args...)
|
|
|
}
|
|
|
|
|
|
// Debug debug日志(调试日志)
|
|
|
func (lr *LogRusLog) Debug(ctx context.Context, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Debug(args...)
|
|
|
}
|
|
|
|
|
|
// Debugf debug日志(调试日志)
|
|
|
func (lr *LogRusLog) Debugf(ctx context.Context, format string, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Debugf(format, args...)
|
|
|
}
|
|
|
|
|
|
// Trace 粒度超细的,一般情况下我们使用不上
|
|
|
func (lr *LogRusLog) Trace(ctx context.Context, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Debug(args...)
|
|
|
}
|
|
|
|
|
|
// Tracef 粒度超细的,一般情况下我们使用不上
|
|
|
func (lr *LogRusLog) Tracef(ctx context.Context, format string, args ...interface{}) {
|
|
|
lr.setOutPutFile()
|
|
|
lr.withTraceId(ctx)
|
|
|
lr.entry.Tracef(format, args...)
|
|
|
}
|
|
|
|
|
|
// https://www.fushengwushi.com/archives/1397
|
|
|
// https://blog.csdn.net/oscarun/article/details/114295955
|
|
|
// https://juejin.cn/post/6974353191974469668
|
|
|
func (lr *LogRusLog) setOutPutFile() {
|
|
|
|
|
|
// 是否保存到文件
|
|
|
if lr.config.LogPath == "" {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 判断文件夹
|
|
|
if _, err := os.Stat(lr.config.LogPath); os.IsNotExist(err) {
|
|
|
err = os.MkdirAll(lr.config.LogPath, 0777)
|
|
|
if err != nil {
|
|
|
panic(fmt.Errorf("create log dir '%s' error: %s", lr.config.LogPath, err))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 日志名
|
|
|
fileName := path.Join(lr.config.LogPath, "logrus."+gotime.Current().SetFormat(gotime.ShortDateFormat)+".log")
|
|
|
|
|
|
file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
|
|
|
|
|
// 是否同时输出到控制台
|
|
|
if lr.config.LogInConsole {
|
|
|
lr.logger.SetOutput(os.Stdout)
|
|
|
writers := []io.Writer{
|
|
|
file,
|
|
|
os.Stdout,
|
|
|
}
|
|
|
fileAndStdoutWriter := io.MultiWriter(writers...)
|
|
|
if err == nil {
|
|
|
lr.logger.SetOutput(fileAndStdoutWriter)
|
|
|
} else {
|
|
|
log.Printf("无法记录到文件 %s\n", fileName)
|
|
|
}
|
|
|
} else {
|
|
|
lr.logger.SetOutput(file)
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|