【Go API 开发实战 7】基础 3:记录和管理 API 日志
記錄和管理 API 日志
本節(jié)核心內(nèi)容
Go 日志包數(shù)量眾多,功能不同、性能不同,本教程介紹一個筆者認(rèn)為比較好的日志庫,并給出原因
介紹如何初始化日志包
介紹如何調(diào)用日志包
介紹如何轉(zhuǎn)存(rotate)日志文件
本小節(jié)源碼下載路徑:demo03
可先下載源碼到本地,結(jié)合源碼理解后續(xù)內(nèi)容,邊學(xué)邊練。
本小節(jié)的代碼是基于 demo02 來開發(fā)的。
日志包介紹
apiserver 所采用的日志包 lexkong/log 是筆者根據(jù)開發(fā)經(jīng)驗,并調(diào)研 GitHub 上的 開源log 包后封裝的一個日志包,也是筆者所在項目使用的日志包。它參考華為 paas-lager,做了一些便捷性的改動,功能完全一樣,只不過更為便捷。相較于 Go 的其他日志包,該日志包有如下特點:
支持日志輸出流配置,可以輸出到 stdout 或 file,也可以同時輸出到 stdout 和 file
支持輸出為 JSON 或 plaintext 格式
支持彩色輸出
支持 log rotate 功能
高性能
初始化日志包
在conf/config.yaml中添加 log 配置
在config/config.go中添加日志初始化代碼
package configimport (.... "github.com/lexkong/log"
....
)
....func Init(cfg string) error {
.... // 初始化配置文件
if err := c.initConfig(); err != nil { return err
} // 初始化日志包
c.initLog()
....
}func (c *Config) initConfig() error {
....
}func (c *Config) initLog() {
passLagerCfg := log.PassLagerCfg {
Writers: viper.GetString("log.writers"),
LoggerLevel: viper.GetString("log.logger_level"),
LoggerFile: viper.GetString("log.logger_file"),
LogFormatText: viper.GetBool("log.log_format_text"),
RollingPolicy: viper.GetString("log.rollingPolicy"),
LogRotateDate: viper.GetInt("log.log_rotate_date"),
LogRotateSize: viper.GetInt("log.log_rotate_size"),
LogBackupCount: viper.GetInt("log.log_backup_count"),
}
log.InitWithConfig(&passLagerCfg)
}
// 監(jiān)控配置文件變化并熱加載程序func (c *Config) watchConfig() {
....
}
這里要注意,日志初始化函數(shù)c.initLog()要放在配置初始化函數(shù)
c.initConfig()之后,因為日志初始化函數(shù)要讀取日志相關(guān)的配置。
func (c *Config) initLog()是日志初始化函數(shù),會設(shè)置日志包的各項參數(shù),參數(shù)為:
writers:輸出位置,有兩個可選項 —— file 和 stdout。選擇 file 會將日志記錄到 logger_file 指定的日志文件中,選擇 stdout 會將日志輸出到標(biāo)準(zhǔn)輸出,當(dāng)然也可以兩者同時選擇
logger_level:日志級別,DEBUG、INFO、WARN、ERROR、FATAL
logger_file:日志文件
log_format_text:日志的輸出格式,JSON 或者 plaintext,true 會輸出成非 JSON 格式,false 會輸出成 JSON 格式
rollingPolicy:rotate 依據(jù),可選的有 daily 和 size。如果選 daily 則根據(jù)天進(jìn)行轉(zhuǎn)存,如果是 size 則根據(jù)大小進(jìn)行轉(zhuǎn)存
log_rotate_date:rotate 轉(zhuǎn)存時間,配 合rollingPolicy: daily 使用
log_rotate_size:rotate 轉(zhuǎn)存大小,配合 rollingPolicy: size 使用
log_backup_count:當(dāng)日志文件達(dá)到轉(zhuǎn)存標(biāo)準(zhǔn)時,log 系統(tǒng)會將該日志文件進(jìn)行壓縮備份,這里指定了備份文件的最大個數(shù)
調(diào)用日志包
日志初始化好了,將 demo02 中的 log 用 lexkong/log 包來替換。替換前(這里 grep 出了需要替換的行,讀者可自行確認(rèn)替換后的效果):
$ grep log * -Rconfig/config.go: "log"
config/config.go: log.Printf("Config file changed: %s", e.Name)
main.go: "log"
main.go: log.Fatal("The router has no response, or it might took too long to start up.", err)
main.go: log.Print("The router has been deployed successfully.")
main.go: log.Printf("Start to listening the incoming requests on http address: %s", viper.GetString("addr"))
main.go: log.Printf(http.ListenAndServe(viper.GetString("addr"), g).Error())
main.go: log.Print("Waiting for the router, retry in 1 second.")
替換后的源碼文件見 demo03。
編譯并運行
下載 apiserver_demos 源碼包(如前面已經(jīng)下載過,請忽略此步驟)
將 apiserver_demos/demo03復(fù)制為 $GOPATH/src/apiserver
在 apiserver 目錄下編譯源碼
$ gofmt -w .
$ go tool vet .
$ go build -v .
啟動 apiserver
啟動后,可以看到 apiserver 有 JSON 格式的日志輸出:
管理日志文件
這里將日志轉(zhuǎn)存策略設(shè)置為size,轉(zhuǎn)存大小設(shè)置為 1 MB
rollingPolicy: sizelog_rotate_size: 1
并在main函數(shù)中加入測試代碼:
啟動 apiserver 后發(fā)現(xiàn),在當(dāng)前目錄下創(chuàng)建了 log/apiserver.log 日志文件:
$ ls log/
apiserver.log
程序運行一段時間后,發(fā)現(xiàn)又創(chuàng)建了 zip 文件:
$ ls log/
apiserver.log apiserver.log.20180531134509631.zip
該 zip 文件就是當(dāng) apiserver.log 大小超過 1MB 后,日志系統(tǒng)將之前的日志壓縮成 zip 文件后的文件。
小結(jié)
本小節(jié)通過具體實例講解了如何配置、使用和管理日志。
本系列文章轉(zhuǎn)載自公眾號:騰訊游戲存儲與計算技術(shù) 微信號: game_infra
總結(jié)
以上是生活随笔為你收集整理的【Go API 开发实战 7】基础 3:记录和管理 API 日志的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Go API 开发实战】Go API
- 下一篇: 【Go API 开发实战 5】基础1:启