Go总结(十六)| 自定义Log日志
开发软件日志很重要,不管是应用的标准输出信息,还是主动打印的日志,还是被动的异常信息;都有被记录和整理的需求。大数据从哪里来,很多时候其实是从日志中来的。日志很重要,Go标准库也为日志输出内置了大量实用方法。
标准配置
标准库就提供了这些参数,按需要配置就好了:
|
|
日志前缀
可以自定义日志前缀,这样方便不同的子模块的日志混合在一起的情况下,也能很好的检索。
|
|
下面就是效果示例:
[GoFast]2021/01/19 08:01:21 Listening and serving HTTP on 127.0.0.1:8099
[GoFast]2021/01/19 08:01:21 App OnReady Call.
特殊日志
log包除了有Print系列的函数,还有Fatal以及Panic系列的函数,其中Fatal表示程序遇到了致命的错误,需要退出,这时候使用Fatal记录日志后,然后程序退出,也就是说Fatal相当于先调用Print打印日志,然后再调用os.Exit(1)退出程序。
同理Panic系列的函数也一样,表示先使用Print记录日志,然后调用panic()函数抛出一个恐慌,这时候除非使用recover()函数,否则程序就会打印错误堆栈信息,然后程序终止。
看看源代码:
|
|
日志底层封装
看看主要的源代码:
|
|
源代码可以看出,变量std其实是一个*Logger,通过log.New函数创建,默认输出到os.Stderr设备,前缀为空,日志抬头信息为标准抬头LstdFlags。os.Stderr对应的是UNIX里的标准错误警告信息的输出设备,同时被作为默认的日志输出目的地。除此之外,还有标准输出设备os.Stdout以及标准输入设备os.Stdin。
解释下这里的Logger类:
- 字段
mu是一个互斥锁,主要是是保证这个日志记录器Logger是goroutine安全的。 - 字段
prefix是每一行日志的前缀。 - 字段
flag是日志抬头信息。 - 字段
out是日志输出的目的地,默认情况下是os.Stderr。 - 字段
buf是一次日志输出文本缓冲,最终会被写到out里。
log包的SetOutput函数,可以设置输出目的地。这里稍微简单介绍下runtime.Caller,它可以获取运行时方法的调用信息。
func Caller(skip int) (pc uintptr, file string, line int, ok bool)
参数skip表示跳过栈帧数,0表示不跳过,也就是runtime.Caller的调用者。1的话就是再向上一层,表示调用者的调用者。log日志包里使用的是2,也就是表示我们在源代码中调用log.Print、log.Fatal和log.Panic这些函数的调用者。
以main函数调用log.Println为例,是main->log.Println->*Logger.Output->runtime.Caller这么一个方法调用栈,所以这时候,skip的值分别代表:
0表示*Logger.Output中调用runtime.Caller的源代码文件和行号1表示log.Println中调用*Logger.Output的源代码文件和行号2表示main中调用log.Println的源代码文件和行号
这也就是log包里的这个skip的值为什么一直是2的原因。
定制日志
标准库中的log包只是定义了一种通用的日志类型,输出都到了os.Stderr,你也可以定义自己的日志系统。
|
|
控制台输出:
INFO: 2021/01/19 18:08:09 cus_logger.go:32: Special Information
WARN: 2021/01/19 18:08:09 cus_logger.go:33: There is something you need to know about
ERROR: 2021/01/19 18:08:09 cus_logger.go:34: Something has failed
还有你会发现在项目根目录新加了一个文件errors.txt,里面的内容是:
ERROR: 2021/01/19 18:08:09 cus_logger.go:34: Something has failed
小结:
这里我们通过定义多个Logger来区分不同的日志级别,使用比较麻烦;针对这种情况,可以使用第三方的log框架;也可以自己包装定义,直接通过不同级别的方法来记录不同级别的日志,还可以设置记录日志的级别等。
(完)
- 原文作者: 闪电侠
- 原文链接:https://chende.ren/2021/01/19131400-016-go-log.html
- 版权声明:本作品采用 开放的「署名 4.0 国际 (CC BY 4.0)」创作共享协议 进行许可