Golang中日志使用詳解
日志庫介紹
rotatelogs "github.com/lestrrat-go/file-rotatelogsgithub.com/rifflock/lfshookgithub.com/sirupsen/logrus
這三個(gè)包通常被一起使用是為了實(shí)現(xiàn)日志文件的輪轉(zhuǎn)(log rotation)功能。解釋一下它們的作用:github.com/lestrrat-go/file-rotatelogs:- 這是一個(gè)用于文件日志輪轉(zhuǎn)的 Go 語言包。它允許你創(chuàng)建按時(shí)間輪轉(zhuǎn)的日志文件,確保日志文件不會(huì)無限制地增長(zhǎng),而是會(huì)按照一定的規(guī)則進(jìn)行切割,例如按天、按小時(shí)等。
github.com/rifflock/lfshook:- 這是 Logrus(一個(gè) Go 語言的日志庫)的一個(gè)鉤子(hook)。Logrus 是一個(gè)功能強(qiáng)大的日志庫,而 lfshook 允許你將 Logrus 的日志輸出寫入到文件,并且可以結(jié)合
github.com/lestrrat-go/file-rotatelogs這個(gè)包,實(shí)現(xiàn)日志文件的定期輪轉(zhuǎn)。
- 這是 Logrus(一個(gè) Go 語言的日志庫)的一個(gè)鉤子(hook)。Logrus 是一個(gè)功能強(qiáng)大的日志庫,而 lfshook 允許你將 Logrus 的日志輸出寫入到文件,并且可以結(jié)合
github.com/sirupsen/logrus:- Logrus 是一個(gè)非常流行的 Go 語言日志庫,提供了豐富的日志功能。它支持日志級(jí)別、字段結(jié)構(gòu)化輸出等特性,使得日志記錄變得更加靈活和可定制。
綜合使用這三個(gè)包的方式,你可以在應(yīng)用程序中使用 Logrus 進(jìn)行日志記錄,并通過 lfshook 將日志輸出到文件,同時(shí)利用 file-rotatelogs 來管理日志文件的輪轉(zhuǎn),以防止日志文件無限增長(zhǎng)而導(dǎo)致的存儲(chǔ)問題。這樣的組合可以確保你的應(yīng)用程序能夠高效地記錄日志,并在需要時(shí)保持日志文件的可管理性。
簡(jiǎn)單日志記錄
這是一個(gè)簡(jiǎn)單的日志包(clog)的實(shí)現(xiàn),使用 Logrus、file-rotatelogs 和 lfshook 這三個(gè)包來實(shí)現(xiàn)日志記錄和輪轉(zhuǎn)的功能。
package clog
import (
"fmt"
"os"
"path"
"time"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
)
// 日志文件路徑和文件名
var (
logFilePath = "./log/"
logFileName = "system.log"
)
// Logger 是日志記錄器實(shí)例
var Logger *logrus.Logger
// init 函數(shù)在包被導(dǎo)入時(shí)執(zhí)行,用于初始化日志設(shè)置
func init() {
// 初始化日志記錄器
Logger = logrus.New()
// 設(shè)置日志級(jí)別為 Debug
Logger.SetLevel(logrus.DebugLevel)
// 設(shè)置輸出到文件
fileName := path.Join(logFilePath, logFileName)
src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Println("err", err)
}
Logger.Out = src
// 設(shè)置 rotatelogs,實(shí)現(xiàn)日志文件輪轉(zhuǎn)
logWriter, _ := rotatelogs.New(
fileName+".%Y%m%d.log",
rotatelogs.WithLinkName(fileName),
rotatelogs.WithMaxAge(15*24*time.Hour),
rotatelogs.WithRotationTime(24*time.Hour),
)
// 配置 lfshook,將不同日志級(jí)別的日志寫入同一個(gè)文件
writeMap := lfshook.WriterMap{
logrus.InfoLevel: logWriter,
logrus.FatalLevel: logWriter,
logrus.DebugLevel: logWriter,
logrus.WarnLevel: logWriter,
logrus.ErrorLevel: logWriter,
logrus.PanicLevel: logWriter,
}
// 添加 lfshook 到 Logger
Logger.AddHook(lfshook.NewHook(writeMap, &logrus.TextFormatter{
TimestampFormat: "2006-01-02 15:04:05",
}))
}
// Add 函數(shù)用于添加日志記錄
func Add(requestId, info string, err error) {
if err != nil {
// 如果有錯(cuò)誤,記錄 Error 級(jí)別的日志
Logger.WithFields(logrus.Fields{
"request_id": requestId,
"info": info,
"error": err.Error(),
}).Error()
} else {
// 如果沒有錯(cuò)誤,記錄 Info 級(jí)別的日志
Logger.WithFields(logrus.Fields{
"request_id": requestId,
"info": info,
"error": "",
}).Info()
}
}
logFilePath和logFileName定義了日志文件的路徑和名稱。Logger是 logrus 的日志記錄器實(shí)例。init函數(shù)在包被導(dǎo)入時(shí)執(zhí)行,用于初始化 Logger、設(shè)置日志級(jí)別、輸出到文件、配置文件輪轉(zhuǎn)等。rotatelogs.New創(chuàng)建了一個(gè)按時(shí)間輪轉(zhuǎn)的日志寫入器。lfshook.WriterMap定義了不同日志級(jí)別對(duì)應(yīng)的寫入器,確保不同級(jí)別的日志寫入到同一個(gè)文件。lfshook.NewHook創(chuàng)建了一個(gè) lfshook 鉤子,將其添加到 Logger 中。Add函數(shù)用于添加日志記錄,根據(jù)是否有錯(cuò)誤來選擇記錄 Info 或 Error 級(jí)別的日志。
結(jié)合Gin框架使用
這是一個(gè)基于 Gin 框架的中間件(LoggerMiddleware),用于記錄請(qǐng)求的相關(guān)信息
package auth
import (
"encoding/json"
"fmt"
"time"
"go-yinhe-cloud/middleware/clog"
"go-yinhe-cloud/models"
"go-yinhe-cloud/pkg/util"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
// LoggerMiddleware 返回一個(gè) Gin 中間件,用于記錄請(qǐng)求日志
func LoggerMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 記錄請(qǐng)求開始時(shí)間
startTime := time.Now()
// 處理請(qǐng)求
c.Next()
// 記錄請(qǐng)求結(jié)束時(shí)間
endTime := time.Now()
// 計(jì)算請(qǐng)求執(zhí)行時(shí)間
latencyTime := endTime.Sub(startTime)
// 獲取請(qǐng)求相關(guān)信息
reqMethod := c.Request.Method // 請(qǐng)求方式
reqUrl := c.Request.RequestURI // 請(qǐng)求路由
statusCode := c.Writer.Status() // 狀態(tài)碼
clientIP := c.ClientIP() // 請(qǐng)求IP
header := c.GetHeader("User-Agent") + "@@" + c.GetHeader("token") // 請(qǐng)求頭
_ = c.Request.ParseMultipartForm(128)
reqForm := c.Request.Form
var reqJsonStr string
// 將請(qǐng)求數(shù)據(jù)轉(zhuǎn)為 JSON 字符串
if len(reqForm) > 0 {
reqJsonByte, _ := json.Marshal(reqForm)
reqJsonStr = string(reqJsonByte)
}
// 獲取請(qǐng)求中的 requestId
requestId := c.GetString("requestId")
// 獲取 Gin 中間件中的錯(cuò)誤信息
var errorsStr string
for _, err := range c.Errors.Errors() {
errorsStr += err + "; "
}
// 記錄請(qǐng)求日志到文件
clog.Logger.WithFields(logrus.Fields{
"request_id": requestId,
"status_code": statusCode,
"latency_time": latencyTime,
"client_ip": clientIP,
"req_method": reqMethod,
"ua_token": header,
"req_uri": reqUrl,
"body": reqJsonStr,
"err_str": errorsStr,
}).Info()
}
}
- LoggerMiddleware 返回一個(gè) Gin 中間件函數(shù)。
- 記錄請(qǐng)求開始時(shí)間和結(jié)束時(shí)間,計(jì)算請(qǐng)求執(zhí)行時(shí)間。
- 獲取請(qǐng)求的方法、路由、狀態(tài)碼、IP、請(qǐng)求頭等信息。
- 將請(qǐng)求數(shù)據(jù)轉(zhuǎn)為 JSON 字符串。
- 獲取 Gin 中間件中的錯(cuò)誤信息,并拼接成字符串。
- 記錄請(qǐng)求日志到文件,使用 clog.Logger。
以上就是Golang中日志使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Golang日志使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go語言實(shí)現(xiàn)對(duì)稱加密和非對(duì)稱加密的示例代碼
本文主要介紹了Go語言實(shí)現(xiàn)對(duì)稱加密和非對(duì)稱加密的示例代碼,通過實(shí)際代碼示例展示了如何在Go中實(shí)現(xiàn)這兩種加密方式,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
Go語言標(biāo)準(zhǔn)庫之strconv的使用
本文主要介紹了Go語言標(biāo)準(zhǔn)庫之strconv的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
Go語言如何高效的進(jìn)行字符串拼接(6種方式對(duì)比分析)
本文主要介紹了Go語言如何高效的進(jìn)行字符串拼接(6種方式對(duì)比分析),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
Gin 框架快速創(chuàng)建靜態(tài)文件下載Web服務(wù)
本文主要介紹了Gin 框架快速創(chuàng)建靜態(tài)文件下載Web服務(wù),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
go語言如何使用gin庫實(shí)現(xiàn)SSE長(zhǎng)連接
所謂長(zhǎng)連接指在一個(gè)TCP連接上可以連續(xù)發(fā)送多個(gè)數(shù)據(jù)包,在TCP連接保持期間,如果沒有數(shù)據(jù)包發(fā)送,需要雙方發(fā)檢測(cè)包以維持此連接,一般需要自己做在線維持,下面這篇文章主要給大家介紹了關(guān)于go語言如何使用gin庫實(shí)現(xiàn)SSE長(zhǎng)連接的相關(guān)資料,需要的朋友可以參考下2023-06-06
Go語言編程通過dwarf獲取內(nèi)聯(lián)函數(shù)
這篇文章主要為大家介紹了Go語言編程通過dwarf獲取內(nèi)聯(lián)函數(shù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11

