一、背景介绍
首先,Go没有Exception(Why does Go not have exceptions),它具有自己独特的一套处理错误的方法(Defer, Panic, Recover),所以类似 Java 那样直接 printStackTrace 是不行的。
其次,相比于 Java 里的 log4j、slf4j 等框架,Golang 里的日志框架都显得比较简单,无论是beego的 logs,还是 github.com/Sirupsen/logrus ,亦或是 github.com/golang/glog 。
下面以beego的 logs 为例,介绍通常情况下的 beego 项目的关于日志的设置。
实际使用可参考第六部分 – 样例。
二、如何使用
首先要设置输出引擎,以及配置引擎,然后即可记录日志了。
beego的输出引擎有9种,包括:
const (
AdapterConsole = "console"
AdapterFile = "file"
AdapterMultiFile = "multifile"
AdapterMail = "smtp"
AdapterConn = "conn"
AdapterEs = "es"
AdapterJianLiao = "jianliao"
AdapterSlack = "slack"
AdapterAliLS = "alils"
)
分别表示输出到 console,输出到文件、多个文件、smtp、conn、ES、简聊、slack、alils。
三、引擎配置
console
可以设置输出的级别,或者不设置保持默认,默认输出到 os.Stdout
:
logs.SetLogger(logs.AdapterConsole, `{"level":1}`)
file
设置的例子如下所示:
logs.SetLogger(logs.AdapterFile, `{``"filename"``:``"test.log"``}`)
主要的参数如下说明:
- filename 保存的文件名
- maxlines 每个文件保存的最大行数,默认值 1000000
- maxsize 每个文件保存的最大尺寸,默认值是 1 << 28, //256 MB
- daily 是否按照每天 logrotate,默认是 true
- maxdays 文件最多保存多少天,默认保存 7 天
- rotate 是否开启 logrotate,默认是 true
- level 日志保存的时候的级别,默认是 Trace 级别
- perm 日志文件权限
multifile
设置的例子如下所示:
logs.SetLogger(logs.AdapterMultiFile, `{"filename":"test.log","separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"]}`)
主要的参数如下说明(除 separate 外,均与file相同):
- filename 保存的文件名
- maxlines 每个文件保存的最大行数,默认值 1000000
- maxsize 每个文件保存的最大尺寸,默认值是 1 << 28, //256 MB
- daily 是否按照每天 logrotate,默认是 true
- maxdays 文件最多保存多少天,默认保存 7 天
- rotate 是否开启 logrotate,默认是 true
- level 日志保存的时候的级别,默认是 Trace 级别
- perm 日志文件权限
- separate 需要单独写入文件的日志级别,设置后命名类似 test.error.log
conn
网络输出,设置的例子如下所示:
logs.SetLogger(logs.AdapterConn, `{"net":"tcp","addr":":7020"}`)
主要的参数说明如下:
- reconnectOnMsg 是否每次链接都重新打开链接,默认是 false
- reconnect 是否自动重新链接地址,默认是 false
- net 发开网络链接的方式,可以使用 tcp、unix、udp 等
- addr 网络链接的地址
- level 日志保存的时候的级别,默认是 Trace 级别
smtp
邮件发送:
logs.SetLogger(logs.AdapterMail, `{"username":"beegotest@gmail.com","password":"xxxxxxxx","host":"smtp.gmail.com:587","sendTos":["xiemengjun@gmail.com"]}`)
主要的参数说明如下:
- username smtp 验证的用户名
- password smtp 验证密码
- host 发送的邮箱地址
- sendTos 邮件需要发送的人,支持多个
- subject 发送邮件的标题,默认是
Diagnostic message from server
- level 日志发送的级别,默认是 Trace 级别
Elasticsearch
输出到ES:
logs.SetLogger(logs.AdapterEs, `{"dsn":"http://localhost:9200/","level":1}`)
简聊
输出到简聊:
logs.SetLogger(logs.AdapterJianLiao, `{"authorname":"xxx","title":"beego", "webhookurl":"https://jianliao.com/xxx", "redirecturl":"https://jianliao.com/xxx","imageurl":"https://jianliao.com/xxx","level":1}`)
slack
输出到slack:
logs.SetLogger(logs.AdapterSlack, `{"webhookurl":"https://slack.com/xxx","level":1}`)
四、异步输出日志
为了提升性能, 可以设置异步输出:
logs.Async()
异步输出允许设置缓冲 chan 的大小
logs.Async(1000) // message 的长度,单位是字节,这里设置了1000
五、级别
8个级别:
LevelEmergency = iota // 0
LevelAlert // 1
LevelCritical // 2
LevelError // 3
LevelWarning // 4
LevelNotice // 5
LevelInformational // 6
LevelDebug // 7
各个级别的日志样例:
- Trace (record general information, for example:)
- “Entered parse function validation block”
- “Validation: entered second ‘if'”
- “Dictionary ‘Dict’ is empty. Using default value”
- Debug (debugging information, for example:)
- “Web page requested: http://somesite.com Params = ‘…'”
- “Response generated. Response size: 10000. Sending.”
- “New file received. Type: PNG Size: 20000”
- Info (printing general information, for example:)
- “Web server restarted”
- “Hourly statistics: Requested pages: 12345 Errors: 123…”
- “Service paused. Waiting for ‘resume’ call”
- Warn (warning messages, for example:)
- “Cache corrupted for file = ‘test.file’. Reading from back-end”
- “Database 192.168.0.7/DB not responding. Using backup 192.168.0.8/DB”
- “No response from statistics server. Statistics not sent”
- Error (error messages, for example:)
- “Internal error. Cannot process request# 12345 Error:….”
- “Cannot perform login: credentials DB not responding”
- Critical (fatal errors, for example:)
- “Critical panic received:…. Shutting down”
- “Fatal error:… App is shutting down to prevent data corruption or loss”
说明:
beego为了支持 RFC5424 标准,在某个版本后引入了上面的8个级别,这8个级别是没有 trace,warn,info 的,但是为了和以前的级别兼容:
const (
LevelInfo = LevelInformational
LevelTrace = LevelDebug
LevelWarn = LevelWarning
)
所以某些文档,依然保留了 trace、info、warn等说法。
六、样例
logOutputs
- 在 conf/app.conf 文件里,logOutputs要以分号分割不同的配置,每个配置里以逗号分割 adapter和config,其中config是标准的json格式
logOutputs = multifile,{"filename":"/home/admin/apps/logs/gangas-inbox/gangas-inbox.log", "daily":true, "maxdays":10, "level":6};console,{"level":7}
Async
- 在 main.go 里,设置Async及其大小
logs.Async(1000)
format
- 默认是 APACHE_FORMAT
const (
apacheFormatPattern = "%s - - [%s] \"%s %d %d\" %f %s %s\n"
apacheFormat = "APACHE_FORMAT"
jsonFormat = "JSON_FORMAT"
)
msg = fmt.Sprintf(apacheFormatPattern, r.RemoteAddr, timeFormatted, r.Request, r.Status, r.BodyBytesSent,
r.ElapsedTime.Seconds(), r.HTTPReferrer, r.HTTPUserAgent)