一、标准日志库log
在日常开发中,日志是必不可少的功能。虽然有时可以用fmt
库输出一些信息,但是灵活性不够。Go 标准库提供了一个日志库log
。
1、快速使用
log
是 Go 标准库提供的,不需要另外安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
log
默认输出到标准错误(stderr
),每条日志前会自动加上日期和时间。如果日志不是以换行符结尾的,那么log
会自动加上换行符。即每条日志会在新行中输出。
log
提供了三组函数:
-
Print/Printf/Println
:正常输出日志; -
Panic/Panicf/Panicln
:输出日志后,以拼装好的字符串为参数调用panic
; -
Fatal/Fatalf/Fatalln
:输出日志后,调用os.Exit(1)
退出程序。
命名比较容易辨别,带f
后缀的有格式化功能,带ln
后缀的会在日志后增加一个换行符。
注意,上面的程序中由于调用log.Panicf
会panic
,所以log.Fatalf
并不会调用
2、自定义选项
选项
-
Ldate
:输出当地时区的日期,如2020/02/07
; -
Ltime
:输出当地时区的时间,如11:45:45
; -
Lmicroseconds
:输出的时间精确到微秒,设置了该选项就不用设置Ltime
了。如11:45:45.123123
; -
Llongfile
:输出长文件名+行号,含包名,如github.com/darjun/go-daily-lib/log/flag/main.go:50
; -
Lshortfile
:输出短文件名+行号,不含包名,如main.go:50
; -
LUTC
:如果设置了Ldate
或Ltime
,将输出 UTC 时间,而非当地时区。
1 2 | |
3、输出到文件
1 2 3 4 5 6 7 8 | |
4、自定义输出
实际上,log
库为我们定义了一个默认的Logger
,名为std
,意为标准日志。我们直接调用的log
库的方法,其内部是调用std
的对应方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
log.New
接受三个参数:
-
io.Writer
:日志都会写到这个Writer
中; -
prefix
:前缀,也可以后面调用logger.SetPrefix
设置; -
flag
:选项,也可以后面调用logger.SetFlag
设置。
可以使用io.MultiWriter
实现多目的地输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |
二、logrus的使用
1、golang日志库
golang标准库的日志框架非常简单,仅仅提供了print,panic和fatal三个函数对于更精细的日志级别、日志文件分割以及日志分发等方面并没有提供支持。所以催生了很多第三方的日志库,但是在golang的世界里,没有一个日志库像slf4j那样在Java中具有绝对统治地位。golang中,流行的日志框架包括logrus、zap、zerolog、seelog等。
logrus是目前Github上star数量最多的日志库。logrus功能强大,性能高效,而且具有高度灵活性,提供了自定义插件的功能。很多开源项目,如docker,prometheus等,都是用了logrus来记录其日志。
zap是Uber推出的一个快速、结构化的分级日志库。具有强大的ad-hoc分析功能,并且具有灵活的仪表盘。
seelog提供了灵活的异步调度、格式化和过滤功能。
2、logrus特性
GitHub访问地址:https://github.com/sirupsen/logrus
logrus具有以下特性:
- 完全兼容golang标准库日志模块:logrus拥有六种日志级别:debug、info、warn、error、fatal和panic,这是golang标准库日志模块的API的超集。如果您的项目使用标准库日志模块,完全可以以最低的代价迁移到logrus上。
- 可扩展的Hook机制:允许使用者通过hook的方式将日志分发到任意地方,如本地文件系统、标准输出、logstash、elasticsearch或者mq等,或者通过hook定义日志内容和格式等。
- 可选的日志输出格式:logrus内置了两种日志格式,JSONFormatter和TextFormatter,如果这两个格式不满足需求,可以自己动手实现接口Formatter,来定义自己的日志格式。
- Field机制:logrus鼓励通过Field机制进行精细化的、结构化的日志记录,而不是通过冗长的消息来记录日志。
- logrus是一个可插拔的、结构化的日志框架。
尽管 logrus有诸多优点,但是为了灵活性和可扩展性,官方也削减了很多实用的功能,例如:
- 没有提供行号和文件名的支持
- 输出到本地文件系统没有提供日志分割功能
- 官方没有提供输出到ELK等日志处理中心的功能
但是这些功能都可以通过自定义hook来实现。
3、日志格式
比如,我们约定日志格式为 Text,包含字段如下:
请求时间
、日志级别
、状态码
、执行时间
、请求IP
、请求方式
、请求路由
。
4、使用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | |
5、简单的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
6、Logger
logger是一种相对高级的用法, 对于一个大型项目, 往往需要一个全局的logrus实例,即logger
对象来记录项目所有的日志。如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
7、Fields
logrus不推荐使用冗长的消息来记录运行信息,它推荐使用Fields
来进行精细化的、结构化的信息记录。
例如下面的记录日志的方式:
1 2 3 4 5 6 7 8 9 | |
8、gin框架日志中间件使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
9、简单的日志切割
需要引入外部组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
10、ZAP的使用方法(性能最高)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |