go log包简单了解 | 青训营笔记

90 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第6天

go提供了log包, 实现了简单的日志服务可以通过import "log"使用

log包定义了一个标准的Logger类, 用以方便的调用官方库封装好的日志方法.

std和New

常规的面向对象都需要定义一个对象, 然后才能调用方法

既然我们可以直接通过log来调用方法, 就表明log为我们提供了一个默认对象

log的文档说, 它为我们提供了一个预定义的"标准"Logger, 可以通过辅助函数Printf(), Fatalf(), Panicf()等方法访问, 大大降低了上手难度

image-20230209235053693

虽然官方自己提供一个默认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包的核心, 主要作用是进行一次写日志事件

image-20230209235941081

后续log的其他类似Printf(), Fatalf()等操作均需要通过Output方法实现, Output的主要作用是将传入的字符串转化为字节流, 写入到Writer中.

Print()

log.Print()的处理方式和fmt.Print()一致, 通过调用Output()方法, 将传入的字符串转化为字节流输出到logger中

image-20230210000802005

Fatal()

image-20230210000714577

从官方代码来看log.Fatal()等价于

log.Print()
os.Exit(1)

Panic()

等价于

log.Print()
panci(...)