seelog 使用笔记
一、简介
最近两个月都在写 Golang 的项目,作为一个日志狂人,当然首先要找一款用的顺手的日志模块,搜了一圈后选择了 seelog。
下面是项目地址:
seelog 功能非常强大,简要概括下:
- 可以设置分级日志;
- 可以输出到命令行或文件;
- 可以定义多种日志的格式;
- 可以根据触发日志的文件名、函数名来区别输出日志;
- 可以通过 SMTP 或 TCP 转发日志;
- 可以滚动日志文件。
二、使用
1、记录日志
稍后会介绍如何配置,假设我们已经配置好了日志,那么在程序中记录日志非常简单:
import (
log "github.com/cihub/seelog"
)
func main() {
// 记录日志后需要 flush
defer log.Flush()
// 从上往下,级别依次升高
log.Trace("trace: xxx")
log.Debug("debug: xxx")
log.Info("info: xxx")
log.Warn("warn: xxx")
log.Error("error: xxx")
log.Critical("critical: xxx")
}
三、配置
1、启用配置
seelog 采取配置文件的形式来配置,比如我们可以在项目根路径创建一个 seelog.xml
,然后在 main 文件内写:
func main() {
logger, err := log.LoggerFromConfigAsFile("seelog.xml")
if err != nil {
panic(err.Error())
}
}
除了配置文件外,也可以直接通过字符串的形式来配置
log.LoggerFromConfigAsBytes(configInBytes)
如果你使用 beego,可以替换 beego 的日志:
import (
log "github.com/cihub/seelog"
)
func SetupLogger() {
logger, err := log.LoggerFromConfigAsFile("seelog.xml")
if err != nil {
return
}
log.ReplaceLogger(logger)
}
2、简单配置
先讲一个最简单的配置文件范例:
<seelog type="asynctimer" asyncinterval="1000000" minlevel="debug" maxlevel="error">
<outputs formatid="main">
<!-- 唯一的输出:控制台 -->
<console/>
</outputs>
<formats>
<!-- 设置格式 -->
<format id="main" format="%UTCDate %UTCTime - [%LEV] - %RelFile - l%Line - %Msg%n"/>
</formats>
</seelog>
四、详细配置
下面介绍一些详细的细节配置。
1、Constraints 级别限制
用于配置接受的日志级别:
<!-- 设置接受的最小和最大级别 -->
<seelog minlevel="info" maxlevel="error">
<!-- 设置接受的级别 -->
<seelog levels="trace,info,critical">
可以在全局的 <seelog />
或 <exception />
上配置。
2、Exceptions
不同于 <seelog />
是全局配置,<exception />
是为特定的程序文件或函数设定特殊的日志规则。
有两种匹配方式:
filepattern
:根据文件名来匹配;funcpattern
:根据函数名来匹配。
<seelog minlevel="info">
<exceptions> <!-- 首先声明一个 exceptions 段 -->
<!-- 为 test 开头的文件开启 debug 级别的日志 -->
<exception filepattern="test*" minlevel="debug"/>
<!-- 为 main.testFunc 函数开启 debug 级别的日志 -->
<exception funcpattern="main.testFunc" minlevel="debug"/>
</exceptions>
</seelog>
3、Dispatcher 分发日志
有三个关键字:
outputs
用于定义输出块,在 outpus
内定义具体的输出方式和格式。spliter
和 filter
都定义在 outputs
块内。
<outputs>
<splitter>...</splitter>
<filter>...</filter>
</outputs>
spliter
用于指定格式,内部可以包含多个 receiver。
<!-- 通过 formatid 定义适用的日志格式 -->
<splitter formatid="common">
...
</splitter>
filter
用于指定接收的日志级别,内部可以包含多个 receiver。
<!-- 通过 levels 定义适用的日志级别 -->
<filter levels="critical">
...
</filter>
一个完整的例子:
<seelog>
<!-- 定义 outputs 块 -->
<outputs>
<!-- splitter 应用格式 -->
<splitter formatid="common">
<console/>
<file path="file.log"/>
<conn addr="192.168.0.2:8123"/>
</splitter>
<!-- filter 应用级别 -->
<filter levels="critical">
<file path="critical.log" formatid="critical"/>
<smtp formatid="criticalemail" 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>
</filter>
</outputs>
<!-- formats 块定义各种格式 -->
<formats>
<format id="common" format="[%LEV] %Msg"/>
<format id="critical" format="%Time %Date %RelFile %Func %Msg"/>
<format id="criticalemail" format="Critical error on our server!\n %Time %Date %RelFile %Func %Msg \nSent by Seelog"/>
</formats>
</seelog>
4、Receiver 处理日志
Receiver 具体定义日志的处理和分发方式,上面示例中出现的 console
, file
, conn
, smtp
都是 receiver 类型。
介绍几种常用的 receiver:
console
最常用的,直接输出到控制台,用 supervisor 等工具管理进程的时候比较方便。
<console/>
file
最简单的输出到文件,不作任何处理。
<file path="<YOUR_LOG_FILE_PATH>"/>
rollingfile
滚动文件,可以按大小或时间滚动日志文件。
滚动是指为了防止文件过大,按一定的规律创建新的日志文件,并且删除过期的日志文件,保证磁盘的使用量不会无限的增长。
可以接受的参数有:
filename
:文件名;type
:data
|size
,滚动的触发条件;maxrolls
:最大文件数;archivetype
:none
|zip
|gzip
;namemode
:prefix | postfix,滚动文件的命名方式;archiveexploded
:archivepath
:当 archivetype 不为 none 时,指定保存的位置;maxsize
:最大大小;datepattern
:指定按事件滚动的触发条件;02.01.2006
指按日滚动;02.01.2006.15
指按时滚动;
fullname
:bool。
<seelog>
<outputs>
<rollingfile type="size" filename="logs/roll.log" maxsize="1000" maxrolls="5" />
</outputs>
</seelog>
buffered
将日志先存在内存中,定期写入文件,适合日志并发量较大或 IO 比较紧张的场合。
参数:
size
:缓存大小;flushperiod
:缓存间隔(毫秒)。
<buffered size="10000" flushperiod="1000" formatid="someFormat">
<rollingfile type="date" filename="logs/roll.log" datepattern="02.01.2006" />
</buffered>
smtp
以邮件的形式发送日志。
参数:
senderaddress
:发信人地址;sendername
:发信人名字;hostname
:邮件服务器地址;hostport
:邮件服务器端口;username
:邮件服务器用户名;password
:邮件服务器密码;subject
:邮件标题;address
:收信人地址;header
name
:value
cacertdirpath
path
<filter levels="error,critical">
<smtp senderaddress="nns@none.org" sendername="ANS" hostname="mail.none.org" hostport="587" username="nns" password="123" subject="test">
<cacertdirpath path="cacdp1"/>
<recipient address="hans-meier@none.com"/>
<header name="Priority" value="Urgent" />
<header name="Importance" value="high" />
<header name="Sensitivity" value="Company-Confidential" />
<header name="Auto-Submitted" value="auto-generated" />
</smtp>
</filter>
conn
通过网络转发,支持多种协议。
参数:
net
:tcp | udp | tcp4 | udp4;addr
:地址;reconnectonmsg
:bool;usetls
:bool;insecureskipverify
:bool。
<conn formatid="syslog" net="tcp4" addr="server.address:5514" tls="true" insecureskipverify="true" />
五、Formats
定义日志格式,如上文中出现的例子,首先定义 formats
块,然后在内部定义任意条 <format id="xxx" format="xxx" />
, 然后就可以在 dispatcher 和 receiver 内通过 formatid="xxx"
的形式来指定格式。
格式其实就是个字符串,通过不同的占位符来显示不同的内容,比如我自己用的格式就是:
<format id="main" format="%UTCDate %UTCTime - [%LEV] - %RelFile - l%Line - %Msg%n"/>
详细的定义可以参见官方文档:https://github.com/cihub/seelog/wiki/Format-reference
六、Example
我根据自己情况做的一些调整
package logger
import (
"bytes"
"fmt"
"html/template"
"strings"
log "github.com/cihub/seelog"
)
func SetupLogger(logLevel, logName string) {
logLevel = strings.ToLower(logLevel)
switch logLevel {
case "trace":
case "debug":
case "info":
case "warn":
case "error":
default:
panic(fmt.Errorf("输入日志级别错误"))
}
defer log.Flush()
args := struct {
LogLevel string
LogName string
}{
LogLevel: logLevel,
LogName: logName,
}
logConfig := `
<seelog type="asynctimer" asyncinterval="1000000" minlevel="{{.LogLevel}}" maxlevel="error">
<exceptions>
<exception funcpattern="*main.test*Something*" minlevel="{{.LogLevel}}"/>
<exception filepattern="*main.go" minlevel="{{.LogLevel}}"/>
</exceptions>
<outputs formatid="main">
<console/> <!-- 输出到控制台 -->
<rollingfile type="date" filename="./log/{{.LogName}}.log" datepattern="02.01.2006" />
</outputs>
<formats>
<format id="main" format="[%Date %Time - %Lev - %RelFile - line:%Line] %Msg%n"/>
</formats>
</seelog>
`
tmpl, err := template.New("seelogConfig").Parse(logConfig)
if err != nil {
panic(err.Error())
}
var configBytes bytes.Buffer
if err := tmpl.Execute(&configBytes, args); err != nil {
panic(err.Error())
}
logger, err := log.LoggerFromConfigAsBytes(configBytes.Bytes())
if err != nil {
panic(err.Error())
}
log.ReplaceLogger(logger)
}
本文摘自 其他网站,但是自己使用的部分代码做了调整
用于个人记录笔记