115 lines
3.4 KiB
Go
115 lines
3.4 KiB
Go
package log
|
|
|
|
import (
|
|
"context"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/spf13/viper"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
"gopkg.in/natefinch/lumberjack.v2"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
const ctxLoggerKey = "zapLogger"
|
|
|
|
type Logger struct {
|
|
*zap.Logger
|
|
}
|
|
|
|
func NewLog(conf *viper.Viper) *Logger {
|
|
// log address "out.log" User-defined
|
|
lp := conf.GetString("log.log_file_name")
|
|
lv := conf.GetString("log.log_level")
|
|
var level zapcore.Level
|
|
//debug<info<warn<error<fatal<panic
|
|
switch lv {
|
|
case "debug":
|
|
level = zap.DebugLevel
|
|
case "info":
|
|
level = zap.InfoLevel
|
|
case "warn":
|
|
level = zap.WarnLevel
|
|
case "error":
|
|
level = zap.ErrorLevel
|
|
default:
|
|
level = zap.InfoLevel
|
|
}
|
|
hook := lumberjack.Logger{
|
|
Filename: lp, // Log file path
|
|
MaxSize: conf.GetInt("log.max_size"), // Maximum size unit for each log file: M
|
|
MaxBackups: conf.GetInt("log.max_backups"), // The maximum number of backups that can be saved for log files
|
|
MaxAge: conf.GetInt("log.max_age"), // Maximum number of days the file can be saved
|
|
Compress: conf.GetBool("log.compress"), // Compression or not
|
|
}
|
|
|
|
var encoder zapcore.Encoder
|
|
if conf.GetString("log.encoding") == "console" {
|
|
encoder = zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
|
|
TimeKey: "ts",
|
|
LevelKey: "level",
|
|
NameKey: "Logger",
|
|
CallerKey: "caller",
|
|
MessageKey: "msg",
|
|
StacktraceKey: "stacktrace",
|
|
LineEnding: zapcore.DefaultLineEnding,
|
|
EncodeLevel: zapcore.LowercaseColorLevelEncoder,
|
|
EncodeTime: timeEncoder,
|
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
EncodeCaller: zapcore.FullCallerEncoder,
|
|
})
|
|
} else {
|
|
encoder = zapcore.NewJSONEncoder(zapcore.EncoderConfig{
|
|
TimeKey: "ts",
|
|
LevelKey: "level",
|
|
NameKey: "logger",
|
|
CallerKey: "caller",
|
|
FunctionKey: zapcore.OmitKey,
|
|
MessageKey: "msg",
|
|
StacktraceKey: "stacktrace",
|
|
LineEnding: zapcore.DefaultLineEnding,
|
|
EncodeLevel: zapcore.LowercaseLevelEncoder,
|
|
EncodeTime: zapcore.EpochTimeEncoder,
|
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
EncodeCaller: zapcore.ShortCallerEncoder,
|
|
})
|
|
}
|
|
core := zapcore.NewCore(
|
|
encoder,
|
|
zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // Print to console and file
|
|
level,
|
|
)
|
|
if conf.GetString("env") != "prod" {
|
|
return &Logger{zap.New(core, zap.Development(), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
|
|
}
|
|
return &Logger{zap.New(core, zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
|
|
}
|
|
|
|
func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
|
//enc.AppendString(t.Format("2006-01-02 15:04:05"))
|
|
enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
|
|
}
|
|
|
|
// WithValue Adds a field to the specified context
|
|
func (l *Logger) WithValue(ctx context.Context, fields ...zapcore.Field) context.Context {
|
|
if c, ok := ctx.(*gin.Context); ok {
|
|
ctx = c.Request.Context()
|
|
c.Request = c.Request.WithContext(context.WithValue(ctx, ctxLoggerKey, l.WithContext(ctx).With(fields...)))
|
|
return c
|
|
}
|
|
return context.WithValue(ctx, ctxLoggerKey, l.WithContext(ctx).With(fields...))
|
|
}
|
|
|
|
// WithContext Returns a zap instance from the specified context
|
|
func (l *Logger) WithContext(ctx context.Context) *Logger {
|
|
if c, ok := ctx.(*gin.Context); ok {
|
|
ctx = c.Request.Context()
|
|
}
|
|
zl := ctx.Value(ctxLoggerKey)
|
|
ctxLogger, ok := zl.(*zap.Logger)
|
|
if ok {
|
|
return &Logger{ctxLogger}
|
|
}
|
|
return l
|
|
}
|