Uso da biblioteca de log de alto desempenho golang zap

Autor: Chen Jinjian
blog pessoal: HTTPS: //jian1098.github.io
CSDN blog: https: //blog.csdn.net/c_jian
Jane book: https: //www.jianshu.com/u/8ba9ac5706b6
Contato: jian1098 @ qq.com

Resumo

zapÉ Uberuma biblioteca de log Go desenvolvida muito rápida, estruturada e em nível de log. De acordo com a documentação do Uber-go Zap, seu desempenho é melhor do que pacotes de logs estruturados semelhantes e mais rápido que a biblioteca padrão. O teste de desempenho específico pode ir githubpara ver.

endereço do github:https://github.com/uber-go/zap

Crie uma instância

Chamando zap.NewProduction()/ zap.NewDevelopment()ou zap.Example()criando um Logger. A diferença entre esses três métodos é que ele registrará informações diferentes, e os parâmetros só podem ser stringtipos

//代码
var log *zap.Logger
log = zap.NewExample()
log, _ := zap.NewDevelopment()
log, _ := zap.NewProduction()
log.Debug("This is a DEBUG message")
log.Info("This is an INFO message")

//Example 输出
{
    
    "level":"debug","msg":"This is a DEBUG message"}
{
    
    "level":"info","msg":"This is an INFO message"}

//Development 输出
2018-10-30T17:14:22.459+0800    DEBUG    development/main.go:7    This is a DEBUG message
2018-10-30T17:14:22.459+0800    INFO    development/main.go:8    This is an INFO message

//Production 输出
{
    
    "level":"info","ts":1540891173.3190675,"caller":"production/main.go:8","msg":"This is an INFO message"}
{
    
    "level":"info","ts":1540891173.3191047,"caller":"production/main.go:9","msg":"This is an INFO message with fields","region":["us-west"],"id":2}

Comparação de três métodos de criação:

  • ExampleE Productionuse a jsonsaída de formato, Developmentuse a forma de saída de linha
  • Development
    • Imprima até a pilha a partir do nível de aviso para rastrear
    • Sempre imprime pacote / arquivo / linha (método)
    • Adicione quaisquer campos extras no final da linha como uma string json
    • Imprimir o nome do nível em maiúsculas
    • Imprima o carimbo de hora no formato ISO8601 em milissegundos
  • Production
    • Mensagens de nível de depuração não são registradas
    • Erro, registros de nível Dpânico, rastreará o arquivo na pilha, Aviso não
    • Sempre adicione o autor da chamada ao arquivo
    • Imprimir data em formato de carimbo de data / hora
    • Imprimir o nome do nível em letras minúsculas

Saída formatada

Existem dois tipos de zap, *zap.Loggere a *zap.SugaredLoggerúnica diferença entre eles é que . Sugar()obtemos um chamando o método logger principal SugaredLoggere, em seguida, usamos SugaredLoggero printfformato para gravar a instrução, por exemplo

var sugarLogger *zap.SugaredLogger

func InitLogger() {
    
    
  logger, _ := zap.NewProduction()
    sugarLogger = logger.Sugar()
}

func main() {
    
    
    InitLogger()
    defer sugarLogger.Sync()
    sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, err)
}

Gravar arquivo

Por padrão, os logs serão impressos na interface do console do aplicativo, mas para a conveniência da consulta, os logs podem ser gravados em um arquivo, mas não podemos mais usar os 3 métodos de criação de uma instância, mas usamoszap.New()

package main

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"os"
)

var log *zap.Logger
func main() {
    
    
	writeSyncer, _ := os.Create("./info.log")							//日志文件存放目录
	encoderConfig := zap.NewProductionEncoderConfig()					 //指定时间格式
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	encoder := zapcore.NewConsoleEncoder(encoderConfig)					//获取编码器,NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式
	core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)	 //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志
	log = zap.New(core,zap.AddCaller())								   //AddCaller()为显示文件名和行号
	log.Info("hello world")
	log.Error("hello world")
}

Resultados de saída do arquivo de log:

