一、zap介绍

在许多Go语言项目中,我们需要一个好的日志记录器能够提供下面这些功能:

1.能够将事件记录到文件中,而不是应用程序控制台。
2.日志切割-能够根据文件大小、时间或间隔等来切割日志文件。
3.支持不同的日志级别。例如INFO,DEBUG,ERROR等。
4.能够打印基本信息,如调用文件/函数名和行号,日志时间等。

二、安装及使用

2.1 安装

go get -u go.uber.org/zap

2.2 配置logger日志记录器

Zap提供了两种类型的日志记录器—Sugared Logger和Logger,一般使用Logger 。

2.2.1 初始化Logger

func InitLogger() *zap.Logger{
logger ,_ := zap.NewProduction() return logger
}

2.2.2 初始化SugaredLogger

//在Logger基础上调用logger.Suger()
func InitLogger() *zap.SugaredLogger{
logger ,_ := zap.NewProduction() return logger.Sugar()
}

而初始化logger调用的函数可以通过调用zap.NewProduction()/zap.NewDevelopment()或者zap.Example()创建一个Logger。区别就是一个是以json的格式返回,一个是以终端标准输出带有空格返回。

NewProducts()

NewDevelopment()

2.3 使用logger进行日志记录

使用logger的自带的方法进行日志记录,logger.info(),logger.error().logger.debug等等

这些方法的语法都是

func (log *Logger) MethodXXX(msg string, fields ...Field)
例如:
logger.info(
"msg",
zap.String("msg",v),
zap.Error(err), )

完整代码

点击查看代码
package main

import (
"net/http" "go.uber.org/zap"
) var Logger *zap.SugaredLogger
func main() {
//初始化zap日志记录器
Logger = InitLogger()
defer Logger.Sync()
//模拟义务
Simplefunc("http://www.baidu.com")
Simplefunc("www.google.com") }
func InitLogger() *zap.SugaredLogger{
logger ,_ := zap.NewDevelopment() return logger.Sugar()
} func Simplefunc(url string) {
res,err:=http.Get(url)
if err!=nil {
//记录错误日志
Logger.Error(
"http get failed..",
zap.String("url:",url),
zap.Error(err),
)
}else {
//使用info记录成功日志。
Logger.Info(
"get success",
zap.String("status:",res.Status),
zap.String("url:",url),
)
res.Body.Close()
} }

2.4 自定义logger记录器

2.4.1 将日志写入文件而不是终端

上述的官方提供的logger生成功能不是那么强大,项目需要将日志记录到文件和分割 的时候就需要自定义。

zap自定义logger生成器使用zap.New():

func New(core zapcore.Core, options ...Option) *Logger

其中zapcore.Core需要设置三个参数Encoder,WriteSyncer,LogLevel

Encoder:编译器,通俗说就是输出日志是什么格式,json or 终端格式。

json格式就使用NewJSONEncoder(),并使用预先设置的ProductionEncoderConfig():
zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
终端格式就使用NewConsoleEncoder():
zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig())

WriteSyncer:将日志输出到哪。使用zapcore.AddSync()函数并且将打开的文件句柄传进去。

file, _ := os.Create("./test.log")
writeSyncer := zapcore.AddSync(file)

LogLevel:将什么样级别的日志输出.

代码实例:

点击查看代码
//使用自定义的zap logger
func InitLogger() *zap.SugaredLogger{
//日志文件
logfile, _ :=os.OpenFile("zap_log.log",os.O_APPEND | os.O_CREATE|os.O_RDWR,0666)
//编码器
encoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
//输出位置
writeSyncer := zapcore.AddSync(logfile) //定义core
core := zapcore.NewCore(
encoder,
writeSyncer,
zapcore.DebugLevel,
) //创建logger
logger:= zap.New(core) return logger.Sugar()
}

2.4.2 若输出到文件和终端,只需要更改WriteSyncer参数

