这是我参与「第五届青训营 」伴学笔记创作活动的第6天
go提供了log包, 实现了简单的日志服务可以通过import "log"使用
log包定义了一个标准的Logger类, 用以方便的调用官方库封装好的日志方法.
std和New
常规的面向对象都需要定义一个对象, 然后才能调用方法
既然我们可以直接通过log来调用方法, 就表明log为我们提供了一个默认对象
log的文档说, 它为我们提供了一个预定义的"标准"Logger, 可以通过辅助函数Printf(), Fatalf(), Panicf()等方法访问, 大大降低了上手难度
虽然官方自己提供一个默认log对象, 但是我们也可以像官方一样, 通过New方法自定义一个log对象
其中, New方法api为
func New(out io.Writer, prefix string, flag int) *Logger
prefix表示日志的前缀, 每次都在打出的日志最前面, flag一般用来输出一些标准信息, 例如文件名, 时间等等
package main
import "log"
func main() {
log.SetPrefix("我是前缀")
log.SetFlags(log.Ldate | log.Lshortfile | log.Lmicroseconds)
log.Println("我是日志正文")
}
// output
// 我是前缀2023/02/09 23:54:24.851250 scratch.go:8: 我是日志正文
由示例可以看出, 日志遵循的顺序是 prefix, flag, 正文
constant
Logger类封装了一些常量, 如下所示
const (
// 字位共同控制输出日志信息的细节。不能控制输出的顺序和格式。
// 在所有项目后会有一个冒号:2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
Ldate = 1 << iota // 日期:2009/01/23
Ltime // 时间:01:23:23
Lmicroseconds // 微秒分辨率:01:23:23.123123(用于增强Ltime位)
Llongfile // 文件全路径名+行号: /a/b/c/d.go:23
Lshortfile // 文件无路径名+行号:d.go:23(会覆盖掉Llongfile)
LstdFlags = Ldate | Ltime // 标准logger的初始值
)
我们可以通过log.Ldate等直接进行调用, 通常这些常量用于设置在Flag上, Flag输出在自定义的文本前. 通过|可以将多个常量设置为flag
通过flag, 我们可以定位到日志的一些标准信息
Output
Output是log包的核心, 主要作用是进行一次写日志事件
后续log的其他类似Printf(), Fatalf()等操作均需要通过Output方法实现, Output的主要作用是将传入的字符串转化为字节流, 写入到Writer中.
Print()
log.Print()的处理方式和fmt.Print()一致, 通过调用Output()方法, 将传入的字符串转化为字节流输出到logger中
Fatal()
从官方代码来看log.Fatal()等价于
log.Print()
os.Exit(1)
Panic()
等价于
log.Print()
panci(...)