首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

Go日志管理库zap

编程知识
2024年09月12日 22:22

一、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()
image

NewDevelopment()
image

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))

image

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日志记录器

From:https://www.cnblogs.com/iruan/p/18411322
本文地址: http://www.shuzixingkong.net/article/1963
0评论
提交 加载更多评论
其他文章 DECL: 针对噪声时间序列的去噪感知对比学习《Denoising-Aware Contrastive Learning for Noisy Time Series》(时间序列、对比学习、去噪)
今天是2024年9月12日,组会摸鱼,很久没看论文了,在摸鱼看代码,最近IJCAI 2024出来了,找了几篇论文看,首先这是第一篇。 论文:Denoising-Aware Contrastive Learning for Noisy Time Series 或者是:Denoising-Aware C
Vert.x HttpClient调用后端服务时使用Idle Timeout和KeepAlive Timeout的行为分析
其实网上有大量讨论HTTP长连接的文章,而且Idle Timeout和KeepAlive Timeout都是HTTP协议上的事情,跟Vert.x本身没有太大关系,只不过最近在项目上遇到了一些问题,用到了Vert.x的HttpClient,就干脆总结一下,留给自己今后做参考。 在使用Vert.x的Ht
Vert.x HttpClient调用后端服务时使用Idle Timeout和KeepAlive Timeout的行为分析 Vert.x HttpClient调用后端服务时使用Idle Timeout和KeepAlive Timeout的行为分析 Vert.x HttpClient调用后端服务时使用Idle Timeout和KeepAlive Timeout的行为分析
Qml 实现仿前端的 Notification (悬浮出现页面上的通知消息)
在前端中一般称它为 Notification 或 Message,但本质是一种东西,即:悬浮弹出式的消息提醒框。 这种组件一般具有以下特点: 1、全局/局部显示:它不依赖于具体的页面元素,可以在整个页面的任意位置显示。 2、自动消失:默认情况下,消息会在一定时间后自动消失,也可以设置为不自动消失。
Qml 实现仿前端的 Notification (悬浮出现页面上的通知消息) Qml 实现仿前端的 Notification (悬浮出现页面上的通知消息) Qml 实现仿前端的 Notification (悬浮出现页面上的通知消息)
LinkedHashMap原理详解—从LRU缓存机制说起
写在前面 从一道Leetcode题目说起 首先,来看一下Leetcode里面的一道经典题目:146.LRU缓存机制,题目描述如下: 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容
LinkedHashMap原理详解—从LRU缓存机制说起 LinkedHashMap原理详解—从LRU缓存机制说起 LinkedHashMap原理详解—从LRU缓存机制说起
vue3项目部署到Github
此教程适应于以webpack,vue-cli,vite等脚手架构建的vue项目。当然,vue2和vue3都是可以滴。 1. 前提:你的代码库已经提交到Github上 如果没有的话,请到GitHub上新建仓库,并把你本地的项目提交到GitHub上新建的仓库里。 具体方法,可以参考我的博客 Git使用记
vue3项目部署到Github vue3项目部署到Github vue3项目部署到Github
项目完成小结:使用DjangoStarter v3和Taro开发的微信小程序
前言 不知不觉已经九月了,又到了一年的开学季,我每年都想做的项目墙甚至连个影子都没有…😂 最近生活中的琐事太多了,导致完全没有想写文章的动力,不过再怎么拖还是得记录,随便写写吧~ 这次是7月份的一个小项目,谈不上什么技术含量,算是友情开发了。后端 DjangoStarter v3,前
Redis入门 - C#|.NET Core封装Nuget包
分享封装Redis C#库并打包成Nuget包的方法,旨在增强代码可测试性、解耦及扩展Redis功能。通过封装Redis客户端库,提供统一接口,便于测试、替换和扩展功能,同时支持依赖注入,简化配置和使用。
Redis入门 - C#|.NET Core封装Nuget包 Redis入门 - C#|.NET Core封装Nuget包 Redis入门 - C#|.NET Core封装Nuget包
Entity Framework Plus: 让 EF Core 开发如虎添翼
EF Core介绍 Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术,EF Core 是适用于 .NET 的现代对象数据库映射器。它支持 LINQ 查询、更改跟踪、更新和架构迁移。EF Core 通过提供程序
Entity Framework Plus: 让 EF Core 开发如虎添翼 Entity Framework Plus: 让 EF Core 开发如虎添翼