点击查看代码
//使用自定义的zap logger
func InitLogger() *zap.SugaredLogger{
//日志文件
logfile, _ :=os.OpenFile("zap_log.log",os.O_APPEND | os.O_CREATE|os.O_RDWR,0666)
//编码器
encoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
//输出位置
// writeSyncer := zapcore.AddSync(logfile)
//输出多个位置
wc := io.MultiWriter(logfile,os.Stdout)
writeSyncer:= zapcore.AddSync(wc) //定义core
core := zapcore.NewCore(
encoder,
writeSyncer,
zapcore.DebugLevel,
) //创建logger
logger:= zap.New(core) return logger.Sugar()
}

效果:
![image](https://img2024.cnblogs.com/blog/3452880/202409/3452880-20240912221329852-1914127797.png)

2.4.3 将输出的时间转化

//设置日志编译器,什么类型的日志
func getEncoder() zapcore.Encoder{
//encoder配置
encoderConfig := zap.NewProductionEncoderConfig()
//设置时间格式为2024-9-1-12.32
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
//json格式
// jsonencoder := zapcore.NewJSONEncoder(encoderConfig) //终端形式
ConsoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
return ConsoleEncoder }

2.4.4 记录不同级别的日志

有时候日志可分为log.erro.log 记录错误级别日志,;log.success.log记录成功级别日志,zapcore.DebugLevel就全记录。

	core1 := zapcore.NewCore(
encoder,
writeSyncer,
zapcore.DebugLevel,//全记录
)
//错误日志
core2 := zapcore.NewCore(
encoder,
getwriteSyncer("log.err.log"),
zapcore.ErrorLevel,
)
c:=zapcore.NewTee(core1,core2)
logger:= zap.New(c,zap.AddCaller())
return logger.Sugar()

2.4.5 AddCaller详细记录调用的代码行,AddCallerSkip(1)调用链很多时直接跳过

logger:= zap.New(core,zap.AddCaller(), zap.AddCallerSkip(1))

3. 记录全日志,错误日志文件,同步终端,标准时间,记录代码位置的自定义logger代码

点击查看代码
//使用自定义的zap logger
func InitLogger() *zap.SugaredLogger{ //编码器
encoder := getEncoder()
//输出位置
writeSyncer:= getwriteSyncer("log_all.log") //定义core
core1 := zapcore.NewCore(
encoder,
writeSyncer,
zapcore.DebugLevel,//全记录
)
//错误日志
core2 := zapcore.NewCore(
encoder,
getwriteSyncer("log.err.log"),
zapcore.ErrorLevel,
) //创建单个logger
// logger:= zap.New(core1,zap.AddCaller(), zap.AddCallerSkip(1)) //AddCaller详细记录调用的代码行,AddCallerSkip(1)调用链很多时直接跳过
// return logger.Sugar() //创建双日志,全日志和错误日志
c:=zapcore.NewTee(core1,core2)
logger:= zap.New(c,zap.AddCaller())
return logger.Sugar()
} //设置日志编译器,什么类型的日志
func getEncoder() zapcore.Encoder{
//encoder配置
encoderConfig := zap.NewProductionEncoderConfig()
//设置时间格式为2024-9-1-12.32
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
//json格式
// jsonencoder := zapcore.NewJSONEncoder(encoderConfig) //终端形式
ConsoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
return ConsoleEncoder } //设置输出位置
func getwriteSyncer(logfilename string) zapcore.WriteSyncer {
//日志文件
logfile, _ :=os.OpenFile(logfilename,os.O_APPEND | os.O_CREATE|os.O_RDWR,0666) //只输出到日志文件
// return zapcore.AddSync(logfile) //也输出到终端
wc := io.MultiWriter(logfile,os.Stdout)
return zapcore.AddSync(wc)
}

[========]

[========]

4.使用Lumberjack进行日志切割归档

//设置输出位置
func getwriteSyncer(logfilename string) zapcore.WriteSyncer {
//日志文件
// logfile, _ :=os.OpenFile(logfilename,os.O_APPEND | os.O_CREATE|os.O_RDWR,0666) //分割日志 l, _ := rotatelogs.New(
logfilename+".%Y%m%d%H%M.log",
rotatelogs.WithMaxAge(30*24*time.Hour), // 最长保存30天
rotatelogs.WithRotationTime(time.Hour*24), // 24小时切割一次
) //也输出到终端
wc := io.MultiWriter(l,os.Stdout)
return zapcore.AddSync(wc)
}

