1 简介

logrus的优点如下:

  • 完全兼容标准的log库
  • 内置了两种日志格式JSONFormater和TextFormatter
  • 允许使用者通过Hook的方式将日志分发到任意地方
  • 通过Filed机制进行结构化的日志记录

但是它用到了反射, 效率会相对低一点

提供的日志等级有:

  • logrus.Debug(“Useful debugging information.”)
  • logrus.Info(“Something noteworthy happened!”), 输出到stdout
  • logrus.Warn(“You should probably take a look at this.”)
  • logrus.Error(“Something failed but I’m not quitting.”), 输出到stderr, 还会继续执行
  • logrus.Panic(“I’m bailing.”) //log之后会panic(), 会退出所有协程
  • logrus.Fatal(“Bye.”) //log之后会调用os.Exit(1), 强制退出所有协程

    2 使用示例

    ```go package main

import ( log “github.com/sirupsen/logrus” )

func main() { log.Info(“hello”)

  1. log.WithFields(log.Fields{
  2. "animal": "walrus",
  3. }).Info("a walrus appears")

}

  1. 运行结果如下:
  2. ```go
  3. INFO[0000] hello
  4. INFO[0000] a walrus appears animal=walrus

3 设置log的参数

  1. package main
  2. import (
  3. log "github.com/sirupsen/logrus"
  4. "os"
  5. )
  6. func init() {
  7. log.SetFormatter(&log.JSONFormatter{})
  8. log.SetOutput(os.Stdout)
  9. log.SetLevel(log.InfoLevel)
  10. }
  11. func main() {
  12. log.Info("hello")
  13. }

运行结果如下:

  1. {"level":"info","msg":"hello","time":"2022-01-29T20:15:32+08:00"}

4 输出到文件

  1. package main
  2. import (
  3. log "github.com/sirupsen/logrus"
  4. "io"
  5. "os"
  6. )
  7. func init() {
  8. log.SetFormatter(&log.JSONFormatter{})
  9. writer1 := os.Stdout
  10. writer2, _ := os.OpenFile("log.txt", os.O_WRONLY|os.O_CREATE, 0755)
  11. // 同时输出到 控制台, 文件
  12. log.SetOutput(io.MultiWriter(writer1, writer2))
  13. // 设置日志只记录Info及以上
  14. log.SetLevel(log.InfoLevel)
  15. }
  16. func main() {
  17. log.Info("hello")
  18. }

5 hook

hook的原理是,在logrus写入日志时拦截,修改logrus.Entry

  1. package main
  2. import (
  3. log "github.com/sirupsen/logrus"
  4. "io"
  5. "os"
  6. )
  7. type MyFieldHook struct {
  8. }
  9. func (this MyFieldHook) Fire(entry *log.Entry) error {
  10. entry.Data["tag"] = "ws"
  11. return nil
  12. }
  13. func (this MyFieldHook) Levels() []log.Level {
  14. return log.AllLevels
  15. }
  16. func init() {
  17. log.SetFormatter(&log.JSONFormatter{})
  18. writer1 := os.Stdout
  19. writer2, _ := os.OpenFile("log.txt", os.O_WRONLY|os.O_CREATE, 0755)
  20. log.SetOutput(io.MultiWriter(writer1, writer2))
  21. log.SetLevel(log.InfoLevel)
  22. hook := MyFieldHook{}
  23. log.AddHook(hook)
  24. log.SetReportCaller(true) // 输出文件名,行号,函数名
  25. }
  26. func main() {
  27. log.Info("hello")
  28. }

运行结果如下:

{“file”:”/Users/ws/GolandProjects/awesomeProject/main.go:33”,”func”:”main.main”,”level”:”info”,”msg”:”hello”,”tag”:”ws”,”time”:”2022-01-29T20:35:54+08:00”}

6 日志文件切割

通过hook插件file-rotatelogs进行日志本地文件分割
日志轮转相关函数:

  • WithLinkName() 为最新的日志建立软连接
  • WithMaxAge() 设置文件清理前的最长保存时间
  • WithRotationTime() 设置日志分割的时间,隔多久分割一次
  • WithRotationCount() 设置文件清理前最多保存的个数

    注: WithMaxAge 和 WithRotationCount二者只能设置一个

  1. package main
  2. import (
  3. "time"
  4. rotatelogs "github.com/lestrrat-go/file-rotatelogs"
  5. log "github.com/sirupsen/logrus"
  6. )
  7. func init() {
  8. path := "./log/go.log"
  9. writer, _ := rotatelogs.New(
  10. path+".%Y%m%d%H%M", // 正在记录的日志文件
  11. rotatelogs.WithLinkName(path), // 正在记录的日志文件 对应的软链接(最好用绝对路径)
  12. rotatelogs.WithMaxAge(180*time.Second), // 设置文件清理前的最长保存时间
  13. rotatelogs.WithRotationTime(60*time.Second), // 设置日志分割的时间,隔多久分割一次
  14. )
  15. log.SetOutput(writer)
  16. }
  17. func main() {
  18. for {
  19. log.Info("hello, world!")
  20. time.Sleep(2 * time.Second)
  21. }
  22. }

7 记录到ElasticSearch

  1. import (
  2. log "github.com/sirupsen/logrus"
  3. "github.com/olivere/elastic"
  4. "gopkg.in/sohlich/elogrus"
  5. )
  6. func initLog() {
  7. client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200"))
  8. if err != nil {
  9. log.Panic(err)
  10. }
  11. hook, err := elogrus.NewElasticHook(client, "localhost", log.DebugLevel, "mylog")
  12. if err != nil {
  13. log.Panic(err)
  14. }
  15. log.AddHook(hook)
  16. }

8 记录到Mongo

  1. package main
  2. import (
  3. log "github.com/sirupsen/logrus"
  4. "github.com/weekface/mgorus"
  5. )
  6. func main() {
  7. hook, err := mgorus.NewHooker("localhost:27017", "db", "collection")
  8. if err != nil {
  9. panic(err)
  10. }
  11. log.AddHook(hook)
  12. log.WithFields(logrus.Fields{
  13. "name": "zhangsan",
  14. "age": 28,
  15. }).Error("Hello world!")
  16. }

有时会报错: Failed to write to log, invalid argument
image.png