苏州高端网站建设开发,政务网站无障碍建设,家具网站建设方案,创建全国文明城市标语zap日志封装
Zap是一个高性能、结构化日志库#xff0c;专为Go语言设计。它由Uber开源#xff0c;并且在Go社区中非常受欢迎。它的设计目标是提供一个简单易用、高效稳定、灵活可扩展的日志系统。 以下是Zap的一些主要特点#xff1a; 1.高性能#xff1a;Zap的性能非常出…zap日志封装
Zap是一个高性能、结构化日志库专为Go语言设计。它由Uber开源并且在Go社区中非常受欢迎。它的设计目标是提供一个简单易用、高效稳定、灵活可扩展的日志系统。 以下是Zap的一些主要特点 1.高性能Zap的性能非常出色可以在不影响应用程序性能的情况下记录大量的日志。它的性能比其他Go语言的日志库高出数倍这使得它成为高负载生产环境中的不错选择。 2.结构化日志Zap支持结构化日志这意味着你可以在日志中包含结构化数据而不是只是简单的文本。这个功能非常有用因为它可以让你更容易地对日志进行分析和搜索。 3.可扩展Zap提供了一个灵活的接口可以让你轻松地添加自定义的日志输出器和格式化器。这使得它非常适合在大型项目中使用。 4.模块化Zap提供了一个模块化的设计可以让你选择仅使用你需要的功能。这使得它非常适合在不同的项目中使用因为你可以只使用你需要的功能而不必使用整个库。 5.安全Zap使用了一个严格的日志记录器接口这可以确保你的应用程序的日志记录不会被恶意软件篡改或删除。 实现方式
yaml配置文件
在根目录下创建一个configs文件夹然后再创建zap.debug.yaml
# zap logger configuration
Zap:Level: infoPrefix: gin-vue-adminFormat: consoleDirector: logsEncodeLevel: LowercaseColorLevelEncoderStacktraceKey: stacktraceMaxAge: 30 # 默认日志留存默认以天为单位ShowLine: trueLogInConsole: true放置在全局Config中 config.go
我的创建是使用protobuf快速创建出来的如果你不是使用protobuf你可以忽略这个tag。在根目录下创建一个config文件然后创建一个config.go 文件用来存放全局的config。
config.go 文件
type Config struct {state protoimpl.MessageStatesizeCache protoimpl.SizeCacheunknownFields protoimpl.UnknownFieldsZap *Zap protobuf:bytes,2,opt,nameZap,proto3 json:Zap,omitempty}// Zap zap logger config
type Zap struct {state protoimpl.MessageStatesizeCache protoimpl.SizeCacheunknownFields protoimpl.UnknownFields// Level 级别Level string protobuf:bytes,1,opt,nameLevel,proto3 json:Level,omitempty// Prefix 日志前缀Prefix string protobuf:bytes,2,opt,namePrefix,proto3 json:Prefix,omitempty// Format 输出Format string protobuf:bytes,3,opt,nameFormat,proto3 json:Format,omitempty// Director 日志文件夹Director string protobuf:bytes,4,opt,nameDirector,proto3 json:Director,omitempty// EncodeLevel 编码级EncodeLevel string protobuf:bytes,5,opt,nameEncodeLevel,proto3 json:EncodeLevel,omitempty// StacktraceKey 栈名StacktraceKey string protobuf:bytes,6,opt,nameStacktraceKey,proto3 json:StacktraceKey,omitempty// MaxAge 日志留存时间MaxAge int64 protobuf:varint,7,opt,nameMaxAge,proto3 json:MaxAge,omitempty// ShowLine 显示行ShowLine bool protobuf:varint,8,opt,nameShowLine,proto3 json:ShowLine,omitempty// LogInConsole 输出控制台LogInConsole bool protobuf:varint,9,opt,nameLogInConsole,proto3 json:LogInConsole,omitempty
}创建zap.go
然后再config文件夹再创建zap.go文件该文件主要是用来将我们配置文件的内容转换成为zap所认识的内容。
type LevelEncoder int// ZapEncodeLevel 根据 EncodeLevel 返回 zapcore.LevelEncoder
func (x *Zap) ZapEncodeLevel() zapcore.LevelEncoder {switch {case x.EncodeLevel LowercaseLevelEncoder: // 小写编码器(默认)return zapcore.LowercaseLevelEncodercase x.EncodeLevel LowercaseColorLevelEncoder: // 小写编码器带颜色return zapcore.LowercaseColorLevelEncodercase x.EncodeLevel CapitalLevelEncoder: // 大写编码器return zapcore.CapitalLevelEncodercase x.EncodeLevel CapitalColorLevelEncoder: // 大写编码器带颜色return zapcore.CapitalColorLevelEncoderdefault:return zapcore.LowercaseLevelEncoder}
}// TransportLevel 根据字符串转化为 zapcore.Level
func (x *Zap) TransportLevel() zapcore.Level {x.Level strings.ToLower(x.Level)switch x.Level {case debug:return zapcore.DebugLevelcase info:return zapcore.InfoLevelcase warn:return zapcore.WarnLevelcase error:return zapcore.WarnLevelcase dpanic:return zapcore.DPanicLevelcase panic:return zapcore.PanicLevelcase fatal:return zapcore.FatalLeveldefault:return zapcore.DebugLevel}
}
创建核心文件core
这里我主要放置一些Initialization 初始化的方法比如gorm、viper、zap等一些核心的内容。
创建zap.go
在core文件中创建zap.go 文件该文件主要是初始化自己配置的zap日志一般会把日志分割、日志存放地、注册到全局等放置在这里当然为了让代码更加整洁和可阅读性下我们会对这里封装成为方法。注: _zap 命名方式是因为和zap包重名了可以根据自己喜好命名但是这样的命明也就是仅在该文件下生效你可以认为这样变成了所谓的私有性
core/zap.go
var Zap new(_zap)type _zap struct{}// Initialization 初始化
func (c *_zap) Initialization() {ok, _ : utils.Directory.PathExists(global.Config.Zap.Director)if !ok { // 判断是否有 global.Config.Zap.Director 文件夹fmt.Printf(create %v directory\n, global.Config.Zap.Director)_ os.Mkdir(global.Config.Zap.Director, os.ModePerm)}cores : internal.Zap.GetZapCores() // 获取 zap 核心切片logger : zap.New(zapcore.NewTee(cores...)) // 初始化 zap.Loggerif global.Config.Zap.ShowLine { // 判断是否显示行logger logger.WithOptions(zap.AddCaller())}zap.ReplaceGlobals(logger) // logger 注册到全局, 通过 zap.L() 调用日志组件
}
创建私有访问方法
在core文件夹下创建interal文件中这个internal的方法仅能在这个core下的文件才可以进行访问其他文件夹比如service、api、util等文件夹无法访问这样使得这些方法不会泄漏导致程序结构的污染性我个人也比较喜欢这样去命名以及去写代码。注下列写法core/interal/zap.go 但是我们调取interal文件夹的方法不需要通过core去调取直接使用interal进行访问。
core/interal/zap.go var Zap new(_zap)type _zap struct{}// GetEncoder 获取 zapcore.Encoder
func (z *_zap) GetEncoder() zapcore.Encoder {// 日志的内容格式有 控制台 和 jsonif global.Config.Zap.Format json {return zapcore.NewJSONEncoder(z.GetEncoderConfig())}return zapcore.NewConsoleEncoder(z.GetEncoderConfig())
}// GetEncoderConfig 获取zapcore.EncoderConfig
func (z *_zap) GetEncoderConfig() zapcore.EncoderConfig {return zapcore.EncoderConfig{MessageKey: message,LevelKey: level,TimeKey: time,NameKey: logger,CallerKey: caller,StacktraceKey: global.Config.Zap.StacktraceKey,LineEnding: zapcore.DefaultLineEnding,EncodeLevel: global.Config.Zap.ZapEncodeLevel(),EncodeTime: z.CustomTimeEncoder,EncodeDuration: zapcore.SecondsDurationEncoder,EncodeCaller: zapcore.FullCallerEncoder,}
}// GetEncoderCore 获取Encoder的 zapcore.Core
func (z *_zap) GetEncoderCore(l zapcore.Level, level zap.LevelEnablerFunc) zapcore.Core {syncer, err : FileRotatelogs.GetWriteSyncer(l.String()) // 使用file-rotatelogs进行日志分割if err ! nil {fmt.Printf(Get Write Syncer Failed err:%v, err.Error())return nil}return zapcore.NewCore(z.GetEncoder(), syncer, level)
}// CustomTimeEncoder 自定义日志输出时间格式
func (z *_zap) CustomTimeEncoder(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {encoder.AppendString(global.Config.Zap.Prefix t.Format(2006-01-02 15:04:05.000))
}// GetZapCores 根据配置文件的Level获取 []zapcore.Corefunc (z *_zap) GetZapCores() []zapcore.Core {cores : make([]zapcore.Core, 0, 7)for level : global.Config.Zap.TransportLevel(); level zapcore.FatalLevel; level {cores append(cores, z.GetEncoderCore(level, z.GetLevelPriority(level)))}return cores
}// GetLevelPriority 根据 zapcore.Level 获取 zap.LevelEnablerFunc
func (z *_zap) GetLevelPriority(level zapcore.Level) zap.LevelEnablerFunc {switch level {case zapcore.DebugLevel:return func(level zapcore.Level) bool { // 调试级别return level zap.DebugLevel}case zapcore.InfoLevel:return func(level zapcore.Level) bool { // 日志级别return level zap.InfoLevel}case zapcore.WarnLevel:return func(level zapcore.Level) bool { // 警告级别return level zap.WarnLevel}case zapcore.ErrorLevel:return func(level zapcore.Level) bool { // 错误级别return level zap.ErrorLevel}case zapcore.DPanicLevel:return func(level zapcore.Level) bool { // dpanic级别return level zap.DPanicLevel}case zapcore.PanicLevel:return func(level zapcore.Level) bool { // panic级别return level zap.PanicLevel}case zapcore.FatalLevel:return func(level zapcore.Level) bool { // 终止级别return level zap.FatalLevel}default:return func(level zapcore.Level) bool { // 调试级别return level zap.DebugLevel}}
}
在main中注册
在根目录下创建一个main.go文件(这个就不多啰嗦了…)
main.go
func main() {core.Zap.Initialization()
}