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: 'info'Prefix: 'gin-vue-admin'Format: 'console'Director: 'logs'EncodeLevel: 'LowercaseColorLevelEncoder'StacktraceKey: 'stacktrace'MaxAge: 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,name=Zap,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,name=Level,proto3" json:"Level,omitempty"`// Prefix 日志前缀Prefix string `protobuf:"bytes,2,opt,name=Prefix,proto3" json:"Prefix,omitempty"`// Format 输出Format string `protobuf:"bytes,3,opt,name=Format,proto3" json:"Format,omitempty"`// Director 日志文件夹Director string `protobuf:"bytes,4,opt,name=Director,proto3" json:"Director,omitempty"`// EncodeLevel 编码级EncodeLevel string `protobuf:"bytes,5,opt,name=EncodeLevel,proto3" json:"EncodeLevel,omitempty"`// StacktraceKey 栈名StacktraceKey string `protobuf:"bytes,6,opt,name=StacktraceKey,proto3" json:"StacktraceKey,omitempty"`// MaxAge 日志留存时间MaxAge int64 `protobuf:"varint,7,opt,name=MaxAge,proto3" json:"MaxAge,omitempty"`// ShowLine 显示行ShowLine bool `protobuf:"varint,8,opt,name=ShowLine,proto3" json:"ShowLine,omitempty"`// LogInConsole 输出控制台LogInConsole bool `protobuf:"varint,9,opt,name=LogInConsole,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()
}

Go语音基于zap的日志封装相关推荐

  1. 【日志包】go语言如何设计日志包 - 基于zap封装适合自己的日志包

    文章目录 前言 一.自己设计log包的重要性 二.日志包的基本需求 1. 全局logger和传递参数的logger的用法 2. 日志包的基本需求 logger最基本的功能 3. 日志debug.inf ...

  2. 基于log4net的日志组件扩展封装,实现自动记录交互日志 XYH.Log4Net.Extend(微服务监控)...

    背景: 随着公司的项目不断的完善,功能越来越复杂,服务也越来越多(微服务),公司迫切需要对整个系统的每一个程序的运行情况进行监控,并且能够实现对自动记录不同服务间的程序调用的交互日志,以及通一个服务或 ...

  3. 基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil

    基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil,把日常能用到的各种CRUD都进行了简化封装,让普通程序员只需关注业务即可,因为非常简单,故直接贴源代码,大家若需使用可以直 ...

  4. 【Android 高性能音频】Oboe 开发流程 ( 创建并设置 AudioStreamCallback 对象 | 打开 Oboe 音频流 | 日志封装 logging_macros.h )

    文章目录 一.创建并设置 AudioStreamCallback 对象 二.打开 Oboe 音频流 三.日志封装 Oboe GitHub 主页 : GitHub/Oboe ① 简单使用 : Getti ...

  5. 基于SQL的日志分析工具myselect

    基本介绍 程序开发者常常要分析程序日志,包括自己打印的日志及使用的其他软件打印的日志,如php,nginx日志等,linux环境下分析日志有一些内置命令能够使用,如grep,sort,uniq,awk ...

  6. 动手造轮子:实现一个简单的基于 Console 的日志输出

    动手造轮子:实现一个简单的基于 Console 的日志输出 Intro 之前结合了微软的 Logging 框架和 Serilog 写了一个简单的日志框架,但是之前的用法都是基于 log4net.ser ...

  7. 给微软的日志框架写一个基于委托的日志提供者

    动手造轮子:给微软的日志框架写一个基于委托的日志提供者 Intro 微软的日志框架现在已经比较通用,有时候我们不想使用外部的日志提供者,但又希望提供一个比较简单的委托就可以实现日志记录,于是就有了后面 ...

  8. mysql 日志节点恢复_基于binlog二进制日志的MySQL恢复笔记

    基于binlog二进制日志的MySQL恢复笔记 刚好复习到这里,顺手做个小实验,记录下. 总的操作流程: step0.关掉数据库的对外访问[防止用户操作继续写入这个库] step1.mysqlbinl ...

  9. CentOS下ELK基于ElastAlert实现日志的微信报警

    转载来源 :ELK基于ElastAlert实现日志的微信报警 : https://www.jianshu.com/p/f31c0d6020fe 一.ElastAlert介绍 在日志管理上我们使用Ela ...

最新文章

  1. 题目1256:找出两个只出现了一次的数字
  2. 3.放弃CHAR吧,在铸成大错之前!
  3. Vivado2015.4使用教程(一个完成工程的建立)
  4. python电脑截图文字识别软件_Python实现文字识别,来看看大牛怎么实现截图/
  5. linux 笔记之一mysql源码包安装
  6. JQuery实现旅游导航菜单应用方便
  7. Python语言编程规范与优化建议
  8. MySQL_02之增删改查、PHP数据库操作
  9. SHEL脚本中调用另外一个脚本的函数和变量
  10. C语言RSA大数运算库,[转载]RSA大数运算库  c++实现
  11. 网络断网远程计算机会自动修复么,网络断网不怕,教你自己动手修复
  12. mysql 测试数据库employees导入
  13. 我来到广东第一“鬼城”,打算买房安家
  14. Macbook如何打开Chrome调试工具Developer Tools
  15. 卖铲子也是一种赚钱方式
  16. 网课视频禁止倍速和快进
  17. Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改
  18. Java的封装继承多态简介与实例
  19. 国际快递顺丰API接口接入教程代码示例
  20. windows script host是什么意思,windows based script host

热门文章

  1. 顺丰快递单号批量提取
  2. JavaWeb 项目 --- 博客系统(基于模板引擎)
  3. GD32F450ZIT6脉冲捕获会丢失脉冲的问题
  4. C语言中八进制和16进制怎么表示,原码,反码及补码,C语言按位取反运算符~
  5. 如何使用视频流媒体服务器支持HTML5直播?
  6. Berkeley DB介绍
  7. ryu安装遇到的问题
  8. 172. 立体推箱子
  9. 易订货专属App文档
  10. 10 模拟SPI驱动PS2无线手柄