• Logrus日志框架:简介与入门指南


    GitHub 仓库:https://github.com/sirupsen/logrus

    简介

    Logrus是一个流行的Go语言日志库,提供了丰富的日志输出和格式化功能。它被广泛应用于Go语言项目中,用于记录程序的运行状态、错误信息和调试信息等。

    Logrus具有以下特点:

    1. 灵活的日志级别:Logrus支持多种日志级别,包括调试、信息、警告、错误和致命等级别,可以根据不同的需求设置日志级别。

    2. 多种输出格式:Logrus支持多种输出格式,包括文本格式、JSON格式等,可以根据需要选择适合的格式。

    3. 可扩展的钩子机制:Logrus提供了钩子(hook)机制,可以自定义日志的输出方式,比如将日志发送到远程服务器、写入文件等。

    4. 上下文(context)日志:Logrus支持给日志添加上下文信息,可以很方便地记录一些附加的上下文数据,比如请求ID、用户ID等。

    5. 日志字段标签化:Logrus支持为日志字段添加标签(Field Tags),可以更好地组织和搜索日志信息。

    安装

    在Go语言项目中使用 Logrus 需要先安装 Logrus 库,然后在代码中引入即可。

    1. 安装 Logrus 库:

      使用go命令可以很方便地安装Logrus库:

      go get github.com/sirupsen/logrus
      
      • 1
    2. 引入 Logrus 库:

      import (
          "github.com/sirupsen/logrus"
      )
      
      • 1
      • 2
      • 3

    日志级别

    Logrus 支持 7 种不同的日志级别,严重程度从高到低依次为panic>>fatal>>error>>warn>>info>>debug>>trace

    const (
    	// PanicLevel级别,最高严重级别。记录日志后调用panic,并传递给Debug、Info等方法的消息。
    	PanicLevel Level = iota
    	// FatalLevel级别。记录日志后调用logger.Exit(1),即使日志级别设置为Panic也会退出。
    	FatalLevel
    	// ErrorLevel级别。用于必须被注意到的错误。通常用于将错误发送到错误跟踪服务的钩子中。
    	ErrorLevel
    	// WarnLevel级别。不是关键的条目,但值得关注。
    	WarnLevel
    	// InfoLevel级别。关于应用程序内部正在进行的一般操作的记录。
    	InfoLevel
    	// DebugLevel级别。通常仅在调试时启用。非常详细的日志记录。
    	DebugLevel
    	// TraceLevel级别。比Debug更细粒度的信息事件。
    	TraceLevel
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    更改输出日志级别

    在 Logrus 中,默认的日志级别是InfoLevel,即 Info 级别。这意味着只有级别大于或等于Info的日志才会被打印出来。如果需要更改输出日志级别可以使用logger.SetLevel()方法来设置:

    logger.SetLevel(logrus.DebugLevel)
    
    • 1

    设置特定字段

    在Logrus中,你可以使用WithField()WithFields()方法来为日志添加特定字段。这些字段可以提供额外的上下文信息,并且可以轻松地在日志中显示。

    logger.WithField("user", "John Doe").Info("Login successful")
    logger.WithFields(logrus.Fields{
        "user":    "John Doe",
        "account": "123456789",
    }).Info("Account created")
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在上述代码中,我们使用WithField()方法添加了一个名为"user"的特定字段,并将其设置为"John Doe"。然后,我们使用Info()方法记录一条日志并触发该字段。

    另外,我们还使用了WithFields()方法来添加多个特定字段,其中包括"user"和"account"。然后,我们使用Info()方法记录一条带有多个字段的日志。

    输出示例:

    time="2023-10-04T08:45:57+08:00" level=info msg="Login successful" user="John Doe"
    time="2023-10-04T08:45:57+08:00" level=info msg="Account created" account="123456789" user="John Doe"
    
    • 1
    • 2

    通常,在一个应用中、或者应用的一部分中,都有一些固定的 Field。比如在处理用户 http 请求时,上下文中所有的日志都会有 request_id 和 user_ip,为了避免每次记录日志都要使用 logrus.WithFields(logrus.Fields{"ip": "0.0.0.1",}),我们可以创建一个 logrus.Entry 实例,为这个实例设置默认 Fields,后续直接在上下文中使用这个
    logrus.Entry 实例记录日志即可。

    修改后样例如下:

    var (
        logger *logrus.Entry
    )
    
    func init() {
        // 设置日志级别
        logrus.SetLevel(logrus.DebugLevel)
    
        // 创建 logrus.Entry 实例
        logger = logrus.WithFields(logrus.Fields{
            "ip": "0.0.0.1",
        })
    
        // 设置日志输出格式
        logrus.SetFormatter(&logrus.JSONFormatter{})
    
        // 设置日志输出位置为标准输出
        logrus.SetOutput(os.Stdout)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1. 首先,我们定义了一个logger变量,它将用于记录日志。这是一个指向logrus.Entry类型的指针。

    2. init()函数中,我们使用SetLevel()方法设置了日志级别为Debug级别。这意味着只有级别大于或等于Debug级别的日志才会被记录。

    3. 然后,我们使用WithFields()方法创建了一个Logger实例,并设置了一个名为"ip"的特定字段,其值为"0.0.0.1"。

    4. 接下来,我们使用SetFormatter()方法设置了日志输出格式为JSON格式。这将把日志记录为JSON格式,以便更轻松地对其进行后续处理。

    5. 最后,我们使用SetOutput()方法将日志输出位置设置为标准输出。这意味着日志将记录在控制台上。

    日志输出格式

    Logrus 提供了两种预定义的 Formatter:TextFormatterJSONFormatter,同时也支持自定义的Formatter。

    • TextFormatter(默认格式):

      import (
          "github.com/sirupsen/logrus"
      )
      
      func main() {
          logger := logrus.New()
          logger.Formatter = &logrus.TextFormatter{}
          logger.Info("This is a log message")
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      输出示例:

      time="2023-10-04T09:16:25+08:00" level=info msg="This is a log message"
      
      • 1
    • JSONFormatter:

      import (
          "github.com/sirupsen/logrus"
      )
      
      func main() {
          logger := logrus.New()
          logger.Formatter = &logrus.JSONFormatter{}
          logger.Info("This is a log message")
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      输出示例:

      {"level":"info","msg":"This is a log message","time":"2023-10-04T09:16:25+08:00"}
      
      • 1

    自定义颜色

    在Logrus中,可以通过设置 Formatter 来为日志添加颜色。具体而言,Logrus提供了一个TextFormatter的属性ForceColors用于启用日志的颜色输出:

    // 设置日志输出格式
    logrus.SetFormatter(&logrus.TextFormatter{
        ForceColors: true,
    })
    
    • 1
    • 2
    • 3
    • 4

    我们将 Logrus 实例的 Formatter 设置为TextFormatter,接着,我们将ForceColors属性设置为true,启用日志的颜色输出。

    如果你想自定义这些颜色,那么可以跳转查看这篇文章:Logrus 日志框架——自定义日志颜色

    日志输出方式

    • 输出到控制台:

      // 设置日志输出位置为标准输出
      logrus.SetOutput(os.Stdout)
      
      • 1
      • 2
    • 输出到文件:

      //创建文件
      logFile, err := os.OpenFile("logs.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
      if err != nil {
          fmt.Println("无法创建日志文件:", err)
          return
      }
      
      // 设置日志输出位置为文件
      logrus.SetOutput(logFile)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 控制台文件同时输出:

      // 设置日志输出位置为控制台文件
      logrus.SetOutput(io.MultiWriter(os.Stdout, logFile))
      
      • 1
      • 2

    显示文件名和行号

    // 设置 logrus 输出日志中的文件名和行号
    logrus.SetReportCaller(true)
    
    • 1
    • 2

    Hook

    logrus 中,hook 可以被用于将日志消息发送到多个目标,比如发送到 Elasticsearch、Slack、email 等。hook 接口定义了在每次写入新的日志消息时需要执行的方法,这些方法可以使用我们想要的任何数据通道或协议来传递日志消息。

    logrus 内置了一些常见的 hook,比如 SyslogHook,可以将日志消息发送到系统日志中。此外,还有一些第三方库提供各种 hook,可以满足各种需求。

    下面是一个简单的自定义 hook 示例代码:

    package main
    
    import (
    	"fmt"
    	"time"
    
    	"github.com/sirupsen/logrus"
    	log "github.com/rifflock/loggers"
    	_ "github.com/rifflock/loggers/logrus" // 导入 logurs 适配器
    )
    
    // 自定义的 Hook
    type CustomHook struct {
    }
    
    func (h *CustomHook) Levels() []logrus.Level {
    	return logrus.AllLevels
    }
    
    func (h *CustomHook) Fire(entry *logrus.Entry) error {
    	// 获取日志消息和级别
    	message := entry.Message
    	level := entry.Level
    
    	// 获取当前时间
    	now := time.Now().Format("2006-01-02 15:04:05")
    
    	// 构造自定义消息格式
    	customMessage := fmt.Sprintf("[%s] [%s] %s", now, level, message)
    
    	// 输出到标准输出
    	fmt.Println(customMessage)
    
    	return nil
    }
    
    func main() {
    	// 创建 logurs 的 logger
    	logger, _ := log.New("logrus")
    
    	// 配置 logrus 日志记录器
    	logrus.SetFormatter(&logrus.TextFormatter{
    		DisableColors:   true,
    		DisableSorting:  true,
    		FullTimestamp:   true,
    		QuoteEmptyFields: true,
    	})
    
    	logrus.SetOutput(logger) // 将 logurs logger 设置为 logrus 的输出
    
    	// 设置自定义的 Hook
    	logrus.AddHook(&CustomHook{})
    
    	// 进行日志记录
    	logrus.Info("This is a log message.")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    在上面的示例中,我们实现了一个自定义的 hook,称为 CustomHook。我们通过实现两个方法:Levels()Fire() 来满足 hook 接口。Levels() 方法指定了我们想要监听哪些日志级别,这里我们监听了所有的级别。Fire() 方法是在每个日志消息写入时被调用,并传递 logrus.Entry 指针,这个指针包含了当前的日志消息及其元数据。

  • 相关阅读:
    佳博打印机打印条码和二维码的方法
    redis之常见的集合操作有哪些?
    原生mybatis使用细节回顾
    GBase 8s 产品功能-高可用和ER
    Redis数据结构之跳表
    【论文阅读笔记】Pyramid Real Image Denoising Network
    AI AIgents时代 - (四.) HuggingGPT & MetaGPT
    React + Router
    DOM节点类型
    html--src和href的区别
  • 原文地址:https://blog.csdn.net/qq_20185737/article/details/133657456