您的位置:首页 > 编程语言 > Go语言

Go语言-log

2018-03-29 11:18 302 查看

1. log包

作为程序调试手段和运行记录,log是非常重要的,现在多数情况下并不是通过某个调试器来进行debug了,而是通过打log的方式观察和调试程序。

可以根据自己的需要实现log功能,Go语言本身也已经内置了log包,这里研究Go语言内置log包的使用方法。

如果习惯看go doc,可以查阅go doc 来快速查阅log包的信息。

1.1 屏显log

屏幕显示即输出log到标准输出设备。

package main

import (
"log"
)

func main() {
log.Println("log.Println")
}

---------------
2018/03/29 10:09:20 log.Println


可以看到,直接使用log包,通过log.Println就可以向标准输出打印log,带有日期时间和自定义字符串。可以使用的函数还有print和printf,参考fmt包中的print函数家族的使用方法。

函数原型
Printfunc Print(v …interface{})
Printlnfunc Println(v …interface{})
Printffunc Printf(format string, v …interface{})
Print和Println,其实用起来没有什么区别,连续用log.Print,也并不会输出到同一行,还是每调用一次,就产生新的一行log。

1.2 panic, fatal

log包还提供了两个异常情况的处理函数,panic家族和fatal家族:

函数原型
Panicfunc Panic(v …interface{})
Paniclnfunc Panicln(v …interface{})
Panicffunc Panicf(format string, v …interface{})
Fatalfunc Fatal(v …interface{})
Fatallnfunc Fatalln(v …interface{})
Fatalffunc Fatalf(format string, v …interface{})
panic会打印指定的log字符转,然后抛出异常,显示调用栈。

package main

import (
"log"
)

func main() {
defer log.Println("log in defer")
log.Println("log.Println")
log.Panicln("log.Panicln")
}
---------------
2018/03/29 10:34:27 log.Println
2018/03/29 10:34:27 log.Panicln
2018/03/29 10:34:27 log in defer
panic: log.Panicln

goroutine 1 [running]:
log.Panicln(0xc42003ff50, 0x1, 0x1)
/home/docker/go192/go/src/log/log.go:340 +0xc0
main.main()
/home/docker/go/test/log/src/main.go:11 +0x11b
exit status 2


log包中的Panic和系统内置的panic是一样的,运行到log.Panic的时候,打印log信息,然后会继续逆序执行defer,如果存在多级调用,以此返回上级,执行defer,最终打印调用栈。

而Fatal与Panic不同,区别是不会执行defer,也没有调用栈,直接os.Exit(1)了:

package main

import (
"log"
)

func main() {
defer log.Println("log in defer")
log.Println("log.Println")
log.Fatalln("log.Fatalln")
}
---------------
2018/03/29 10:38:33 log.Println
2018/03/29 10:38:33 log.Fatalln
exit status 1


1.3 设置格式

上面的例子都是用默认的输出格式,每行的最开始显示日期时间,然后显示给定的log内容。

如果需要改变最开始显示的内容,是可以通过设定flag和前缀来完成的。

1.3.1 SetFlags

可以设定的flag包括:

标志含义
Ldate日期: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的初始值
通过例子看下各个flag的意义:

package m
4000
ain

import (
"log"
)

func main() {
log.SetFlags(log.Ldate)
log.Println("日期")

log.SetFlags(log.Ltime)
log.Println("时间")

log.SetFlags(log.Lmicroseconds)
log.Println("微秒")

log.SetFlags(log.Llongfile)
log.Println("全文件路径和行号")

log.SetFlags(log.Lshortfile)
log.Println("文件名和行号")

log.SetFlags(log.LstdFlags)
log.Println("标准")

log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
log.Println("组合: 日期 + 微秒 + 文件名和行号")
}
---------------
2018/03/29 日期
10:54:10 时间
10:54:10.582154 微秒
/home/docker/go/test/log/src/main.go:18: 全文件路径和行号
main.go:21: 文件名和行号
2018/03/29 10:54:10 标准
2018/03/29 10:54:10.582187 main.go:27: 组合: 日期 + 微秒 + 文件名和行号


1.3.2 SetPrefix

上一节设置的flag控制的是最前边显示的时间日期,文件名行号什么的。还可以通过SetPrefix来改变每一行最开始显示的字符串:

package main

import (
"log"
)

func main() {
log.SetPrefix("func main")
log.Println("含前缀")
}
---------------
func main:2018/03/29 10:59:36 含前缀


通过SetFlags和SetPrefix,对log格式的控制,基本可以满足绝大部分的log打印需要了。

1.4 log文件

输出log到文件,可以通过new一些logger,通过logger实例自己的方法调用,去写入不到不同的目标位置。

Logger方法原型
Newfunc New(out io.Writer, prefix string, flag int) *Logger
Print家族同log
Panic家族同log
Fatal家族同log
SetFlags同log
SetPrefix同log
Outputfunc (l *Logger) Output(calldepth int, s string) error
一个最简单的例子:

package main

import (
"log"
"os"
)

func main() {
dbgLog, err := os.OpenFile("./dbgLog.log",  os.O_CREATE | os.O_APPEND| os.O_WRONLY, os.ModePerm)
if err != nil {
log.Fatalln("dbgLog.log创建失败")
}

errLog, err := os.OpenFile("./errLog.log",  os.O_CREATE | os.O_APPEND| os.O_WRONLY, os.ModePerm)
if err != nil {
log.Fatalln("errLog.log创建失败")
}

dbgLogger := log.New(dbgLog, "[DEBUG] ", log.LstdFlags)
errLogger := log.New(errLog, "[ERROR] ", log.LstdFlags|log.Lshortfile)

log.Println("log文件创建成功")
dbgLogger.Println("调试信息log")
errLogger.Println("错误信息log")
}
---------------
2018/03/29 11:15:22 log文件创建成功

---------------
dbgLog.log
[DEBUG] 2018/03/29 11:15:22 调试信息log

---------------
errLog.log
[ERROR] 2018/03/29 11:15:22 main.go:24: 错误信息log


logger不仅可以在New的时候指定Flag,也可以通过与log相同的函数 SetFlags控制log格式,可以通过SetPrefix改变前缀。

对于常规log打印需求,log包已经可以完全满足需要了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: