前两周调bug调的吐血,虽然解决了但是还是挺浪费时间的。跟同事聊了聊,觉得我们现在项目中的日志记录太少了,导致出了问题不知道怎么下手,还得自己改代码记录日志,然后排查问题。这样如果将来还有bug的话还得这么调,很麻烦,让我深入看一下go语言中如何记录日志(好吧我最近就跟日志耗上了)。
根据python的经验和目前项目中的要求,我对日志的要求有两个:
一是定义日志级别,可以记录debug/warning/error之类的不同级别的日志,这样的话,在通常正常运行的时候,就只需要记录一下运行状态,而报错需要调试的时候,可以显示的日志多一些;
二是定义日志格式,想要记录什么内容,比如时间、级别、位置、日志信息等等。于是,简单的看了一下Go自带的log模块,就知道根本达不到我的要求。
在网上查了一下现在比较流行的日志记录方法,看到有人推荐seelog,于是尝试一下。中了几个小坑,不过还算顺利,写起来也比较流畅。记录一下。
seelog官网:https://github.com/cihub/seelog
安装seelog
在命令行下
go get -u github.com/cihub/seelog
这里我踩了第一个坑——因为对go语言还不太熟,没有装git。去百度一下,装个git,回来发现还是不行,因为windows下git不会自动配置环境变量。需要在path中添加bin路径和git-core路径。如果是默认安装,一般就是添加
;C:\Program Files\Git\bin;C:\Program Files\Git\mingw64\libexec\git-core
需要注意一下windows是32位还是64位的(linux下就没这么多事了,直接apt-get install git完事)
之后敲个命令git试试,有这个命令了就是环境变量配置好了。再次go get安装seelog十分顺利就装好了。
使用seelog
安装好了之后就可以试试看了。跟python和java的logging不同的是,seelog是需要一个xml配置文件的,里面设置log输出的路径,等级,格式等。一个典型的配置文件是长成酱婶的:
<seelog type="asynctimer" asyncinterval="5000000" minlevel="debug" maxlevel="error"> <exceptions> <exception funcpattern="*main.test*Something*" minlevel="info"/> <exception filepattern="*main.go" minlevel="error"/> </exceptions> <outputs formatid="main"> <console/> <splitter formatid="format1"> <file path="log.log"/> <file path="log2.log"/> </splitter> <splitter formatid="format2"> <file path="log3.log"/> <file path="log4.log"/> </splitter> <rollingfile formatid="someformat" type="size" filename="./log/roll.log" maxsize="100" maxrolls="5" /> <buffered formatid="testlevels" size="10000" flushperiod="1000"> <file path="./log/bufFileFlush.log"/> </buffered> <filter levels="error"> <file path="./log/error.log"/> <smtp senderaddress="noreply-notification-service@none.org" sendername="Automatic notification service" hostname="mail.none.org" hostport="587" username="nns" password="123"> <recipient address="john-smith@none.com"/> <recipient address="hans-meier@none.com"/> </smtp> <conn net="tcp4" addr="server.address:5514" tls="true" insecureskipverify="true" /> </filter> </outputs> <formats> <format id="main" format="%Date(2006 Jan 02/3:04:05.000000000 PM MST) [%Level] %Msg%n"/> <format id="someformat" format="%Ns [%Level] %Msg%n"/> <format id="testlevels" format="%Level %Lev %LEVEL %LEV %l %Msg%n"/> <format id="usetags" format="<msg>%Msg</time>"/> <format id="format1" format="%Date/%Time [%LEV] %Msg%n"/> <format id="format2" format="%File %FullPath %RelFile %Msg%n"/> </formats> </seelog>
此xml见:https://github.com/cihub/seelog/wiki/Example-config
别问我这虾米,我也只能看懂一部分。目前我只知道最简单的几个节点的用法,满足我的需求的。对于我来说,下面这样一个xml就基本够用了:
(这里我用-->这符号假装注释,xml本身没有注释)
<seelog> <outputs formatid="main"> -->去找id为main的格式 <filter levels="info,debug,critical,error"> -->定义记录格式 <console /> -->向屏幕输出 </filter> <filter levels="debug"> <file path="debug.txt" /> -->向文件输出。可以多个共存。 </filter> </outputs> <formats> <format id="main" format="%Date/%Time [%LEV] %Msg%n"/> -->format内容,可以多个共存,只要id不相同。然后上面可以用不同的id来输出不同格式的日志。 </formats> </seelog>
OK。写好xml之后可以码代码了。写个简单的例子:
// TestSeelog.go package main import ( seelog "github.com/cihub/seelog" ) func main() { logger, err := seelog.LoggerFromConfigAsFile("seelog.xml") if err != nil { seelog.Critical("err parsing config log file", err) return } seelog.ReplaceLogger(logger) seelog.Error("seelog error") seelog.Info("seelog info") seelog.Debug("seelog debug") }
(呃。。博客园没有Golang的代码颜色,就这样吧,反正不耽误看)
写完运行。一个好消息和一个坏消息。好消息是没有问题正常运行结束了。坏消息是特么的没有出来日志。屏幕和日志文件都没有。卧槽我日志呢?你给我藏哪去了?
来来回回检查了十来遍没找到原因,于是去QQ群里问了一下,感谢 吴迎松 和 溺水的鱼 两位同学的解答:没有来得及运行就结束了,并且没有flush。于是在seelog记录日志内容之前加了一句
defer seelog.Flush()
之后就可以出结果了。
2015-12-17/16:28:23 [ERR] seelog error 2015-12-17/16:28:23 [INF] seelog info 2015-12-17/16:28:23 [DBG] seelog debug
至此。seelog第一步算是踏出来了。看看seelog里面还有很多的函数,还有配置文件里那堆我不明白的属性,还有github上的文档,我觉得,这个库还有更多值得深入挖掘的地方。以后有空再看。
有疑问加站长微信联系(非本文作者)