5.上述完整代码

点击查看代码
package main

import (
"io"
"net/http"
"os"
"time"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
// "gopkg.in/natefinch/lumberjack.v2"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
) var Logger *zap.SugaredLogger
func main() {
//初始化zap日志记录器
Logger = InitLogger()
defer Logger.Sync()
//模拟义务
Simplefunc("http://www.baidu.com")
Simplefunc("http://www.google.com") }
//使用自定义的zap logger
func InitLogger() *zap.SugaredLogger{ //编码器
encoder := getEncoder()
//输出位置
writeSyncer:= getwriteSyncer("log_all") //定义core
core1 := zapcore.NewCore(
encoder,
writeSyncer,
zapcore.DebugLevel,//全记录
)
//错误日志
core2 := zapcore.NewCore(
encoder,
getwriteSyncer("log.err"),
zapcore.ErrorLevel,
) //创建单个logger
// logger:= zap.New(core1,zap.AddCaller(), zap.AddCallerSkip(1)) //AddCaller详细记录调用的代码行,AddCallerSkip(1)调用链很多时直接跳过
// return logger.Sugar() //创建双日志,全日志和错误日志
c:=zapcore.NewTee(core1,core2)
logger:= zap.New(c,zap.AddCaller())
return logger.Sugar()
} //设置日志编译器,什么类型的日志
func getEncoder() zapcore.Encoder{
//encoder配置
encoderConfig := zap.NewProductionEncoderConfig()
//设置时间格式为2024-9-1-12.32
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
//json格式
// jsonencoder := zapcore.NewJSONEncoder(encoderConfig) //终端形式
ConsoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
return ConsoleEncoder } //设置输出位置
func getwriteSyncer(logfilename string) zapcore.WriteSyncer {
//日志文件
// logfile, _ :=os.OpenFile(logfilename,os.O_APPEND | os.O_CREATE|os.O_RDWR,0666) //分割日志 l, _ := rotatelogs.New(
logfilename+".%Y%m%d%H%M.log",
rotatelogs.WithMaxAge(30*24*time.Hour), // 最长保存30天
rotatelogs.WithRotationTime(time.Hour*24), // 24小时切割一次
) //也输出到终端
wc := io.MultiWriter(l,os.Stdout)
return zapcore.AddSync(wc)
} func Simplefunc(url string) {
res,err:=http.Get(url)
if err!=nil {
//记录错误日志
Logger.Error(
"http get failed..",
zap.String("url:",url),
zap.Error(err),
)
}else {
//使用info记录成功日志。
Logger.Info(
"get success",
zap.String("status:",res.Status),
zap.String("url:",url),
)
res.Body.Close()
} }

在gin框架中使用zap日志记录器

