在我们编写程序时是离不开日志的,在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区别
Fatal
和 Panic
都是用来打印信息然后终止程序,不知道何时用哪个?
Panic
: 抛出异常终止程序,一般来说在调试时想获得更多错误信息那就使用 PanicFatal
: 这其实只是打印信息后正常退出程序不会提供更多额外信息给你
所以在程序中使用 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
}
强大的第三方日志模块
目前比较流行的是这两个日志系统,可以去了解下