2020-12-16T17:53:30.466+0800	INFO	geth/main.go:18	hello world
2020-12-16T17:53:30.486+0800	ERROR	geth/main.go:19	hello world

Console de saída e arquivo ao mesmo tempo

Se você precisar gerar o console e os arquivos ao mesmo tempo, basta modificá-los zapcore.NewCore. Exemplo:

package main

import (
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"os"
)

var log *zap.Logger

func main() {
    
    
	//获取编码器,NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder //指定时间格式
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	encoder := zapcore.NewConsoleEncoder(encoderConfig)

	//文件writeSyncer
	fileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
    
    
		Filename:   "./info.log", //日志文件存放目录
		MaxSize:    1,            //文件大小限制,单位MB
		MaxBackups: 5,            //最大保留日志文件数量
		MaxAge:     30,           //日志文件保留天数
		Compress:   false,        //是否压缩处理
	})
	fileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(fileWriteSyncer,zapcore.AddSync(os.Stdout)), zapcore.DebugLevel) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志

	log = zap.New(fileCore, zap.AddCaller()) //AddCaller()为显示文件名和行号


	log.Info("hello world")
	log.Error("hello world")
}

Corte de arquivo

Os arquivos de registro ficarão cada vez maiores com o tempo. Para evitar que os arquivos de registro ocupem o espaço do disco rígido, os arquivos de registro precisam ser cortados de acordo com as condições. O pacote zap em si não oferece a função de corte de arquivos, mas pode ser lumberjackprocessado com pacotes recomendados por funcionários zap.

	//文件writeSyncer
	fileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
    
    
		Filename:   "./info.log", //日志文件存放目录,如果文件夹不存在会自动创建
		MaxSize:    1,            //文件大小限制,单位MB
		MaxBackups: 5,            //最大保留日志文件数量
		MaxAge:     30,           //日志文件保留天数
		Compress:   false,        //是否压缩处理
	})

Grave arquivos por nível

Para facilitar a consulta do pessoal de gestão, geralmente precisamos armazenar os logs abaixo do nível de erro no info.log, e armazenar os logs com o nível de gravidade do erro e acima no arquivo error.log. Só precisamos modifique zapcore.NewCoreo terceiro parâmetro do método e, em seguida, adicione a WriteSyncerdivisão do arquivo em infoe errordois ao exemplo:

package main

import (
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"os"
)

var log *zap.Logger

func main() {
    
    
	var coreArr []zapcore.Core

	//获取编码器
	encoderConfig := zap.NewProductionEncoderConfig()				//NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder 			//指定时间格式
	encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder	//按级别显示不同颜色,不需要的话取值zapcore.CapitalLevelEncoder就可以了
	//encoderConfig.EncodeCaller = zapcore.FullCallerEncoder      	//显示完整文件路径
	encoder := zapcore.NewConsoleEncoder(encoderConfig)

	//日志级别
	highPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool{
    
    	//error级别
		return lev >= zap.ErrorLevel
	})
	lowPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
    
    	//info和debug级别,debug级别是最低的
		return lev < zap.ErrorLevel && lev >= zap.DebugLevel
	})

	//info文件writeSyncer
	infoFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
    
    
		Filename:   "./log/info.log", 	//日志文件存放目录,如果文件夹不存在会自动创建
		MaxSize:    1,            		//文件大小限制,单位MB
		MaxBackups: 5,            		//最大保留日志文件数量
		MaxAge:     30,           		//日志文件保留天数
		Compress:   false,        		//是否压缩处理
	})
	infoFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(infoFileWriteSyncer,zapcore.AddSync(os.Stdout)), lowPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志
	//error文件writeSyncer
	errorFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
    
    
		Filename:   "./log/error.log", 		//日志文件存放目录
		MaxSize:    1,            			//文件大小限制,单位MB
		MaxBackups: 5,            			//最大保留日志文件数量
		MaxAge:     30,           			//日志文件保留天数
		Compress:   false,        			//是否压缩处理
	})
	errorFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(errorFileWriteSyncer,zapcore.AddSync(os.Stdout)), highPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志

	coreArr = append(coreArr, infoFileCore)
	coreArr = append(coreArr, errorFileCore)
	log = zap.New(zapcore.NewTee(coreArr...), zap.AddCaller()) //zap.AddCaller()为显示文件名和行号,可省略

	log.Info("hello info")
	log.Debug("hello debug")
	log.Error("hello error")
}

