
在我们编写程序时是离不开日志的,在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
}
强大的第三方日志模块
目前比较流行的是这两个日志系统,可以去了解下