Go日志管理库zap的更多相关文章

  1. golang常用库包:log日志记录-uber的Go日志库zap使用详解

    Go 日志记录库:uber-go 的日志操作库 zap 使用 一.简介 zap 是 uber 开源的一个高性能,结构化,分级记录的日志记录包. go1.20.2 zap v1.24.0 zap的特性 ...

  2. C++ spdlog日志管理

    [1]spdlog简介 spdlog是一个开源的.快速的.仅有头文件的基于C++11实现的一款C++专用日志管理库. [2]源码下载 下载地址:https://github.com/gabime/sp ...

  3. 清晰架构(Clean Architecture)的Go微服务: 日志管理

    良好的日志记录可以提供丰富的日志数据,便于在调试时发现问题,从而大大提高编码效率. 记录器提供的自动化信息越多越好,日志信息也需要以简洁的方式呈现,便于找到重要的数据. 日志需求: 无需修改业务代码即 ...

  4. ABP(现代ASP.NET样板开发框架)系列之8、ABP日志管理

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之8.ABP日志管理 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...

  5. Java 日志管理最佳实践

    转:http://blog.jobbole.com/51155/ 日志记录是应用程序运行中必不可少的一部分.具有良好格式和完备信息的日志记录可以在程序出现问题时帮助开发人员迅速地定位错误的根源.对于开 ...

  6. Java日志管理方法(转载)

    原文地址:http://www.cnblogs.com/leocook/p/log_java.html java开发中常见的几种日志管理方案有以下4种: 1. Commons-logging + lo ...

  7. ABP日志管理

    ABP日志管理 基于DDD的现代ASP.NET开发框架--ABP系列之8.ABP日志管理 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ABP ...

  8. 项目实战6—Mysql实现企业级日志管理、备份与恢复实战

    Mysql实现企业级日志管理.备份与恢复实战 环境背景:随着业务的发展,公司业务和规模不断扩大,网站积累了大量的用户信息和数据,对于一家互联网公司来说,用户和业务数据是根基.一旦公司的数据错乱或者丢失 ...

  9. 2019你该掌握的开源日志管理平台ELK STACK

    转载于https://www.vtlab.io/?p=217   在企业级开源日志管理平台ELK VS GRAYLOG一文中,我简单阐述了日志管理平台对技术人员的重要性,并把ELK Stack和Gra ...

  10. CentOS安装Nginx 以及日志管理

    环境:CentOS-6.4 Nginx版本:nginx-1.6.2.tar Linux连接工具:XShell VMWare虚拟机上准备两台CentOS: 两台机器做同样操作(后边做负载均衡.高可用的时 ...

随机推荐

  1. 【数据集】Maple-IDS——网络安全恶意流量检测数据集

    一.数据集介绍 Maple-IDS数据集是一个网络入侵检测评估数据集,旨在增强异常基础入侵检测系统(IDS)和入侵预防系统(IPS)的性能和可靠性.随着网络空间安全领域攻击的日益复杂化,拥有一个可靠和 ...

  2. oeasy 教您玩转linux 之010208 满屏乱码 bb

    我们来回顾一下 上一部分我们都讲了什么? 黑客帝国 各种速度颜色参数 最后我们想找一个让人完全崩溃的软件包,这不就来了,话不多说,先试试. apt show bbapt search bbsudo a ...

  3. oeasy教您玩转vim - 17 - # 向上向下

    向上向下 回忆上节课内容 和 f 相关的是跳到 向 前 跳到是 f 向 后 跳到是 F 和 t 相关的是贴靠 向 前 贴靠是 t 向 后 贴靠是 T 和 小写 相关的是 向前 向前 跳跃是 f 向前 ...

  4. oeasy教您玩转python - 010 - # 不换行输出

    不换行输出 回忆上次内容 \n 就是换行 他对应着 ascii 字符的代码是(10)10进制 他的英文是 LF,意思是Line Feed 这样我就可以自由的控制哪里换行了! 可以做下面这个框架标题吗? ...

  5. QT 开发快速入门

    本人 qt 业余,但有的时候要用到 qt,而又没有系统的学习,用到哪里看哪里. 环境: vs2012+ qt-vsaddins+qt5.5 qt 的按钮点击事件出发的基本要素: 1. 按钮触发函数为 ...

  6. Java解压rar5兼容rar4

    RAR文件格式由WinRAR开发,广泛用于文件压缩和归档.随着技术的发展,RAR5作为更新的版本,引入了多项改进以提高压缩效率和数据安全性. 压缩效率:RAR5通过增大字典大小至32MB,相较于RAR ...

  7. 【RabbitMQ】08 深入部分P1 可靠性投递

    1.消息投递确认 这里的代码延用了06的东西: https://www.cnblogs.com/mindzone/p/15374684.html 删除之前的整合案例,重新写了一份案例的队列和交换机配置 ...

  8. 【AJAX】Asynchronous JavaScript And XML (非同步的JS & XML)

    什么是AJAX? 按照使用的感觉来看 说到底就是一个可以不刷新网页就能发送POST & GET请求的技术 AJAX 即"Asynchronous Javascript And XML ...

  9. 【Hibernate】Re01.5 API

    1.Session单表的CRUD操作 1.增加或者修改,使用同一个方法,或者下面的两个也行: 感觉多此一举... 2.删除方法,硬删除: 3.获取方法提供了两种,Get & Load get方 ...

  10. 【转载】 PID算法的解析

    原文来自DF创客社区地址:http://www.dfrobot.com.cn/community/thread-14783-1-1.html ----------------------------- ...