golang常用库:日志记录库-logrus使用 (2)

在运行输出:

{"animal":"dog","level":"info","msg":"a group of dog emerges from the zoon","size":10,"time":"2021-11-11T18:28:56+08:00"} {"level":"warning","msg":"the group's number increased","number":12,"omg":true,"time":"2021-11-11T18:28:56+08:00"} {"common":"this is a common filed","level":"info","msg":"I'll be logged with common and other field","other":"i also should be logged always","time":"2021-11-11T18:28:56+08:00"} {"common":"this is a common filed","level":"info","msg":"Me too","other":"i also should be logged always","time":"2021-11-11T18:28:56+08:00"}

这时候可以输出 contextLogger 日志信息了。

3. logrus 的 Fatal 处理

上面的例子定义了输出 Fatal 日志后,其后的日志都不能输出了,这是为什么?日志后面有个信息 exit status 1,

因为 logrus 的 Fatal 输出后,会执行 os.Exit(1)。那如果程序后面还有一些必要的程序要处理怎么办?

logrus 提供了 方法,在 fatal 异常时处理一些问题。

package main import ( "fmt" log "github.com/sirupsen/logrus" ) func main() { log.SetFormatter(&log.TextFormatter{ TimestampFormat: "2006-01-02 15:04:05", }) log.RegisterExitHandler(func() { fmt.Println("发生了fatal异常,执行一些必要的处理工作") }) log.Warn("warn") log.Fatal("fatal") log.Info("info") //不会执行 }

运行输出:

time="2021-11-11 21:48:25" level=warning msg=warn time="2021-11-11 21:48:25" level=fatal msg=fatal 发生了fatal异常,执行一些必要的处理工作 exit status 1 4. 切分日志文件

如果日志文件太大了,想切分成小文件,但是 logrus 没有提供这个功能。

一种是借助linux系统的 logrotate 命令来切分 logrus 生成的日志文件。

另外一种是用 logrus 的 hook 功能,做一个切分日志的插件。找到了 file-rotatelogs,但是这个库状态

已经是 archived 状态,库作者现在不接受任何修改,他也不继续维护了。所以使用还是慎重些。

在 logrus issue 里找到了这个 https://github.com/natefinch/lumberjack 切割文件的库。

例子:

package main import ( log "github.com/sirupsen/logrus" "gopkg.in/natefinch/lumberjack.v2" ) func main() { logger := &lumberjack.Logger{ Filename: "./testlogrus.log", MaxSize: 500, // 日志文件大小,单位是 MB MaxBackups: 3, // 最大过期日志保留个数 MaxAge: 28, // 保留过期文件最大时间,单位 天 Compress: true, // 是否压缩日志,默认是不压缩。这里设置为true,压缩日志 } log.SetOutput(logger) // logrus 设置日志的输出方式 } 5. 设置 logrus 实例

如果一个应用有多个地方使用日志,可以单独实例化一个 logrus,作为全局的日志实例。

package main import ( "os" "github.com/sirupsen/logrus" ) var log = logrus.New() func main() { log.Out = os.Stdout // 设置输出日志位置,可以设置日志到file里 log.WithFields(logrus.Fields{ "fruit": "apple", "size": 20, }).Info(" a lot of apples on the tree") }

输出:

time="2021-11-11T18:39:15+08:00" level=info msg=" a lot of apples on the tree" fruit=apple size=20 6. fields

在使用 logrus 时,鼓励用 log.WithFields(log.Fields{}).Fatal() 这种方式替代 og.Fatalf("Failed to send event %s to topic %s with key %d"), 也就是不是用 %s,%d 这种方式格式化,而是直接传入变量 event,topic 给 log.Fields ,这样就显得结构化日志输出,很人性化美观。

log.WithFields(log.Fields{ "event": event, "topic": topic, "key": key, }).Fatal("Failed to send event") 7. 设置默认字段

比如在链路追踪里,会有一个 rquest_id ,trace_id 等,想这个 log 一直带有这 2 个字段,logrus 怎么设置?

可以用 log.WithFields(log.Fields{"request_id": request_id, "trace_id": trace_id})

requestLogger := log.WithFields(log.Fields{"request_id": request_id, "trace_id": trace_id}) requestLogger.Info("something happened on that request") requestLogger.Warn("something not great happened")

例子:

package main import ( "github.com/google/uuid" log "github.com/sirupsen/logrus" ) func main() { uid := uuid.New() request_id := uid trace_id := uid requestLogger := log.WithFields(log.Fields{"request_id": request_id, "trace_id": trace_id}) requestLogger.Info("something happened on that request") requestLogger.Warn("something not great happened") } 8. hook 钩子-扩展logrus功能

hook 给 logrus 提供了强大的可扩展功能.

用户可以给 logrus 编写钩子插件,根据自己的日志需求编写 hook。

logrus 也有一些内置插件hooks。

第三方给 logrus 编写的 hook, 第三方hook列表。

官方的 syslog hook example:

package main import ( "log/syslog" "github.com/sirupsen/logrus" lSyslog "github.com/sirupsen/logrus/hooks/syslog" ) func main() { log := logrus.New() hook, err := lSyslog.NewSyslogHook("", "", syslog.LOG_INFO, "") if err != nil { log.Hooks.Add(hook) } } 参考

https://github.com/sirupsen/logrus

https://github.com/natefinch/lumberjack

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzpjdw.html