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
É Uber
uma 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 github
para 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 string
tipos
//代码
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:
Example
EProduction
use ajson
saída de formato,Development
use a forma de saída de linhaDevelopment
- 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.Logger
e a *zap.SugaredLogger
única diferença entre eles é que . Sugar()
obtemos um chamando o método logger principal SugaredLogger
e, em seguida, usamos SugaredLogger
o printf
formato 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 lumberjack
processado 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.NewCore
o terceiro parâmetro do método e, em seguida, adicione a WriteSyncer
divisão do arquivo em info
e error
dois 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, info
e debug
nível de logon na loja info.log
, error
nível de log em um error.log
arquivo 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.New
adicionar 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)