Golang中记录日志详解

这篇具有很好参考价值的文章主要介绍了Golang中记录日志详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

记录下Golang项目中日志使用,以及结合Gin框架记录请求日志。


日志库介绍

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

  2. github.com/rifflock/lfshook

  3. github.com/sirupsen/logrus
    这三个包通常被一起使用是为了实现日志文件的轮转(log rotation)功能。解释一下它们的作用:

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

    • 这是一个用于文件日志轮转的 Go 语言包。它允许你创建按时间轮转的日志文件,确保日志文件不会无限制地增长,而是会按照一定的规则进行切割,例如按天、按小时等。
  5. github.com/rifflock/lfshook

    • 这是 Logrus(一个 Go 语言的日志库)的一个钩子(hook)。Logrus 是一个功能强大的日志库,而 lfshook 允许你将 Logrus 的日志输出写入到文件,并且可以结合 github.com/lestrrat-go/file-rotatelogs 这个包,实现日志文件的定期轮转。
  6. github.com/sirupsen/logrus

    • Logrus 是一个非常流行的 Go 语言日志库,提供了丰富的日志功能。它支持日志级别、字段结构化输出等特性,使得日志记录变得更加灵活和可定制。

综合使用这三个包的方式,你可以在应用程序中使用 Logrus 进行日志记录,并通过 lfshook 将日志输出到文件,同时利用 file-rotatelogs 来管理日志文件的轮转,以防止日志文件无限增长而导致的存储问题。这样的组合可以确保你的应用程序能够高效地记录日志,并在需要时保持日志文件的可管理性。

简单日志记录

这是一个简单的日志包(clog)的实现,使用 Logrus、file-rotatelogs 和 lfshook 这三个包来实现日志记录和轮转的功能。

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 函数在包被导入时执行,用于初始化日志设置
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,实现日志文件轮转
	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 函数用于添加日志记录
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()
	}
}
  • logFilePathlogFileName 定义了日志文件的路径和名称。
  • Logger 是 logrus 的日志记录器实例。
  • init 函数在包被导入时执行,用于初始化 Logger、设置日志级别、输出到文件、配置文件轮转等。
  • rotatelogs.New 创建了一个按时间轮转的日志写入器。
  • lfshook.WriterMap 定义了不同日志级别对应的写入器,确保不同级别的日志写入到同一个文件。
  • lfshook.NewHook 创建了一个 lfshook 钩子,将其添加到 Logger 中。
  • Add 函数用于添加日志记录,根据是否有错误来选择记录 Info 或 Error 级别的日志。

结合Gin框架使用

这是一个基于 Gin 框架的中间件(LoggerMiddleware),用于记录请求的相关信息文章来源地址https://www.toymoban.com/news/detail-804539.html

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()

		// 记录请求结束时间
		endTime := time.Now()

		// 计算请求执行时间
		latencyTime := endTime.Sub(startTime)

		// 获取请求相关信息
		reqMethod := c.Request.Method        // 请求方式
		reqUrl := c.Request.RequestURI       // 请求路由
		statusCode := c.Writer.Status()      // 状态码
		clientIP := c.ClientIP()             // 请求IP
		header := c.GetHeader("User-Agent") + "@@" + c.GetHeader("token") // 请求头
		_ = c.Request.ParseMultipartForm(128)
		reqForm := c.Request.Form
		var reqJsonStr string

		// 将请求数据转为 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 中间件函数。
  • 记录请求开始时间和结束时间,计算请求执行时间。
  • 获取请求的方法、路由、状态码、IP、请求头等信息。
  • 将请求数据转为 JSON 字符串。
  • 获取 Gin 中间件中的错误信息,并拼接成字符串。
  • 记录请求日志到文件,使用 clog.Logger。

