init
This commit is contained in:
commit
2a9d1efba1
|
@ -0,0 +1,14 @@
|
||||||
|
module logging
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require (
|
||||||
|
go.uber.org/zap v1.21.0
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/BurntSushi/toml v1.1.0 // indirect
|
||||||
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
|
)
|
|
@ -0,0 +1,266 @@
|
||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ModOptions func(options *Options)
|
||||||
|
|
||||||
|
// Options 日志文件配置选项
|
||||||
|
type Options struct {
|
||||||
|
Path string // 文件保存地方
|
||||||
|
Prefix string // 日志文件前缀
|
||||||
|
ErrorFileSuffix string // error日志文件后缀
|
||||||
|
WarnFileSuffix string // warn日志文件后缀
|
||||||
|
InfoFileSuffix string // info日志文件后缀
|
||||||
|
DebugFileSuffix string // debug日志文件后缀
|
||||||
|
Level zapcore.Level // 日志等级
|
||||||
|
MaxSize int // 日志文件大小(M)
|
||||||
|
MaxBackups int // 最多存在多少个切片文件
|
||||||
|
MaxAge int // 保存的最大天数
|
||||||
|
Development bool // 是否是开发模式
|
||||||
|
zap.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
logger *Logger
|
||||||
|
sp = string(filepath.Separator)
|
||||||
|
errWS, warnWS, infoWS, debugWS zapcore.WriteSyncer // IO输出
|
||||||
|
debugConsoleWS = zapcore.Lock(os.Stdout) // 控制台标准输出
|
||||||
|
errorConsoleWS = zapcore.Lock(os.Stderr)
|
||||||
|
)
|
||||||
|
|
||||||
|
type Logger struct {
|
||||||
|
*zap.Logger
|
||||||
|
sync.RWMutex
|
||||||
|
Opts *Options `json:"opts"`
|
||||||
|
zapConfig zap.Config
|
||||||
|
initialized bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogger(mod ...ModOptions) *zap.Logger {
|
||||||
|
logger = &Logger{}
|
||||||
|
logger.Lock()
|
||||||
|
defer logger.Unlock()
|
||||||
|
if logger.initialized {
|
||||||
|
logger.Info("[NewLogger] logger initEd")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
logger.Opts = &Options{
|
||||||
|
Path: "",
|
||||||
|
Prefix: "app",
|
||||||
|
ErrorFileSuffix: "error.log",
|
||||||
|
WarnFileSuffix: "warn.log",
|
||||||
|
InfoFileSuffix: "info.log",
|
||||||
|
DebugFileSuffix: "debug.log",
|
||||||
|
Level: zapcore.DebugLevel,
|
||||||
|
MaxSize: 100,
|
||||||
|
MaxBackups: 60,
|
||||||
|
MaxAge: 30,
|
||||||
|
}
|
||||||
|
|
||||||
|
if logger.Opts.Path == "" {
|
||||||
|
logger.Opts.Path, _ = filepath.Abs(filepath.Dir(filepath.Join(".")))
|
||||||
|
logger.Opts.Path += sp + "logs" + sp
|
||||||
|
}
|
||||||
|
if logger.Opts.Development {
|
||||||
|
logger.zapConfig = zap.NewDevelopmentConfig()
|
||||||
|
logger.zapConfig.EncoderConfig.EncodeTime = timeEncoder
|
||||||
|
} else {
|
||||||
|
logger.zapConfig = zap.NewProductionConfig()
|
||||||
|
logger.zapConfig.EncoderConfig.EncodeTime = timeEncoder
|
||||||
|
}
|
||||||
|
if logger.Opts.OutputPaths == nil || len(logger.Opts.OutputPaths) == 0 {
|
||||||
|
logger.zapConfig.OutputPaths = []string{"stdout"}
|
||||||
|
}
|
||||||
|
if logger.Opts.ErrorOutputPaths == nil || len(logger.Opts.ErrorOutputPaths) == 0 {
|
||||||
|
logger.zapConfig.OutputPaths = []string{"stderr"}
|
||||||
|
}
|
||||||
|
for _, fn := range mod {
|
||||||
|
fn(logger.Opts)
|
||||||
|
}
|
||||||
|
logger.zapConfig.Level.SetLevel(logger.Opts.Level)
|
||||||
|
logger.init()
|
||||||
|
logger.initialized = true
|
||||||
|
return logger.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) init() {
|
||||||
|
logger.setSyncs()
|
||||||
|
var err error
|
||||||
|
logger.Logger, err = logger.zapConfig.Build(logger.cores())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer logger.Logger.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) setSyncs() {
|
||||||
|
f := func(fN string) zapcore.WriteSyncer {
|
||||||
|
return zapcore.AddSync(&lumberjack.Logger{
|
||||||
|
Filename: logger.Opts.Path + sp + logger.Opts.Prefix + "-" + fN,
|
||||||
|
MaxSize: logger.Opts.MaxSize,
|
||||||
|
MaxBackups: logger.Opts.MaxBackups,
|
||||||
|
MaxAge: logger.Opts.MaxAge,
|
||||||
|
Compress: true,
|
||||||
|
LocalTime: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
errWS = f(logger.Opts.ErrorFileSuffix)
|
||||||
|
warnWS = f(logger.Opts.WarnFileSuffix)
|
||||||
|
infoWS = f(logger.Opts.InfoFileSuffix)
|
||||||
|
debugWS = f(logger.Opts.DebugFileSuffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetMaxSize(MaxSize int) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.MaxSize = MaxSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetMaxBackups(MaxBackups int) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.MaxBackups = MaxBackups
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetMaxAge(MaxAge int) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.MaxAge = MaxAge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetPath(Path string) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.Path = Path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetPrefix(Prefix string) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.Prefix = Prefix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLevel(Level zapcore.Level) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.Level = Level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetErrorFileSuffix(ErrorFileSuffix string) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.ErrorFileSuffix = ErrorFileSuffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetWarnFileSuffix(WarnFileSuffix string) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.WarnFileSuffix = WarnFileSuffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetInfoFileSuffix(InfoFileSuffix string) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.InfoFileSuffix = InfoFileSuffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDebugFileSuffix(DebugFileSuffix string) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.DebugFileSuffix = DebugFileSuffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDevelopment(Development bool) ModOptions {
|
||||||
|
return func(option *Options) {
|
||||||
|
option.Development = Development
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDefaultLogger returns the default logger.
|
||||||
|
func getDefaultLogger() *Logger {
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// L returns the default logger.
|
||||||
|
func L() *Logger {
|
||||||
|
return getDefaultLogger()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *Logger) cores() zap.Option {
|
||||||
|
fileEncoder := zapcore.NewJSONEncoder(logger.zapConfig.EncoderConfig)
|
||||||
|
encoderConfig := zap.NewDevelopmentEncoderConfig()
|
||||||
|
encoderConfig.EncodeTime = timeEncoder
|
||||||
|
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
||||||
|
consoleEncoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
|
||||||
|
TimeKey: "ts",
|
||||||
|
LevelKey: "level",
|
||||||
|
NameKey: "logger",
|
||||||
|
CallerKey: "caller_line",
|
||||||
|
FunctionKey: zapcore.OmitKey,
|
||||||
|
MessageKey: "msg",
|
||||||
|
StacktraceKey: "stacktrace",
|
||||||
|
LineEnding: " ",
|
||||||
|
EncodeLevel: encodeLevel,
|
||||||
|
EncodeTime: encodeTime,
|
||||||
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
||||||
|
EncodeCaller: encodeCaller,
|
||||||
|
})
|
||||||
|
|
||||||
|
errPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
|
||||||
|
return lvl == zapcore.ErrorLevel && zapcore.ErrorLevel-logger.zapConfig.Level.Level() > -1
|
||||||
|
})
|
||||||
|
warnPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
|
||||||
|
return lvl == zapcore.WarnLevel && zapcore.WarnLevel-logger.zapConfig.Level.Level() > -1
|
||||||
|
})
|
||||||
|
infoPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
|
||||||
|
return lvl == zapcore.InfoLevel && zapcore.InfoLevel-logger.zapConfig.Level.Level() > -1
|
||||||
|
})
|
||||||
|
debugPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
|
||||||
|
return lvl == zapcore.DebugLevel && zapcore.DebugLevel-logger.zapConfig.Level.Level() > -1
|
||||||
|
})
|
||||||
|
cores := []zapcore.Core{
|
||||||
|
zapcore.NewCore(fileEncoder, errWS, errPriority),
|
||||||
|
zapcore.NewCore(fileEncoder, warnWS, warnPriority),
|
||||||
|
zapcore.NewCore(fileEncoder, infoWS, infoPriority),
|
||||||
|
zapcore.NewCore(fileEncoder, debugWS, debugPriority),
|
||||||
|
}
|
||||||
|
if logger.Opts.Development {
|
||||||
|
cores = append(cores, []zapcore.Core{
|
||||||
|
zapcore.NewCore(consoleEncoder, errorConsoleWS, errPriority),
|
||||||
|
zapcore.NewCore(consoleEncoder, debugConsoleWS, warnPriority),
|
||||||
|
zapcore.NewCore(consoleEncoder, debugConsoleWS, infoPriority),
|
||||||
|
zapcore.NewCore(consoleEncoder, debugConsoleWS, debugPriority),
|
||||||
|
}...)
|
||||||
|
}
|
||||||
|
return zap.WrapCore(func(c zapcore.Core) zapcore.Core {
|
||||||
|
return zapcore.NewTee(cores...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||||
|
enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeLevel 自定义日志级别显示
|
||||||
|
func encodeLevel(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
|
||||||
|
enc.AppendString("[" + level.CapitalString() + "]")
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeTime 自定义时间格式显示
|
||||||
|
func encodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||||
|
enc.AppendString("[" + t.Format("2006-01-02 15:04:05.000") + "]")
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeCaller 自定义行号显示
|
||||||
|
func encodeCaller(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
|
||||||
|
enc.AppendString("[" + caller.TrimmedPath() + "]")
|
||||||
|
}
|
Loading…
Reference in New Issue