Go开源日志库Logrus的使用

打印 上一主题 下一主题

主题 1048|帖子 1048|积分 3144

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、Logrus简介

Logrus 是一个流行的 Go 语言日志库,以其功能强大、性能高效和高度机动性而闻名。有关更多介绍可检察 Logrus。
重要特点



  • 丰富的日志级别:Logrus 支持多种日志级别,包罗 Debug、Info、Warn、Error、Fatal 和 Panic,以及更细粒度的 Trace 级别。这些级别可以帮助开发者根据日志的严峻程度举行筛选和处置惩罚。
  • 多种输出格式:Logrus 支持文本(TextFormatter)和 JSON(JSONFormatter)两种内置的日志格式,并且允许用户通过实现 Formatter 接口来自定义日志格式。
  • 结构化日志记载:Logrus 的 Field 机制允许用户为日志添加自定义字段,这些字段将作为日志消息的一部门被记载,使得日志信息更加结构化和易于查询。
  • 可扩展的钩子机制:Logrus 提供了钩子(hook)机制,允许用户通过编写自定义的 hook 来扩展日志的功能,例如将日志发送到远程服务器、写入文件等。
  • 预设日志字段:Logrus 的 Default Fields 机制可以给一部门或全部日志统一添加共同的日志字段,如请求ID、用户IP等。

二、Logrus基本用法

1、安装logrus包

  1. go get github.com/sirupsen/logrus
复制代码
2、引入logrus包

  1. import "github.com/sirupsen/logrus"
复制代码
3、设置日志级别

  1. logrus.SetLevel(log.DebugLevel)
复制代码
4、设置日志格式化器

  1. logrus.SetFormatter(&logrus.TextFormatter{
  2.         FullTimestamp:   true,                  // 完整时间
  3.         TimestampFormat: "2006-01-02 15:04:05", // 时间格式
  4.         ForceColors:     true,                  //显示颜色
  5. })
