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函数家族的使用方法。
函数 | 原型 |
---|---|
func Print(v …interface{}) | |
Println | func Println(v …interface{}) |
Printf | func Printf(format string, v …interface{}) |
1.2 panic, fatal
log包还提供了两个异常情况的处理函数,panic家族和fatal家族:函数 | 原型 |
---|---|
Panic | func Panic(v …interface{}) |
Panicln | func Panicln(v …interface{}) |
Panicf | func Panicf(format string, v …interface{}) |
Fatal | func Fatal(v …interface{}) |
Fatalln | func Fatalln(v …interface{}) |
Fatalf | func Fatalf(format string, v …interface{}) |
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的初始值 |
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方法 | 原型 |
---|---|
New | func New(out io.Writer, prefix string, flag int) *Logger |
Print家族 | 同log |
Panic家族 | 同log |
Fatal家族 | 同log |
SetFlags | 同log |
SetPrefix | 同log |
Output | func (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包已经可以完全满足需要了。
相关文章推荐
- Go游戏服务器开发的一些思考(二十三):Go语言Log库封装技巧
- Go语言中日志处理,log包的使用
- go语言学习------Go 记录日志——log包
- Go语言之log日志
- go语言编译运行出错:imported and not used: "log"
- 在Go语言中记录log:seelog包
- Go语言学习之log包(The way to go)
- [Go语言]我的第五个Go语言程序
- 惊人go语言(image网站开发)
- go语言学习
- Go 语言参考教程
- [Go语言]我的第七个Go语言程序
- 第三章 Go语言表达式
- Go语言学习笔记---接口
- Go语言学习(八)获取命令行参数
- Go语言使用Beego的ORM插入Mysql后,时区不一致的解决方案
- Golang 入门系列(三)Go语言基础知识汇总
- go语言即将才能一统江湖_你还不来学?
- [Go语言]从Docker源码学习Go——if语句和map结构