前两周调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="&lt;msg&gt;%Msg&lt;/time&gt;"/>
<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上的文档,我觉得,这个库还有更多值得深入挖掘的地方。以后有空再看。

在Go语言中记录log:seelog包的更多相关文章

  1. 在 Go 语言中使用 Log 包--转自GCTT

    Linux 在许多方面相对于 Windows 来说都是独特的,在 Linux 中编写程序也不例外.标准输出,标准 err 和 null devices 的使用不仅是一个好主意,也是一个原则.如果您的程 ...

  2. R语言中的回归诊断-- car包

    如何判断我们的线性回归模型是正确的? 1.回归诊断的基本方法opar<-par(no.readOnly=TRUE) fit <- lm(weight ~ height, data = wo ...

  3. Python的logging,记录log的包

    最近在做自动化测试时,想给他加上日志,所以用到logging的模块,以下是python增加log的几种方式 一.python代码配置方式(当然还有一种是可以多模块通用的一个python代码设置,这个网 ...

  4. 如何使用T-SQL备份还原数据库及c#如何调用执行? C#中索引器的作用和实现。 jquery控制元素的隐藏和显示的几种方法。 localStorage、sessionStorage用法总结 在AspNetCore中扩展Log系列 - 介绍开源类库的使用(一) span<T>之高性能字符串操作实测

    如何使用T-SQL备份还原数据库及c#如何调用执行? 准备材料:Microsoft SQL Server一部.需要还原的bak文件一只 一.备份 数据库备份语句:user master backup ...

  5. 在AspNetCore中扩展Log系列 - 介绍开源类库的使用(一)

    转发时请注明原创作者及地址,否则追究责任. 原创:alunchen 当创建AspNetCore项目时 当我们创建一个AspNetCore项目时,需要我们手动添加Log: services.AddLog ...

  6. R中常用数据挖掘算法包

    数据挖掘主要分为4类,即预测.分类.聚类和关联,根据不同的挖掘目的选择相应的算法.下面对R语言中常用的数据挖掘包做一个汇总: 连续因变量的预测: stats包 lm函数,实现多元线性回归 stats包 ...

  7. go 语言中常用的包

    来自学习go语言.pdf 译者刑星 ==== fmt 包fmt实现了格式化IO函数,这与c的printf和scanf类似,格式化短语派生于c %v 默认格式的值.当打印结构时,加号(%+v)会增加字段 ...

  8. R语言中的数据处理包dplyr、tidyr笔记

    R语言中的数据处理包dplyr.tidyr笔记   dplyr包是Hadley Wickham的新作,主要用于数据清洗和整理,该包专注dataframe数据格式,从而大幅提高了数据处理速度,并且提供了 ...

  9. R语言中的机器学习包

    R语言中的机器学习包   Machine Learning & Statistical Learning (机器学习 & 统计学习)  网址:http://cran.r-project ...

随机推荐

  1. bzoj 4540: [Hnoi2016]序列

    Description 给定长度为n的序列:a1,a2,-,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,-,ar- 1,ar.若1≤l≤s≤t≤r≤n,则称 ...

  2. EveryThing 使用方法

    1.按照时间范围:datetimed: <*.doc|*.docx>  dm:1/2015-6/2015// 如果本地的时间设置是年份在前,那么把年份放在月份前面// d: <*.d ...

  3. SSRS Report Knowledge Base

    1. 获取Textbox的值,根据Textbox值更改单元格颜色 Textbox值:=ReportItems!Textbox1.Value 当前单元格的值:=Me.Value =IIF(ReportI ...

  4. CentOS7 一键安装KMS服务【整理】

    KMS,是 Key Management System 的缩写,也就是密钥管理系统.这里所说的 KMS,毋庸置疑就是用来激活 VOL 版本的 Windows 和 Office 的 KMS 啦.经常能在 ...

  5. nltk模块

    1. nltk简介 http://www.nltk.org 2. nltk能做什么? 2.1 搜索文本 单词搜索 相似词搜索 相似关键词识别 词汇分布图 生成文本 from nltk.book imp ...

  6. smarty assign 赋值

    assign赋值 void assign (mixed var) void assign (string varname, mixed var) This is used to assign valu ...

  7. Springmvc file多附件上传 显示 删除操作

    之前项目需求要做一个多附件上传 并显示上传文件 带删除操作 一筹莫展之际搜到某个兄弟发的博客感觉非常好用被我copy下来了此贴算是改良版 再次感谢(忘记叫什么了时间也有点久没有历史记录了)先上图 基于 ...

  8. php foreach遍历

    foreach($facility_list['data'] as $facility){ //处理语句} 第一种格式遍历给定的 array_expression_r_r 数组.每次循环中,当前单元的 ...

  9. How to limit Dialog's max height?

    1. We can make it to play trick in code. At Dialog's show function, after app has set contentView, w ...

  10. TransitionEnd事件

    定义和用法: transitionend 事件在 CSS 完成过渡后触发. 注意: 如果过渡在完成前移除,例如 CSS transition-property 属性被移除,过渡事件将不被触发. 浏览器 ...