复制代码
5、设置日志输出范例

  1. // 创建日志文件
  2. file, _ := os.OpenFile("logs/application.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  3. // 设置日志输出到文件
  4. // logrus.SetOutput(file)
  5. // 日志输出到文件和控制台
  6. logrus.SetOutput(io.MultiWriter(file, os.Stdout))
  7. // 输出到控制台
  8. // logrus.SetOutput(os.Stdout)
复制代码
6、记载日志

  1. logrus.WithField("appName", "测试logrus").Debug("这是一条Debug日志")
  2. logrus.WithField("appName", "测试logrus").Info("这是一条Info日志")
  3. logrus.WithFields(logrus.Fields{
  4.         "appName": "测试logrus",
  5.         "appId":   101,
  6. }).Info("这是一条Info日志")
复制代码
结果示例:


三、Logrus进阶用法 

1、显示行号

  1. // 显示行号
  2. logrus.SetReportCaller(true)
复制代码
结果演示: 

 2、hook机制

在 logrus 中,钩子(Hooks)是一种在日志条目(log entry)被处置惩罚之前或之后执行自定义逻辑的机制。你可以使用钩子来执行诸如将日志发送到外部服务(如 Sentry、Splunk 等)、修改日志消息、添加额外的日志上下文等任务。
使用方法:


  • 定义hook
实现logrus.Hook接口,其接口定义为:
  1. type Hook interface {
  2.         Levels() []Level
  3.         Fire(*Entry) error
  4. }
复制代码


  • 注册hook
  1. logrus.AddHook()
复制代码
 完整代码:
  1. package main
  2. import (
  3.         "os"
  4.         "github.com/sirupsen/logrus"
  5. )
  6. // 自定义hook
  7. type simpleHook struct {
  8. }
  9. // 实现logrus.Hook接口
  10. func (h *simpleHook) Levels() []logrus.Level {
  11.         // 只有日志级别为 ErrorLevel 的日志执行 Fire 中定义的操作
  12.         return []logrus.Level{logrus.ErrorLevel}
  13. }
  14. func (h *simpleHook) Fire(entry *logrus.Entry) error {
  15.         // 在日志条目被处理时执行的逻辑
  16.         entry.Data["appName"] = "test"
  17.         // 将错误级别的日志添加单独的错误文件中
  18.         file, _ := os.OpenFile("logs/error.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  19.         defer file.Close()
  20.         line, _ := entry.String()
  21.         file.Write([]byte(line))
  22.         return nil
  23. }
  24. func main() {
  25.         // 注册hook
  26.         logrus.AddHook(&simpleHook{})
  27.         logrus.Info("测试钩子")
  28.         // 只有 error 级别的日志才显示 appName = test
  29.         logrus.Error("测试钩子---错误信息")
  30. }
复制代码
结果演示: 

 错误信息被单独写入logs/error.log文件中,如下:


3、按时间分割日志

Logrus自己不支持日志轮转切割功能,需要共同 file-rotatelogs 包来实现。


  • 下载 file-rotatelogs 包
  1. go get github.com/lestrrat-go/file-rotatelogs
复制代码


  • 新建 RotateLogs(实现了 io.Writer 的 Write 方法)
  1. // 创建一个 writer
  2. logWriter, err := rotatelogs.New(
  3.         filepath.Join("logs", "syslog_%Y%m%d%H%M%S.log"), //日志路径
  4.         rotatelogs.WithLinkName(filepath.Join("logs", "syslog.log")),
  5.         rotatelogs.WithMaxAge(7*24*time.Hour),       // 最大保留天数:7天
  6.         rotatelogs.WithRotationTime(10*time.Second), // 日志分割时间:1分钟
  7. )
  8. if err != nil {
  9.         panic(err)
  10. }
复制代码


  • 新建 NewHook()
  1. // 新建Hook,将 otatelogs作为 writer
  2. hook := lfshook.NewHook(logWriter,
  3.         &logrus.TextFormatter{
  4.                 TimestampFormat: "2006-01-02 15:04:05",
  5.                 FullTimestamp:   true,
  6.         },
  7. )
复制代码


  • 注册 Hook
  1. // 注册 hook
  2. logger.AddHook(hook)
复制代码
完整代码:
  1. package main
  2. import (
  3.         "io"
  4.         "path/filepath"
  5.         "time"
  6.         rotatelogs "github.com/lestrrat-go/file-rotatelogs"
  7.         "github.com/rifflock/lfshook"
  8.         "github.com/sirupsen/logrus"
  9. )
  10. func main() {
  11.         // 创建一个 writer
  12.         logWriter, err := rotatelogs.New(
  13.                 filepath.Join("logs", "syslog_%Y%m%d%H%M%S.log"), //日志路径
  14.                 rotatelogs.WithLinkName(filepath.Join("logs", "syslog.log")),
  15.                 rotatelogs.WithMaxAge(7*24*time.Hour),       // 最大保留天数:7天
  16.                 rotatelogs.WithRotationTime(10*time.Second), // 日志分割时间:10秒
  17.         )
  18.         if err != nil {
  19.                 panic(err)
  20.         }
  21.         // 新建Hook,将 otatelogs作为 writer
  22.         hook := lfshook.NewHook(logWriter,
  23.                 &logrus.TextFormatter{
  24.                         TimestampFormat: "2006-01-02 15:04:05",
  25.                         FullTimestamp:   true,
  26.                 },
  27.         )
  28.         // 创建一个 logger
  29.         logger := logrus.New()
  30.         logger.SetReportCaller(true)
  31.         logger.SetOutput(io.Discard)
  32.         // 注册 hook
  33.         logger.AddHook(hook)
  34.         // 记录日志
  35.         for i := 0; i < 10; i++ {
  36.                 logger.Info("Hello world!!")
  37.                 time.Sleep(3 * time.Second)
  38.         }
  39. }
复制代码
 结果示例:


4、按日志级别分割日志

按日志级别分割日志,可以将错误信息单独写入一个文件。
方法为:新建hook时,将差别日志级别匹配到差别的writer,如下:
  1. // 新建Hook,按日志级别匹配 writer
  2. hook := lfshook.NewHook(
  3.         lfshook.WriterMap{
  4.                 logrus.DebugLevel: logWriter,
  5.                 logrus.InfoLevel:  logWriter,
  6.                 logrus.WarnLevel:  logWriter,
  7.                 logrus.ErrorLevel: errorWriter,
  8.         },
  9.         &logrus.TextFormatter{
  10.                 TimestampFormat: "2006-01-02 15:04:05",
  11.         },
  12. )
复制代码
完整代码:
  1. package main
  2. import (
  3.         "io"
  4.         "path/filepath"
  5.         "time"
  6.         rotatelogs "github.com/lestrrat-go/file-rotatelogs"
  7.         "github.com/rifflock/lfshook"
  8.         "github.com/sirupsen/logrus"
  9. )
  10. func main() {
  11.         // 创建一个 writer
  12.         logWriter, err := rotatelogs.New(
  13.                 filepath.Join("logs", "syslog_%Y%m%d%H%M%S.log"), //日志路径
  14.                 rotatelogs.WithLinkName(filepath.Join("logs", "syslog.log")),
  15.                 rotatelogs.WithMaxAge(7*24*time.Hour),       // 最大保留天数:7天
  16.                 rotatelogs.WithRotationTime(10*time.Second), // 日志分割时间:10s
  17.         )
  18.         if err != nil {
  19.                 panic(err)
  20.         }
  21.         // 创建一个 Error 级别的 writer
  22.         errorWriter, err := rotatelogs.New(
  23.                 filepath.Join("logs", "sysError_%Y%m%d%H%M%S.log"), //日志路径
  24.                 rotatelogs.WithLinkName(filepath.Join("logs", "sysError.log")),
  25.                 rotatelogs.WithMaxAge(7*24*time.Hour),       // 最大保留天数:7天
  26.                 rotatelogs.WithRotationTime(10*time.Second), // 日志分割时间:1分钟
  27.         )
  28.         if err != nil {
  29.                 panic(err)
  30.         }
  31.         // 新建Hook,按日志级别匹配 writer
  32.         hook := lfshook.NewHook(
  33.                 lfshook.WriterMap{
  34.                         logrus.DebugLevel: logWriter,
  35.                         logrus.InfoLevel:  logWriter,
  36.                         logrus.WarnLevel:  logWriter,
  37.                         logrus.ErrorLevel: errorWriter,
  38.                 },
  39.                 &logrus.TextFormatter{
  40.                         TimestampFormat: "2006-01-02 15:04:05",
  41.                 },
  42.         )
  43.         // 创建一个 logger
  44.         logger := logrus.New()
  45.         logger.SetReportCaller(true)
  46.         logger.SetOutput(io.Discard)
  47.         // 注册 hook
  48.         logger.AddHook(hook)
  49.         // 记录日志
  50.         for i := 0; i < 10; i++ {
  51.                 logger.Info("Hello world!!")
  52.                 logger.Error("这是报错信息")
  53.                 time.Sleep(3 * time.Second)
  54.         }
  55. }
复制代码
 结果示例:

 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

杀鸡焉用牛刀

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表