Após esta modificação, infoe debugnível de logon na loja info.log, errornível de log em um error.logarquivo separado no

O console exibe cores por nível

Basta especificar o codificador EncodeLevel,

	//获取编码器
	encoderConfig := zap.NewProductionEncoderConfig()				//NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder 			//指定时间格式
	encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder	//按级别显示不同颜色,不需要的话取值zapcore.CapitalLevelEncoder就可以了
	encoder := zapcore.NewConsoleEncoder(encoderConfig)

Exibir o caminho do arquivo e o número da linha

Conforme mencionado anteriormente, para exibir o caminho do arquivo e o número da linha, você só precisa zap.Newadicionar parâmetros zap.AddCaller()ao método . Se quiser exibir o caminho completo, é necessário especificá-lo na configuração do codificador

	//获取编码器
	encoderConfig := zap.NewProductionEncoderConfig()				//NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder 			//指定时间格式
	encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder	//按级别显示不同颜色,不需要的话取值zapcore.CapitalLevelEncoder就可以了
	encoderConfig.EncodeCaller = zapcore.FullCallerEncoder      	//显示完整文件路径
	encoder := zapcore.NewConsoleEncoder(encoderConfig)

Código completo

package main

import (
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"os"
)

var log *zap.Logger

func main() {
    
    
	var coreArr []zapcore.Core

	//获取编码器
	encoderConfig := zap.NewProductionEncoderConfig()				//NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder 			//指定时间格式
	encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder	//按级别显示不同颜色,不需要的话取值zapcore.CapitalLevelEncoder就可以了
	//encoderConfig.EncodeCaller = zapcore.FullCallerEncoder      	//显示完整文件路径
	encoder := zapcore.NewConsoleEncoder(encoderConfig)

	//日志级别
	highPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool{
    
    	//error级别
		return lev >= zap.ErrorLevel
	})
	lowPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
    
    	//info和debug级别,debug级别是最低的
		return lev < zap.ErrorLevel && lev >= zap.DebugLevel
	})

	//info文件writeSyncer
	infoFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
    
    
		Filename:   "./log/info.log", 	//日志文件存放目录,如果文件夹不存在会自动创建
		MaxSize:    2,            		//文件大小限制,单位MB
		MaxBackups: 100,            	//最大保留日志文件数量
		MaxAge:     30,           		//日志文件保留天数
		Compress:   false,        		//是否压缩处理
	})
	infoFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(infoFileWriteSyncer,zapcore.AddSync(os.Stdout)), lowPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志
	//error文件writeSyncer
	errorFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
    
    
		Filename:   "./log/error.log", 		//日志文件存放目录
		MaxSize:    1,            			//文件大小限制,单位MB
		MaxBackups: 5,            			//最大保留日志文件数量
		MaxAge:     30,           			//日志文件保留天数
		Compress:   false,        			//是否压缩处理
	})
	errorFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(errorFileWriteSyncer,zapcore.AddSync(os.Stdout)), highPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志

	coreArr = append(coreArr, infoFileCore)
	coreArr = append(coreArr, errorFileCore)
	log = zap.New(zapcore.NewTee(coreArr...), zap.AddCaller()) //zap.AddCaller()为显示文件名和行号,可省略


	log.Info("hello info")
	log.Debug("hello debug")
	log.Error("hello error")
}

Artigo de referência

Use a biblioteca de registros Zap em um projeto de linguagem Go - Zhihu (zhihu.com)

[ Exemplo de configuração de zap da biblioteca de registros de alto desempenho Golang-ExplorerMan-Blog Park (cnblogs.com) ] (https://zhuanlan.zhihu.com/p/88856378?utm_source=wechat_session)

Acho que você gosta

Origin blog.csdn.net/C_jian/article/details/111315457
Recomendado
Clasificación