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")
}
运行结果如下:
```go
INFO[0000] hello
INFO[0000] a walrus appears animal=walrus
3 设置log的参数
package main
import (
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 main
import (
log "github.com/sirupsen/logrus"
"io"
"os"
)
func init() {
log.SetFormatter(&log.JSONFormatter{})
writer1 := os.Stdout
writer2, _ := 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 main
import (
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.Stdout
writer2, _ := 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 main
import (
"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 main
import (
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