到了这里,关于Golang中记录日志详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Golang 结构化日志包 log/slog 详解(二):Handler

    上一篇文章介绍了推出 log/slog 包的背景、log/slog 包的简单介绍和使用,简单使用了 Info 函数,例如: 这段代码输出的内容如下: 默认情况下,输出的日志格式是普通的 text 格式,这种格式并不是最适合日志系统的格式。日志系统一般采用 SON 格式或者 key=value 类型的文本格式

    2024年02月09日
    浏览(49)
  • 【Golang】go编程语言适合哪些项目开发?

    前言 在当今数字化时代,软件开发已成为各行各业的核心需求之一。 而选择适合的编程语言对于项目的成功开发至关重要。 本文将重点探讨Go编程语言适合哪些项目开发,以帮助读者在选择合适的编程语言时做出明智的决策。 Go 编程语言适合哪些项目开发? Go是由Google开发

    2024年02月04日
    浏览(80)
  • 【后端学习笔记·Golang】邮箱邮件验证

    流程: 接收用户请求后生成随机验证码,并将验证码存入Redis中,并设置TTL 通过gomail发送验证码给用户邮箱 接收用户输入的验证码,与Redis中存放的验证码进行比对 ​ 随机种子通过 time.Now().UnixNano() 进行设置,以确保对于同一个用户每次请求都使用不同的种子。然后,定义

    2024年04月26日
    浏览(50)
  • golang iris框架 + linux后端运行

    打包应用 开启服务 关闭后台 杀死进程 通过 ps -ef|grep main 找到应用出现 找到应用的( PID(一般是第一个数字) )

    2024年02月07日
    浏览(56)
  • golang 日志库logrus实践

    logrus 完全兼容标准的 log 库,还支持文本、JSON 两种日志输出格式。很多知名的开源项目都使用了这个库,如大名鼎鼎的 docker。 第三方库需要先安装: 后使用: logrus 的使用非常简单,与标准库 log 类似。 logrus 支持更多的日志级别: Panic :记录日志,然后 panic 。 Fatal :致

    2024年02月17日
    浏览(45)
  • golang判断目录是否存在和生成日志文件

    package main import (     \\\"fmt\\\"     \\\"io\\\"     \\\"os\\\"     \\\"time\\\"     \\\"github.com/sirupsen/logrus\\\" ) func main() {     defer func() {         err := recover()         if err != nil {             logrus.Info(err)         }     }()     log_path := \\\"runtime/logs/\\\"     _, err := os.Stat(log_path)     if err != nil {         i

    2024年02月16日
    浏览(59)
  • 使用golang实现日志收集系统的logagent

    参考 七米老师的日志收集项目 主要用go实现logagent的部分,logagent的作用主要是实时监控日志追加的变化,并将变化发送到kafka中。 之前我们已经实现了 用go连接kafka并向其中发送数据,也实现了使用tail库监控日志追加操作。 我们把这两部分结合起来实现监控日志追加并发送

    2023年04月20日
    浏览(35)
  • Golang一日一库之 日志库 zap

    在开发过程中 会使用到日志库去记录错误的日志,尤其是golang中 有无穷无尽的error 如果不记录,当你的代码出错,就无从排错了。 zap 是开源的 Go 高性能日志库 主要有以下特点: 支持不同的日志级别 能够打印基本信息等但不支持日志的分割 但是可以使用 lumberjack 也是 za

    2023年04月12日
    浏览(50)
  • Golang踩坑记录

    系统幂等校验 平时 Golang 开发中会遇到的“坑点”,总结一下,避免重复踩坑 看代码,答问题 结果: 再看如下代码: 结果: 分析 在Go语言中,一个 interface{} 类型的变量包含两个指针,一个指向其类型,另一个指向真正的值。只有当类型和值都是nil的时候,才等于nil。 当我

    2024年02月13日
    浏览(40)
  • golang 锁bug 记录

    例如 会先获取了读锁,协程里面有个写锁,如果整体还嵌套了读锁,直接出现死锁了 ,卡在all_lock_test.RLock() ,读锁永远也不能释放了

    2024年04月29日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包