1. 简介

golang标准库的日志框架非常简单,仅仅提供了print,panic和fatal三个函数对于更精细的日志级别、日志文件分割以及日志分发等方面并没有提供支持. 所以催生了很多第三方的日志库,但是在golang的世界里,没有一个日志库像slf4j那样在Java中具有绝对统治地位.golang中,流行的日志框架包括logrus、zap、zerolog、seelog等.

logrus是目前Github上star数量最多的日志库,目前(2022.04)star数量为20.3k,fork数为2.1k. logrus功能强大,性能高效,而且具有高度灵活性,提供了自定义插件的功能.很多开源项目,如docker,prometheus,dejavuzhou/ginbro等,都是用了logrus来记录其日志.

2. 配置

日志级别: logrus有7个日志级别,依次是Trace << Debug << Info << Warning << Error << Fatal << Panic

  1. logrus.SetLevel(logrus.DebugLevel) //只输出不低于当前级别的日志数据

日志格式: logrus内置了JSONFormatter和TextFormatter两种格式,也可以通过Formatter接口定义日志格式

  1. //json格式输出
  2. logrus.SetFormatter(&logrus.JSONFormatter{
  3. PrettyPrint: true,
  4. TimestampFormat: "2018-01-02 15:04:05",
  5. })
  6. //输出结果
  7. {
  8. "file": "/home/mv-user/RimeData/script/cmd/request.go:20",
  9. "func": "main.main",
  10. "level": "info",
  11. "msg": "我执行了!",
  12. "time": "18048-04-18 10:32:05"
  13. }
  14. //文本格式输出
  15. logrus.SetFormatter(&logrus.TextFormatter{
  16. ForceColors: true,
  17. EnvironmentOverrideColors: true,
  18. TimestampFormat: "2018-01-02 15:04:05",
  19. })
  20. //输出结果
  21. INFO[0000]/home/mv-user/RimeData/script/cmd/request.go:21 main.main() 我执行了!

日志输出:

  1. logfile, _ := os.OpenFile("./app.log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644)
  2. logrus.SetOutput(logfile)
  3. logrus.SetReportCaller(true) //定位行号

3. 日志打印

FieldLogger接口: FieldLogger定义了所有日志打印的方法

  1. type FieldLogger interface {
  2. WithField(key string, value interface{}) *Entry
  3. WithFields(fields Fields) *Entry
  4. WithError(err error) *Entry
  5. Debugf(format string, args ...interface{})
  6. Infof(format string, args ...interface{})
  7. Printf(format string, args ...interface{})
  8. Warnf(format string, args ...interface{})
  9. Warningf(format string, args ...interface{})
  10. Errorf(format string, args ...interface{})
  11. Fatalf(format string, args ...interface{})
  12. Panicf(format string, args ...interface{})
  13. Debug(args ...interface{})
  14. Info(args ...interface{})
  15. Print(args ...interface{})
  16. Warn(args ...interface{})
  17. Warning(args ...interface{})
  18. Error(args ...interface{})
  19. Fatal(args ...interface{})
  20. Panic(args ...interface{})
  21. Debugln(args ...interface{})
  22. Infoln(args ...interface{})
  23. Println(args ...interface{})
  24. Warnln(args ...interface{})
  25. Warningln(args ...interface{})
  26. Errorln(args ...interface{})
  27. Fatalln(args ...interface{})
  28. Panicln(args ...interface{})
  29. // IsDebugEnabled() bool
  30. // IsInfoEnabled() bool
  31. // IsWarnEnabled() bool
  32. // IsErrorEnabled() bool
  33. // IsFatalEnabled() bool
  34. // IsPanicEnabled() bool
  35. }

日志打印1:默认实例 (函数),即通过logrus包提供的函数(覆盖了FieldLogger接口的所有方法),直接打印日志。但其实logrus包函数是调用了logrus.Loger默认实例。

  1. logrus.Infoln("我执行了!")
  2. logrus.Errorf("报错了!")

日志打印2:Logger实例(对象),它实现了FieldLogger接口。

  1. logger := logrus.New()
  2. logger.SetLevel(logrus.DebugLevel)
  3. logger.SetFormatter(&logrus.JSONFormatter{
  4. PrettyPrint: true,
  5. TimestampFormat: "2018-01-02 15:04:05",
  6. })
  7. logfile, _ := os.OpenFile("./app.log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644)
  8. logger.SetOutput(logfile)
  9. logger.SetReportCaller(true)
  10. logger.Infoln("我执行了!")
  11. logger.Errorf("报错了")

日志打印3:Entry示例(对象),它也实现了FieldLogger接口,是最终是日志打印入口。

  • 这里用到了Field机制,logrus鼓励通过Field机制进行精细化的、结构化的日志记录,而不是通过冗长的消息来记录日志。

4. hook机制