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”)
log.WithFields(log.Fields{"animal": "walrus",}).Info("a walrus appears")
}
运行结果如下:```goINFO[0000] helloINFO[0000] a walrus appears animal=walrus
3 设置log的参数
package mainimport (log "github.com/sirupsen/logrus""os")func init() {log.SetFormatter(&log.JSONFormatter{})log.SetOutput(os.Stdout)log.SetLevel(log.InfoLevel)}func main() {log.Info("hello")}
运行结果如下:
{"level":"info","msg":"hello","time":"2022-01-29T20:15:32+08:00"}
4 输出到文件
package mainimport (log "github.com/sirupsen/logrus""io""os")func init() {log.SetFormatter(&log.JSONFormatter{})writer1 := os.Stdoutwriter2, _ := os.OpenFile("log.txt", os.O_WRONLY|os.O_CREATE, 0755)// 同时输出到 控制台, 文件log.SetOutput(io.MultiWriter(writer1, writer2))// 设置日志只记录Info及以上log.SetLevel(log.InfoLevel)}func main() {log.Info("hello")}
5 hook
hook的原理是,在logrus写入日志时拦截,修改logrus.Entry
package mainimport (log "github.com/sirupsen/logrus""io""os")type MyFieldHook struct {}func (this MyFieldHook) Fire(entry *log.Entry) error {entry.Data["tag"] = "ws"return nil}func (this MyFieldHook) Levels() []log.Level {return log.AllLevels}func init() {log.SetFormatter(&log.JSONFormatter{})writer1 := os.Stdoutwriter2, _ := os.OpenFile("log.txt", os.O_WRONLY|os.O_CREATE, 0755)log.SetOutput(io.MultiWriter(writer1, writer2))log.SetLevel(log.InfoLevel)hook := MyFieldHook{}log.AddHook(hook)log.SetReportCaller(true) // 输出文件名,行号,函数名}func main() {log.Info("hello")}
运行结果如下:
{“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二者只能设置一个
package mainimport ("time"rotatelogs "github.com/lestrrat-go/file-rotatelogs"log "github.com/sirupsen/logrus")func init() {path := "./log/go.log"writer, _ := rotatelogs.New(path+".%Y%m%d%H%M", // 正在记录的日志文件rotatelogs.WithLinkName(path), // 正在记录的日志文件 对应的软链接(最好用绝对路径)rotatelogs.WithMaxAge(180*time.Second), // 设置文件清理前的最长保存时间rotatelogs.WithRotationTime(60*time.Second), // 设置日志分割的时间,隔多久分割一次)log.SetOutput(writer)}func main() {for {log.Info("hello, world!")time.Sleep(2 * time.Second)}}
7 记录到ElasticSearch
import (log "github.com/sirupsen/logrus""github.com/olivere/elastic""gopkg.in/sohlich/elogrus")func initLog() {client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200"))if err != nil {log.Panic(err)}hook, err := elogrus.NewElasticHook(client, "localhost", log.DebugLevel, "mylog")if err != nil {log.Panic(err)}log.AddHook(hook)}
8 记录到Mongo
package mainimport (log "github.com/sirupsen/logrus""github.com/weekface/mgorus")func main() {hook, err := mgorus.NewHooker("localhost:27017", "db", "collection")if err != nil {panic(err)}log.AddHook(hook)log.WithFields(logrus.Fields{"name": "zhangsan","age": 28,}).Error("Hello world!")}
有时会报错: Failed to write to log, invalid argument
