zap日志库的Option可以用来增强日志记录器,我们看看它的设计:
1 | type Option interface { |
Option被设计成了内部接口:只有包内部才能定义接口实现,它有一个接受一个日志记录器参数的apply方法。
zap的设计者在接口包内又利用了go的方法类型来实现了这个接口:1
2
3
4
5type optionFunc func(*Logger)
func (f optionFunc) apply(log *Logger) {
f(log)
}
zap包装或者替换Core的Option就利用了这个optionFunc:1
2
3
4
5
6
7func WrapCore(f func(zapcore.Core) zapcore.Core) Option {
return optionFunc(func(log *Logger) {
//
log.core = f(log.core)
})
}
此方法体现了Go语言方法的精妙之处,传入的方法参数通过闭包让外部在合适的时候再调用。
我们来看下WrapCore的使用示例:1
2
3
4
5
6
7
8
9
10
11
12
13nop := zap.WrapCore(func(zapcore.Core) zapcore.Core {
return zapcore.NewNopCore()
})
logger := zap.NewExample()
defer logger.Sync()
logger.Info("working")
//没有任何操作,不会输出日志
logger.WithOptions(nop).Info("no-op")
//不会影响原来的日志输出
logger.Info("original logger still works")
最终只输出了如下两条日志:
{“level”:”info”,”msg”:”working”}
{“level”:”info”,”msg”:”original logger still works”}
也就是说logger可以加上WrapCore这个Option替换了原来的日志输出策略。