Go语言第三方日志库logrus使用

简介

结构化、插件化的Go日志库,与标准库log的API完全兼容。目前处于维护模式,不再开发新的特性,后期专注于安全和性能提升这块。

安装

1go get github.com/sirupsen/logrus

基本使用

 1package main
 2
 3import (
 4  log "github.com/sirupsen/logrus"
 5)
 6
 7func main() {
 8  log.WithFields(log.Fields{
 9    "animal": "walrus",
10  }).Info("A walrus appears")
11}

输出结果

1INFO[0000] A walrus appears                              animal=walrus

进阶用法

 1package main
 2
 3import (
 4  "os"
 5  log "github.com/sirupsen/logrus"
 6)
 7
 8func init() {
 9  // Log as JSON instead of the default ASCII formatter.
10  log.SetFormatter(&log.JSONFormatter{})
11
12  // Output to stdout instead of the default stderr
13  // Can be any io.Writer, see below for File example
14  log.SetOutput(os.Stdout)
15
16  // Only log the warning severity or above.
17  log.SetLevel(log.WarnLevel)
18}
19
20func main() {
21  log.WithFields(log.Fields{
22    "animal": "walrus",
23    "size":   10,
24  }).Info("A group of walrus emerges from the ocean")
25
26  log.WithFields(log.Fields{
27    "omg":    true,
28    "number": 122,
29  }).Warn("The group's number increased tremendously!")
30
31  log.WithFields(log.Fields{
32    "omg":    true,
33    "number": 100,
34  }).Fatal("The ice breaks!")
35
36  // A common pattern is to re-use fields between logging statements by re-using
37  // the logrus.Entry returned from WithFields()
38  contextLogger := log.WithFields(log.Fields{
39    "common": "this is a common field",
40    "other": "I also should be logged always",
41  })
42
43  contextLogger.Info("I'll be logged with common and other field")
44  contextLogger.Info("Me too")
45}

输出结果

1{"level":"warning","msg":"The group's number increased tremendously!","number":122,"omg":true,"time":"2020-03-06T20:11:35+08:00"}
2{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,"time":"2020-03-06T20:11:35+08:00"}

高级用法

比如你可以把日志存到多个地方

 1package main
 2
 3import (
 4  "os"
 5  "github.com/sirupsen/logrus"
 6)
 7
 8// Create a new instance of the logger. You can have any number of instances.
 9var log = logrus.New()
10
11func main() {
12  // The API for setting attributes is a little different than the package level
13  // exported logger. See Godoc.
14  log.Out = os.Stdout
15
16  // You could set this to any `io.Writer` such as a file
17  file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
18  if err == nil {
19    log.Out = file
20  } else {
21    log.Info("Failed to log to file, using default stderr")
22  }
23
24  log.WithFields(logrus.Fields{
25    "animal": "walrus",
26    "size":   10,
27  }).Info("A group of walrus emerges from the ocean")
28}

输出结果

日志保存到文件中了

1cat logrus.log 
2time="2020-03-06T20:15:14+08:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10

格式化

logrus支持两种格式的格式化log.JSONFormatter{}log.TextFormatter{}

设置方式

json便于logstash或Splunk解析

1log.SetFormatter(&log.JSONFormatter{})

默认文本模式

1log.SetFormatter(&log.TextFormatter{})

禁用终端颜色

1log.SetFormatter(&log.TextFormatter{
2		DisableColors: true,
3		FullTimestamp: true,
4	})

记录方法名

1log.SetReportCaller(true)

日志级别

logrus支持7种日志级别:Trace, Debug, Info, Warning, Error, Fatal and Panic。

 1package main
 2
 3import (
 4  log "github.com/sirupsen/logrus"
 5)
 6
 7func main() {
 8	log.Trace("Something very low level.")
 9	log.Debug("Useful debugging information.")
10	log.Info("Something noteworthy happened!")
11	log.Warn("You should probably take a look at this.")
12	log.Error("Something failed but I'm not quitting.")
13	// Calls os.Exit(1) after logging
14	log.Fatal("Bye.")
15	// Calls panic() after logging
16	log.Panic("I'm bailing.")
17}

输出结果

1INFO[0000] Something noteworthy happened!               
2WARN[0000] You should probably take a look at this.     
3ERRO[0000] Something failed but I'm not quitting.       
4FATA[0000] Bye.  

设置日志级别

1// Will log anything that is info or above (warn, error, fatal, panic). Default.
2log.SetLevel(log.InfoLevel)

字段

logrus鼓励通过日志字段进行仔细的结构化记录,而不是长的不可分割的错误信息,如log.Fatalf("Failed to send event %s to topic %s with key %d"),你可以记录为:

1log.WithFields(log.Fields{
2  "event": event,
3  "topic": topic,
4  "key": key,
5}).Fatal("Failed to send event")

默认字段

通常,将字段始终附加到应用程序中的日志语句或其中一部分时有帮助的。例如,你可能希望始终在请求上下文中记录request_iduser_ip这两个字段。不用在没一行都写上

log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip}),你可以创建一个实体代替

1requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
2requestLogger.Info("something happened on that request") # will log request_id and user_ip
3requestLogger.Warn("something not great happened")

钩子

你可以为日志级别添加钩子。比如,当服务出现Error,Fatal和Panic时,将错误发送到多个地方,如syslog。

 1import (
 2  log "github.com/sirupsen/logrus"
 3  "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake"
 4  logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
 5  "log/syslog"
 6)
 7
 8func init() {
 9
10  // Use the Airbrake hook to report errors that have Error severity or above to
11  // an exception tracker. You can create custom hooks, see the Hooks section.
12  log.AddHook(airbrake.NewHook(123, "xyz", "production"))
13
14  hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
15  if err != nil {
16    log.Error("Unable to connect to local syslog daemon")
17  } else {
18    log.AddHook(hook)
19  }
20}

环境

logrus没有环境的概念,如果你希望钩子和格式化程序仅在特定环境下使用,则应自行处理。示例:

 1import (
 2  log "github.com/sirupsen/logrus"
 3)
 4
 5init() {
 6  // do something here to set environment depending on an environment variable
 7  // or command-line flag
 8  if Environment == "production" {
 9    log.SetFormatter(&log.JSONFormatter{})
10  } else {
11    // The TextFormatter is default, you don't actually have to do this.
12    log.SetFormatter(&log.TextFormatter{})
13  }
14}

日志切割

日志切割功能没有提供,可以使用第三方库来实现。

Tool Description
Logrus Mate Logrus mate is a tool for Logrus to manage loggers, you can initial logger’s level, hook and formatter by config file, the logger will be generated with different configs in different environments.
Logrus Viper Helper An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of Logrus Mate. sample

更多信息

更多详细的信息,请查阅godoc或者github上的文档。