|
@@ -9,21 +9,15 @@ import (
|
|
|
"sync"
|
|
|
)
|
|
|
|
|
|
-// 默认配置,准备了控制台、json文件两种输出方式
|
|
|
-var consoleEncoder zapcore.Encoder
|
|
|
-var jsonEncoder zapcore.Encoder
|
|
|
-var consoleSync zapcore.WriteSyncer
|
|
|
-var outputSync zapcore.WriteSyncer
|
|
|
-
|
|
|
-type outFileConfig struct {
|
|
|
- filename string
|
|
|
- maxSize int
|
|
|
- maxAge int
|
|
|
- maxBackups int
|
|
|
- localTime bool
|
|
|
- Compress bool
|
|
|
-}
|
|
|
-
|
|
|
+// Logger 是对 zap.SugaredLogger 的封装,简化其对外使用的接口,
|
|
|
+// 并且针对于 Logger 所有配置都是支持运行时动态修改,且并发安全。
|
|
|
+// Logger 也支持了针对于 zapcore.Core 的扩展,调用 Logger.AddCore 即可,
|
|
|
+//
|
|
|
+// 构建该对象请使用 New 进行创建,在该操作中会对部分必要属性进行初始化,
|
|
|
+// 直接使用结构体创建会导致结构体不可用(甚至panic)。
|
|
|
+//
|
|
|
+// 如非深度定制化扩展,非必要不建议使用 Logger.AddCore 进行扩展,该操作会
|
|
|
+// 导致客户端应用程序对zap包编译依赖,不保证fslog切换内部日志实现。
|
|
|
type Logger struct {
|
|
|
// 互斥量
|
|
|
// 用于内部不可并发逻辑使用
|
|
@@ -37,22 +31,14 @@ type Logger struct {
|
|
|
// 内部使用乐观锁,协程安全
|
|
|
lv zap.AtomicLevel
|
|
|
|
|
|
- // zapcore.Core 映射,存储不同来源/用途的core创建
|
|
|
- cores map[coreType][]CoreContext
|
|
|
+ // 所有的core
|
|
|
+ cores []zapcore.Core
|
|
|
}
|
|
|
|
|
|
-func NewLogger() *Logger {
|
|
|
+func New() *Logger {
|
|
|
logger := new(Logger)
|
|
|
logger.lv = zap.NewAtomicLevelAt(zap.DebugLevel)
|
|
|
- logger.setCore(console, CoreContext{
|
|
|
- Core: zapcore.NewCore(consoleEncoder, consoleSync, logger.lv),
|
|
|
- Writer: consoleSync,
|
|
|
- })
|
|
|
- logger.setCore(output, CoreContext{
|
|
|
- Core: zapcore.NewCore(jsonEncoder, outputSync, logger.lv),
|
|
|
- Writer: outputSync,
|
|
|
- })
|
|
|
- logger.flush()
|
|
|
+ logger.flushLogger()
|
|
|
return logger
|
|
|
}
|
|
|
|
|
@@ -153,7 +139,7 @@ func (l *Logger) NewFileOutput(opts ...FileOutputOpt) {
|
|
|
for _, opt := range opts {
|
|
|
opt(cfg)
|
|
|
}
|
|
|
- l.newOut(&lumberjack.Logger{
|
|
|
+ l.NewOutput(&lumberjack.Logger{
|
|
|
Filename: cfg.filename,
|
|
|
MaxSize: cfg.maxSize,
|
|
|
MaxAge: cfg.maxAge,
|
|
@@ -165,61 +151,43 @@ func (l *Logger) NewFileOutput(opts ...FileOutputOpt) {
|
|
|
|
|
|
// NewOutput 新增日志输出位置
|
|
|
func (l *Logger) NewOutput(writer io.Writer) {
|
|
|
- l.newOut(writer)
|
|
|
+ l.AddCore(zapcore.NewCore(jsonEncoder, zapcore.AddSync(writer), l.lv))
|
|
|
}
|
|
|
|
|
|
// AddCore 添加Core
|
|
|
-func (l *Logger) AddCore(core ...CoreContext) {
|
|
|
- l.setCore(third, core...)
|
|
|
- l.flush()
|
|
|
+func (l *Logger) AddCore(core ...zapcore.Core) {
|
|
|
+ l.addCoreOnly(core...)
|
|
|
+ l.flushLogger()
|
|
|
}
|
|
|
|
|
|
// Flush 将缓冲区日志刷新至目标
|
|
|
func (l *Logger) Flush() {
|
|
|
err := l.logger.Sync()
|
|
|
if err != nil {
|
|
|
- Warn("flush log error: %s", err.Error())
|
|
|
+ With("err", err.Error()).Warn("flushLogger log error")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// newOut 设置日志写出位置
|
|
|
-func (l *Logger) newOut(writer io.Writer) {
|
|
|
- l.setCore(output, CoreContext{
|
|
|
- Core: zapcore.NewCore(jsonEncoder, zapcore.AddSync(writer), l.lv),
|
|
|
- Writer: writer,
|
|
|
- })
|
|
|
- l.flush()
|
|
|
-}
|
|
|
-
|
|
|
// 保存内部core(不负责刷新 logger)
|
|
|
-func (l *Logger) setCore(ct coreType, core ...CoreContext) {
|
|
|
+func (l *Logger) addCoreOnly(core ...zapcore.Core) {
|
|
|
l.lock.Lock()
|
|
|
defer l.lock.Unlock()
|
|
|
- if l.cores == nil {
|
|
|
- l.cores = make(map[coreType][]CoreContext)
|
|
|
- }
|
|
|
- l.cores[ct] = append(l.cores[ct], core...)
|
|
|
+ l.cores = append(l.cores, core...)
|
|
|
+}
|
|
|
+
|
|
|
+func (l *Logger) clone() *Logger {
|
|
|
+ newL := &Logger{cores: l.cores, lv: l.lv}
|
|
|
+ newL.flushLogger()
|
|
|
+ return newL
|
|
|
}
|
|
|
|
|
|
// 刷新内部 logger
|
|
|
// 刷新互斥,触发刷新后,刷新完成前依旧按照旧的配置执行
|
|
|
-func (l *Logger) flush() {
|
|
|
+func (l *Logger) flushLogger() {
|
|
|
l.lock.Lock()
|
|
|
defer l.lock.Unlock()
|
|
|
-
|
|
|
- cores := make(coreContexts, 0, len(l.cores))
|
|
|
- for _, core := range l.cores {
|
|
|
- cores = append(cores, core...)
|
|
|
- }
|
|
|
-
|
|
|
l.logger = *zap.New(
|
|
|
- zapcore.NewTee(cores.Cores()...),
|
|
|
+ zapcore.NewTee(l.cores...),
|
|
|
zap.AddCaller(),
|
|
|
).Sugar()
|
|
|
}
|
|
|
-
|
|
|
-func (l *Logger) clone() *Logger {
|
|
|
- newL := &Logger{cores: l.cores, lv: l.lv}
|
|
|
- newL.flush()
|
|
|
- return newL
|
|
|
-}
|