欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang中日志使用詳解

 更新時間:2024年01月19日 08:48:33   作者:莫忘初心丶  
這篇文章記錄了Golang項目中日志使用,以及結(jié)合Gin框架記錄請求日志,文中通過代碼示例介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下

日志庫介紹

  1. rotatelogs "github.com/lestrrat-go/file-rotatelogs

  2. github.com/rifflock/lfshook

  3. github.com/sirupsen/logrus
    這三個包通常被一起使用是為了實現(xiàn)日志文件的輪轉(zhuǎn)(log rotation)功能。解釋一下它們的作用:

  4. github.com/lestrrat-go/file-rotatelogs

    • 這是一個用于文件日志輪轉(zhuǎn)的 Go 語言包。它允許你創(chuàng)建按時間輪轉(zhuǎn)的日志文件,確保日志文件不會無限制地增長,而是會按照一定的規(guī)則進行切割,例如按天、按小時等。
  5. github.com/rifflock/lfshook

    • 這是 Logrus(一個 Go 語言的日志庫)的一個鉤子(hook)。Logrus 是一個功能強大的日志庫,而 lfshook 允許你將 Logrus 的日志輸出寫入到文件,并且可以結(jié)合 github.com/lestrrat-go/file-rotatelogs 這個包,實現(xiàn)日志文件的定期輪轉(zhuǎn)。
  6. github.com/sirupsen/logrus

    • Logrus 是一個非常流行的 Go 語言日志庫,提供了豐富的日志功能。它支持日志級別、字段結(jié)構(gòu)化輸出等特性,使得日志記錄變得更加靈活和可定制。

綜合使用這三個包的方式,你可以在應用程序中使用 Logrus 進行日志記錄,并通過 lfshook 將日志輸出到文件,同時利用 file-rotatelogs 來管理日志文件的輪轉(zhuǎn),以防止日志文件無限增長而導致的存儲問題。這樣的組合可以確保你的應用程序能夠高效地記錄日志,并在需要時保持日志文件的可管理性。

簡單日志記錄

