Go语言第三方日志库logrus使用
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_id
和user_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上的文档。
- 原文作者:黄忠德
- 原文链接:https://huangzhongde.cn/post/Golang/2020-03-07_golang_logrus_usage/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。