Golang中的标准库Log

2020-11-07 · xiejiahe

在我们编写程序时是离不开日志的,在Go标准库中提供了一个 log 模块。

比较常用的方法有下面这几个:

ln 结尾的只是多了个换行符 \n, f 结尾的是格式化文本。

  • Panicln / Panic / Panicf - 抛出异常并终止程序
  • Println / Print / Printf - 打印信息
  • Fatalln / Fatal / Fatalf - 打印信息并退出程序

很多新手不知道这些方法和 fmt 包中的方法有什么区别。

实际上上面那3个都只是 fmt 包中的语法糖

Panic

抛出异常信息并终止程序。

示例代码:

package main

import (
	"log"
)

func main() {
	log.Panic("error")
}

底层实现是这样子的:

可以看到这其实只是一个语法糖而已

func Panic(v ...interface{}) {
	s := fmt.Sprint(v...)
	std.Output(2, s)
	panic(s)
}

如果说能不能用全局方法 panic 呢? 不行, 因为panic 只接受一个参数:

panic("error")

所以为什么会有 log.Panic 这个方法了吧。

Fatal和Panic区别

FatalPanic 都是用来打印信息然后终止程序,不知道何时用哪个?

  • Panic: 抛出异常终止程序,一般来说在调试时想获得更多错误信息那就使用 Panic
  • Fatal: 这其实只是打印信息后正常退出程序不会提供更多额外信息给你

所以在程序中使用 Fatal 是没什么意义的,所以不推荐使用。

创建日志文件

创建日志文件的好处在于可以持久化,在出现问题的时候可以快速定位。

创建日志文件需要借助 os 模块和 log 模块。

示例代码,以注释说明:

package main

import (
	"log"
	"os"
)

func main() {
  // 打开一个文件
  // 第一个参数是写入日志文件的位置
  // 第二个参数是需要以什么权限进行操作,多个mode用 | 符号分隔代表多个
  // 最后参数是权限的八进制表示法
	file, err := os.OpenFile("./log.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0)

	if err != nil {
		log.Panicln("文件打开错误:", err)
	}

	defer file.Close()

  // 用 New 方法实例化
  // 第一个参数是 io.Writer 接口,只要实现了该接口都支持,文件就是
  // 第二个参数是 前缀信息 一般用于区别日志是属哪个分类
  // 最后一个参数是 标志, 也就是系统额外附加信息 LstdFlags 包含了日志和时间
	ilog := log.New(file, "Error:", log.LstdFlags)
	ilog.Println("输出错误信息")
}

标志有以下(都是以 L 开头):

参数 描述
Ldate 本地时区日期 2020/11/11
Ltime 本地时区时间 01:23:23
Lmicroseconds 微妙 01:23:23.123123
Llongfile 打印完整文件路径和行号
Lshortfile 打印文件名和行号
LUTC 如果设置了日期或时间,请使用UTC而不是本地时区
LstdFlags Ldate和Ltime的结合,日期和时间一起打印
Lmsgprefix 将Flag信息移至消息前面

打印行号

golang打印日志行号有时非常有用,因为默认 fmt 是不打印行号的,给调试带来不便。

有了上面的Flag信息就好实现了, 借助 Llongfile 即可。

package main

import (
	"log"
	"os"
)

func main() {
	ilog := log.New(os.Stdout, "Info:", log.Llongfile)
  ilog.Println("Hello")
  // 输出:Info:/Users/main.go:10: Hello
}

强大的第三方日志模块

目前比较流行的是这两个日志系统,可以去了解下

Golang
原创文章,转载请注明出处。