golang开发:类库篇(一) Zap高性能日志类库的使用
为什么要用zap来写日志
原来是写PHP的,一直用的error_log,第一次写Go项目的时候,还真不知道该怎么写日志,后来就按照PHP的写法自己不成规范的捣鼓写。去了新公司之后,发现用的是zap。后来查询 了解了下zap,前同事反应他们很多大公司都在使用zap写日志,GitHub上star 高达7K多,足以说明它受欢迎的程度。
1.zap是Uber开源的日志库;
2.很多大的公司和小的公司都在使用;
3.跟seelog、logrus等类库相比,高性能是它最突出的优势;
我想以上几个原因就已经说明了它的广泛性、稳定性,就值得我们去尝试。
怎么使用zap
我们说下简单的使用案例
首相当然是下载
go get -u go.uber.org/zap
先贴一个我这边常用的zap的配置
zap.Config{
Level: zap.NewAtomicLevelAt(zap.DebugLevel),
Development: true,
Encoding: "json",
EncoderConfig: zapcore.EncoderConfig{
TimeKey: "t",
LevelKey: "level",
NameKey: "log",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "trace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: 时间格式函数,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
},
OutputPaths: []string{"/tmp/zap.log"},
ErrorOutputPaths: []string{"/tmp/zap.log"},
InitialFields: map[string]interface{}{
"app": "test",
},
}
基本配置的说明
Level:日志级别,跟其他语言是一样的。只不过它需要的类型是AtomicLevel。所以需要使用zap.NewAtomicLevelAt做下如下的转化。
zap.NewAtomicLevelAt(zap.DebugLevel)
zap.DebugLevel
zap.InfoLevel
zap.WarnLevel
zap.ErrorLevel
Development:bool 是否是开发环境。如果是开发模式,对DPanicLevel进行堆栈跟踪
DisableCaller:bool 禁止使用调用函数的文件名和行号来注释日志。默认进行注释日志
DisableStacktrace:bool 是否禁用堆栈跟踪捕获。默认对Warn级别以上和生产error级别以上的进行堆栈跟踪。
Encoding:编码类型,目前两种json 和 console【按照空格隔开】,常用json
EncoderConfig:生成格式的一些配置--TODO 后面我们详细看下EncoderConfig配置各个说明
OutputPaths:[]string 日志写入文件的地址
ErrorOutputPaths:[]string 将系统内的error记录到文件的地址
InitialFields:map[string]interface{} 加入一些初始的字段数据,比如项目名
当然了,如果想控制台输出,OutputPaths和ErrorOutputPaths不能配置为文件地址,而应该改为stdout。
关于config的配置,具体的可以参考文件里面的注释
go.uber.org/zap/config.go
type Config struct
EncoderConfig配置说明
MessageKey:输入信息的key名
LevelKey:输出日志级别的key名
TimeKey:输出时间的key名
NameKey CallerKey StacktraceKey跟以上类似,看名字就知道
LineEnding:每行的分隔符。基本zapcore.DefaultLineEnding 即"\n"
EncodeLevel:基本zapcore.LowercaseLevelEncoder。将日志级别字符串转化为小写
EncodeTime:输出的时间格式
EncodeDuration:一般zapcore.SecondsDurationEncoder,执行消耗的时间转化成浮点型的秒
EncodeCaller:一般zapcore.ShortCallerEncoder,以包/文件:行号 格式化调用堆栈
EncodeName:可选值。
具体EncoderConfig的说明,可以参考文件里面的注释
go.uber.org/zapcore/encoder.go
type EncoderConfig struct
举个栗子
你扯这么多配置说明,谁有时间看这玩意,写个常用的让大家照着用就好了嘛。
package main
import (
"fmt"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"time"
)
var logger *zap.Logger
func formatEncodeTime(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(fmt.Sprintf("%d%02d%02d_%02d%02d%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second()))
}
func FormateLog(args []interface{}) *zap.Logger {
log := logger.With(ToJsonData(args))
return log
}
func Debug(msg string, args ...interface{}) {
FormateLog(args).Sugar().Debugf(msg)
}
func ToJsonData(args []interface{}) zap.Field {
det := make([]string, 0)
if len(args) > 0 {
for _, v := range args {
det = append(det, fmt.Sprintf("%+v", v))
}
}
zap := zap.Any("detail", det)
return zap
}
func InitZapLog() {
cfg := zap.Config{
Level: zap.NewAtomicLevelAt(zap.DebugLevel),
Development: true,
Encoding: "json",
EncoderConfig: zapcore.EncoderConfig{
TimeKey: "t",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "trace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: formatEncodeTime,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
},
OutputPaths: []string{"/tmp/zap.log"},
ErrorOutputPaths: []string{"/tmp/zap.log"},
InitialFields: map[string]interface{}{
"app": "test",
},
}
var err error
logger, err = cfg.Build()
if err != nil {
panic("log init fail:" + err.Error())
}
}
func main() {
InitZapLog()
defer logger.Sync()
a := []string{"test","hello","world"}
Debug("output",a)
}
执行下,就会在日志文件上输入按照我们配置日志格式。
tail -f /tmp/zap.log
{"level":"debug","t":"20190630_044053","caller":"myproject/main.go:21","msg":"output","app":"test","detail":["[test hello world]"]}
然后我们试下控制台输出,修改三个console相关的配置代码
···
OutputPaths: []string{"stdout"},
ErrorOutputPaths: []string{"stdout"},
控制台窗口就会输出
{"level":"debug","t":"20190630_092533","caller":"myproject/main.go:21","msg":"output","app":"test","detail":["[test hello world]"]}
···
当然了,zap最想的使用和文档,看官网嘛
https://github.com/uber-go/zap
https://godoc.org/go.uber.org/zap
golang开发:类库篇(一) Zap高性能日志类库的使用的更多相关文章
- golang开发:环境篇(五)实时加载工具gin的使用
gin 工具是golang开发中非常有用且有效的工具,有效的提高了开发调试go程序的效率. 为什么要使用gin 我们知道golang是编译型语言,这就表示go程序的每次改动,如果需要查看改动结果都必须 ...
- zap高性能日志
摘要 日志在整个工程实践中的重要性不言而喻,在选择日志组件的时候也有多方面的考量.详细.正确和及时的反馈是必不可少的,但是整个性能表现是否也是必要考虑的点呢?在长期的实践中发现有的日志组件对于计算资源 ...
- 【PHP调试篇】PHP高性能日志组件SeasLog
简述 什么是SeasLog SeasLog是一个C语言编写的PHP扩展,提供一组规范标准的功能函数,在PHP项目中方便.规范.高效地写日志,以及快速地读取和查询日志. 为什么使用SeasLog 无论在 ...
- mysql 开发进阶篇系列 41 mysql日志之慢查询日志
一.概述 慢查询日志记录了所有的超过sql语句( 超时参数long_query_time单位 秒),获得表锁定的时间不算作执行时间.慢日志默认写入到参数datadir(数据目录)指定的路径下.默认文件 ...
- mysql 开发进阶篇系列 39 mysql日志之二进制日志(binlog)
一.概述 二进制日志(binlog)记录了所有的DDL(数据定义语言)语句和DML(数据操纵语言)语句,但是不包括数据查询语句, 语句以"事件"的形式保存,它描述了数据的更改过程, ...
- mysql 开发进阶篇系列 38 mysql日志之错误日志log-error
一.mysql日志概述 在mysql中,有4种不同的日志,分别是错误日志,二进制日志(binlog日志),查询日志,慢查询日志.这此日志记录着数据库在不同方面的踪迹(区别sql server里只有er ...
- golang开发:环境篇(六) Go运行监控Supervisord的使用
为什么要使用Supervisord 17年第一次写Go项目的时候,用Go开发项目倒没没费多大劲,很快就开发完成了.到了在测试环境部署的时候,由于不知道有 Supervisord 这个软件,着实花了些功 ...
- golang开发:环境篇(四)包管理器 glide的使用
glide 是golang项目开发中是特别重要的软件,没有它,golang的项目可能都无法发布. 为什么要使用glide 平时我们开发Go项目的时候,使用第三方的包的时候都直接使用go get 去获取 ...
- mysql 开发进阶篇系列 40 mysql日志之二进制日志下以及查询日志
一.binlog 二进制其它选项 在二进制日志记录了数据的变化过程,对于数据的完整性和安全性起着非常重要作用.在mysql中还提供了一些其它参数选项,来进行更小粒度的管理. 1.1 binlog-do ...
随机推荐
- linux awk(good)
一个用awk处理字符串的例子: #!/bin/bash source="nokia201703148855" preffixStr=$(echo $source |awk '{pr ...
- 手把手教你安装QT集成开发环境(操作系统为ubuntu10.04,需要先安装build-essential和libncurses5-dev)
在安装QT集成开发工具包之前需要先安装build-essential和libncurses5-dev这两个开发工具和库,libncurses5-dev库是一个在Linux/Unix下广泛应用的图形函数 ...
- 正交函数(orthogonal functions)
a map is a function. 映射即函数: 1. 双线性映射与双线性形式 bilinear map 基于同一定义域,将两个向量空间(V,W)中的向量映射为第三个向量空间(X)的向量的函数: ...
- kbmmw 中XML 操作入门(跨平台,而且可以与JSON,YAML,BSON 直接互相转换)
delphi 很早以前就自带了xml 的操作,最新版里面有三种XML 解释器,一种是MSXML,看名字就知道 这个是微软自带的,这个据delphi 官方称是速度是最快的,但是只能在windows 上使 ...
- matlab 求解 Ax=B 时所用算法
x = A\B; x = mldivide(A, B); matlab 在这里的求解与严格的数学意义是不同的, 如果 A 接近奇异,matlab 仍会给出合理的结果,但也会提示警告信息: 如果 A 为 ...
- 用WPF轻松打造iTunes CoverFlow效果
原文:用WPF轻松打造iTunes CoverFlow效果 用WPF轻松打造iTunes CoverFlow效果 ...
- mysql重置root密码,并设置可远程访问
linux系统: mysqld_safe --skip-grant-tables & mysql -u root use mysql UPDATE user SET host = '%' wh ...
- ng-zorro 子菜单
效果 代码 // 初始化菜单 // res.menu是一个Menu数组 // 在后端创建子菜单 res.menu.push({ text: "", i18n: "子菜单& ...
- Bootstrap 图片形状
@{ Layout = null;}<!DOCTYPE html><html><head> <meta name="viewport&q ...
- Lexer的设计--中(4)
设计一个小型的内存池以及链表 上一节撸到万事俱备只欠真正的lex, 但是lex的作用是将源代码转化为Token流, 用什么保存Token? 这就涉及到我们要接触的第一个数据结构-链表, 虽然标准库中很 ...