這是一個簡單的日志包(clog)的實現(xiàn),使用 Logrus、file-rotatelogs 和 lfshook 這三個包來實現(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 是日志記錄器實例
var Logger *logrus.Logger

// init 函數(shù)在包被導入時執(zhí)行,用于初始化日志設置
func init() {
	// 初始化日志記錄器
	Logger = logrus.New()

	// 設置日志級別為 Debug
	Logger.SetLevel(logrus.DebugLevel)

	// 設置輸出到文件
	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

	// 設置 rotatelogs,實現(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,將不同日志級別的日志寫入同一個文件
	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 {
		// 如果有錯誤,記錄 Error 級別的日志
		Logger.WithFields(logrus.Fields{
			"request_id": requestId,
			"info":       info,
			"error":      err.Error(),
		}).Error()
	} else {
		// 如果沒有錯誤,記錄 Info 級別的日志
		Logger.WithFields(logrus.Fields{
			"request_id": requestId,
			"info":       info,
			"error":      "",
		}).Info()
	}
}
  • logFilePath 和 logFileName 定義了日志文件的路徑和名稱。
  • Logger 是 logrus 的日志記錄器實例。
  • init 函數(shù)在包被導入時執(zhí)行,用于初始化 Logger、設置日志級別、輸出到文件、配置文件輪轉(zhuǎn)等。
  • rotatelogs.New 創(chuàng)建了一個按時間輪轉(zhuǎn)的日志寫入器。
  • lfshook.WriterMap 定義了不同日志級別對應的寫入器,確保不同級別的日志寫入到同一個文件。
  • lfshook.NewHook 創(chuàng)建了一個 lfshook 鉤子,將其添加到 Logger 中。
  • Add 函數(shù)用于添加日志記錄,根據(jù)是否有錯誤來選擇記錄 Info 或 Error 級別的日志。

結(jié)合Gin框架使用

這是一個基于 Gin 框架的中間件(LoggerMiddleware),用于記錄請求的相關(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 返回一個 Gin 中間件,用于記錄請求日志
func LoggerMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 記錄請求開始時間
		startTime := time.Now()

		// 處理請求
		c.Next()

		// 記錄請求結(jié)束時間
		endTime := time.Now()

		// 計算請求執(zhí)行時間
		latencyTime := endTime.Sub(startTime)

		// 獲取請求相關(guān)信息
		reqMethod := c.Request.Method        // 請求方式
		reqUrl := c.Request.RequestURI       // 請求路由
		statusCode := c.Writer.Status()      // 狀態(tài)碼
		clientIP := c.ClientIP()             // 請求IP
		header := c.GetHeader("User-Agent") + "@@" + c.GetHeader("token") // 請求頭
		_ = c.Request.ParseMultipartForm(128)
		reqForm := c.Request.Form
		var reqJsonStr string

		// 將請求數(shù)據(jù)轉(zhuǎn)為 JSON 字符串
		if len(reqForm) > 0 {
			reqJsonByte, _ := json.Marshal(reqForm)
			reqJsonStr = string(reqJsonByte)
		}

		// 獲取請求中的 requestId
		requestId := c.GetString("requestId")

		// 獲取 Gin 中間件中的錯誤信息
		var errorsStr string
		for _, err := range c.Errors.Errors() {
			errorsStr += err + "; "
		}

		// 記錄請求日志到文件
		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 返回一個 Gin 中間件函數(shù)。
  • 記錄請求開始時間和結(jié)束時間,計算請求執(zhí)行時間。
  • 獲取請求的方法、路由、狀態(tài)碼、IP、請求頭等信息。
  • 將請求數(shù)據(jù)轉(zhuǎn)為 JSON 字符串。
  • 獲取 Gin 中間件中的錯誤信息,并拼接成字符串。
  • 記錄請求日志到文件,使用 clog.Logger。

以上就是Golang中日志使用詳解的詳細內(nèi)容,更多關(guān)于Golang日志使用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • go語言程序cpu過高問題排查的方法詳解

    go語言程序cpu過高問題排查的方法詳解

    使用golang進行復雜的組合運算,導致CPU占用率非常高,下面這篇文章主要給大家介紹了關(guān)于go語言程序cpu過高問題排查的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-04-04
  • Go語言interface詳解

    Go語言interface詳解

    這篇文章主要介紹了Go語言interface詳解,本文講解了什么是interface、interface類型、interface值、空interface、interface函數(shù)參數(shù)等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • Go語言實現(xiàn)對稱加密和非對稱加密的示例代碼

    Go語言實現(xiàn)對稱加密和非對稱加密的示例代碼

    本文主要介紹了Go語言實現(xiàn)對稱加密和非對稱加密的示例代碼,通過實際代碼示例展示了如何在Go中實現(xiàn)這兩種加密方式,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Go語言標準庫之strconv的使用

    Go語言標準庫之strconv的使用

    本文主要介紹了Go語言標準庫之strconv的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • Go語言如何高效的進行字符串拼接(6種方式對比分析)

    Go語言如何高效的進行字符串拼接(6種方式對比分析)

    本文主要介紹了Go語言如何高效的進行字符串拼接(6種方式對比分析),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • Gin 框架快速創(chuàng)建靜態(tài)文件下載Web服務

    Gin 框架快速創(chuàng)建靜態(tài)文件下載Web服務

    本文主要介紹了Gin 框架快速創(chuàng)建靜態(tài)文件下載Web服務,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • go語言如何使用gin庫實現(xiàn)SSE長連接

    go語言如何使用gin庫實現(xiàn)SSE長連接

    所謂長連接指在一個TCP連接上可以連續(xù)發(fā)送多個數(shù)據(jù)包,在TCP連接保持期間,如果沒有數(shù)據(jù)包發(fā)送,需要雙方發(fā)檢測包以維持此連接,一般需要自己做在線維持,下面這篇文章主要給大家介紹了關(guān)于go語言如何使用gin庫實現(xiàn)SSE長連接的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • Go語言編程通過dwarf獲取內(nèi)聯(lián)函數(shù)

    Go語言編程通過dwarf獲取內(nèi)聯(lián)函數(shù)

    這篇文章主要為大家介紹了Go語言編程通過dwarf獲取內(nèi)聯(lián)函數(shù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • 在go語言中安裝與使用protobuf的方法詳解

    在go語言中安裝與使用protobuf的方法詳解

    protobuf以前只支持C++, Python和Java等語言, Go語言出來后, 作為親兒子, 那有不支持的道理呢? 這篇文章主要給大家介紹了關(guān)于在go語言中使用protobuf的相關(guān)資料,文中介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08
  • 大多數(shù)Go程序員都走過的坑盤點解析

    大多數(shù)Go程序員都走過的坑盤點解析

    這篇文章主要為大家介紹了大多數(shù)Go程序員都走過的坑盤點解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12

最新評論