Golang項目中,需要增加循環日志功能,但是從網上資料看,Go本身log包,功能比較簡單,只提供了基本的日志輸出,
並且沒有日志級別控制,日志文件分割和回滾,以及日志分發等功能。
查閱幾篇網絡資料,決定引入logrus軟件包,它完全兼容golang標准庫日志模塊:擁有六種日志級別:debug、info、
warn、error、fatal和panic,這是golang標准庫日志模塊的API的超集。其他特性,可以參考文末的網絡鏈接中的內容。
Go軟件包
需要引入的軟件包如下:
"github.com/sirupsen/logrus"
"github.com/lestrrat-go/file-rotatelogs"
"github.com/rifflock/lfshook"
其中 logrus 是基本的軟件包,可以提供多種級別日志接口,可以通過其hook機制,將日志進行分發,定制文件輸出格式等。
通過file-rotatelogs包,可以對本地日志文件進行分割,可以按照時間,也可以按照文件大小來實現。lfshook是專門為logrus
定制的本地文件系統鈎子,幫助開發者直接把日志寫入到本地文件系統的文件中。
另外,還需要幾個輔助包,否則編譯不通過。
"github.com/lestrrat-go/strftime"
"github.com/pkg/errors"
"golang.org/x/sys"
循環日志示例代碼:
package main
import (
"fmt"
"path"
"os"
"bufio"
"time"
rotatelogs "github.com/lestrrat-go/file-rotatelogs" /* 引入日志回滾功能 */
"github.com/rifflock/lfshook" /* logrus本地文件系統鈎子 */
"github.com/sirupsen/logrus" /* logrus日志包 */
)
/* 定義日志級別 */
const LOG_TRACE = 0
const LOG_DEBUG = 1
const LOG_INFO = 2
const LOG_WARN = 3
const LOG_ERROR = 4
const LOG_FATAL = 5
const LOG_PANIC = 6
/* 創建logrus日志實例 */
var Logger = logrus.New()
/* 使用閉包特性,初始化帶回滾功能的logrus日志環境 */
func LoggerToFile() func(int, ...interface{}){
/* 日志路徑和名稱 */
logFilePath := "/home/goproject/log"
logFileName := "helloworld"
partFileName := path.Join(logFilePath, logFileName)
/* 禁止日志打印到標准輸出stdout */
devnull, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Printf("LoggerToFile open os.DevNull failed: ", err)
}
writernull := bufio.NewWriter(devnull)
Logger.SetOutput(writernull)
/* 設置默認日志級別為 INFO */
Logger.SetLevel(logrus.InfoLevel)
/* 創建日志回滾實例,日志名稱格式,日志回滾模式(日志每20M回滾,保留10各日志文件) */
logWriter, err := rotatelogs.New(
partFileName+".%Y%m%d.log",
rotatelogs.WithLinkName(logFileName+".log"), /* 鏈接文件,鏈接到當前實際的日志文件 */
rotatelogs.WithRotationSize(20*1024*1024),
rotatelogs.WithRotationCount(10),
)
/* 日志輸出到本地文件系統,不同級別都輸出到相同的日志中 */
writeMap := lfshook.WriterMap{
logrus.InfoLevel: logWriter,
logrus.FatalLevel: logWriter,
logrus.DebugLevel: logWriter,
logrus.WarnLevel: logWriter,
logrus.ErrorLevel: logWriter,
logrus.PanicLevel: logWriter,
}
/* 創建新的lfs鈎子 */
lfHook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{
TimestampFormat:"2006-01-02 15:04:05",
})
/* logrus實例添加lfshook鈎子 */
Logger.AddHook(lfHook)
/* 返回日志函數實例,這里可以根據level參數,實現不同級別的日志輸出控制 */
return func(level int, args ...interface{}) {
loginfo := fmt.Sprintf("%v", args)
Logger.WithFields(logrus.Fields{
"module": "helloworld",
}).Info(loginfo)
}
}
/* 創建一個日志函數實例(閉包) */
var TestLog = LoggerToFile()
func main() {
TestLog(LOG_DEBUG, "Hello, World!")
fmt.Println("Hello, World!")
count := 0
for {
TestLog(LOG_INFO, "No.", count, "sleep 2s......")
fmt.Println("No.", count, "sleep 20s......")
count++
time.Sleep(2*time.Second)
}
}
日志文件:
實際日志輸出到/home/goproject/log目錄下,日志文件名為helloworld.YYYYMMDD.log形式;helloworld.log為當前日志文件的鏈接

日志內容:

參考資料:
https://studygolang.com/articles/18494
https://studygolang.com/articles/26516
https://studygolang.com/articles/30220
【4】golang使用日志分割
https://studygolang.com/articles/31475
【5】Local Filesystem Hook for Logrus
https://github.com/rifflock/lfshook
【6】Go語言閉包(Closure)——引用了外部變量的匿名函數
