zap日志库 自定义CallerEncoder 方法, 同时适用于其他几个Encoder如 LevelEncoder,TimeEncoder,NameEncoder,DurationEncoder等

在zap日志库中,zapcore给我们提供了2种CallEncoder, 即  zapcore.FullCallerEncoder  和 zapcore.ShortCallerEncoder  但是这2种都不符合我们的要求:

原有方式的不足

zapcore.FullCallerEncoder 将每个caller的完整路径都进行了记录,从而导致大量的重复的路径记录在日志中,主要是当前项目的完整路径。

而zapcore.ShortCallerEncoder这个方式都所有的caller都只记录简短的路径, 这样导致我们很多的路径无法进行快速定位。

要求:我们希望对于当前项目的caller, 我们只记录相对路径即可,其他记录完整路径。

对于这个需求,我们就只能通过自定义的方式来完成。 要自定义,我们需要首先了解一下这个 EncoderConfig配置信息。

EncoderConfig参考


// An EncoderConfig allows users to configure the concrete encoders supplied by
// zapcore.
type EncoderConfig struct {
	// Set the keys used for each log entry. If any key is empty, that portion
	// of the entry is omitted.
	MessageKey     string `json:"messageKey" yaml:"messageKey"`
	LevelKey       string `json:"levelKey" yaml:"levelKey"`
	TimeKey        string `json:"timeKey" yaml:"timeKey"`
	NameKey        string `json:"nameKey" yaml:"nameKey"`
	CallerKey      string `json:"callerKey" yaml:"callerKey"`
	FunctionKey    string `json:"functionKey" yaml:"functionKey"`
	StacktraceKey  string `json:"stacktraceKey" yaml:"stacktraceKey"`
	SkipLineEnding bool   `json:"skipLineEnding" yaml:"skipLineEnding"`
	LineEnding     string `json:"lineEnding" yaml:"lineEnding"`
	// Configure the primitive representations of common complex types. For
	// example, some users may want all time.Times serialized as floating-point
	// seconds since epoch, while others may prefer ISO8601 strings.
	EncodeLevel    LevelEncoder    `json:"levelEncoder" yaml:"levelEncoder"`
	EncodeTime     TimeEncoder     `json:"timeEncoder" yaml:"timeEncoder"`
	EncodeDuration DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"`
	EncodeCaller   CallerEncoder   `json:"callerEncoder" yaml:"callerEncoder"`
	// Unlike the other primitive type encoders, EncodeName is optional. The
	// zero value falls back to FullNameEncoder.
	EncodeName NameEncoder `json:"nameEncoder" yaml:"nameEncoder"`
	// Configure the encoder for interface{} type objects.
	// If not provided, objects are encoded using json.Encoder
	NewReflectedEncoder func(io.Writer) ReflectedEncoder `json:"-" yaml:"-"`
	// Configures the field separator used by the console encoder. Defaults
	// to tab.
	ConsoleSeparator string `json:"consoleSeparator" yaml:"consoleSeparator"`
}

自定义EncodeCaller

从上面的配置中我们可以得知, 这个EncodeCaller他实际上是一个函数定义 type CallerEncoder func(EntryCaller, PrimitiveArrayEncoder)   如下图所示:

我们要自定义这个EncodeCaller实际上就是定义这样一个函数即可。

定义方式如下:

即在我们初始化配置对象的时候对这个EncodeCaller定义一个函数即可,这样每次在zap执行的时候就会调用我们定义的这个函数。 即,如下示例

        EncodeCaller: func(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
			// 这里将路径的前缀即当前项目的路径去除 其他路径保持完整路径
			ctrimPaht := TrimAppPath(caller.FullPath())
			enc.AppendString(fmt.Sprintf("%v%v", c.Prefix, ctrimPaht))
		},

在这个函数里面我们就可以对这个Encoder进行自定义的操作了。

获取当前项目路径函数 GetAppPath


// 获取当前app的运行路径 如: /opt/app/gotms
func GetAppPath() string {
	var appPath string
	if exeFile, err := os.Executable();err==nil {
		appPath=filepath.Dir(exeFile)
	}else{
		appPath,_=os.Getwd()
	}
	return appPath
}

// 去除当前app的路径 如果包含, 否则原样返回
func TrimAppPath(inPath string) string {
	if path, ok := strings.CutPrefix(inPath, GetAppPath()); ok {
		return path
	}
	return inPath
}

总结: 这里的zap配置里面的Encoder自定义方法也适用于配置里面的其他几个Encoder, 他们二定义方式都是一样的, 如下图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值