golang——工程组件logrus日志记录框架(结构化记录,支持文件切割,hook)

编程入门 行业动态 更新时间:2024-10-11 03:22:04

golang——工程组件logrus日志记录框架(<a href=https://www.elefans.com/category/jswz/34/1764179.html style=结构化记录,支持文件切割,hook)"/>

golang——工程组件logrus日志记录框架(结构化记录,支持文件切割,hook)

logrus

介绍一个golang 日志框架logrus

  • 支持文本与JSON数据格式
  • 支持结构化记录
  • 支持hook

文档介绍

logrus文档

std

官方案例介绍了如何配置std打印

package mainimport ("os"log "github/sirupsen/logrus"
)func init() {// Log as JSON instead of the default ASCII formatter.log.SetFormatter(&log.JSONFormatter{})// Output to stdout instead of the default stderr// Can be any io.Writer, see below for File examplelog.SetOutput(os.Stdout)// Only log the warning severity or above.log.SetLevel(log.WarnLevel)
}func main() {log.WithFields(log.Fields{"animal": "walrus","size":   10,}).Info("A group of walrus emerges from the ocean")log.WithFields(log.Fields{"omg":    true,"number": 122,}).Warn("The group's number increased tremendously!")log.WithFields(log.Fields{"omg":    true,"number": 100,}).Fatal("The ice breaks!")// A common pattern is to re-use fields between logging statements by re-using// the logrus.Entry returned from WithFields()contextLogger := log.WithFields(log.Fields{"common": "this is a common field","other": "I also should be logged always",})contextLogger.Info("I'll be logged with common and other field")contextLogger.Info("Me too")
}

file

仔细观察,如果要输出到文件,只需要在logrus.SetOutput设置上对应的*os.File即可

文件切割

文件日志记录一般都是要切割的,不然文件太大不方便查看

采用的库


案例

log.go

package logsimport ("fmt""github/sirupsen/logrus""log"
)type Log struct {*logrus.EntryLogWriter
}func (l *Log) Flush() {l.LogWriter.Flush()
}type LogConf struct {Level       logrus.LevelAdapterName stringHook        logrus.Hook
}func InitLog(conf LogConf) *Log {adapterName := "std"if conf.AdapterName != "" {adapterName = conf.AdapterName}writer, ok := writerAdapter[adapterName]if !ok {adapterName = "std"writer, _ = writerAdapter[adapterName]}fmt.Println("adapterName:" + adapterName)log :=&Log{logrus.NewEntry(logrus.New()),writer(),  // 初始化writer}// Log as JSON instead of the default ASCII formatter.log.Logger.SetFormatter(&logrus.JSONFormatter{})// Output to stdout instead of the default stderr// Can be any io.Writer, see below for File examplelog.Logger.SetOutput(log.LogWriter)// Only log the warning severity or above.if conf.Level != 0 {log.Logger.SetLevel(conf.Level)} else {log.Logger.SetLevel(logrus.InfoLevel)}if conf.Hook != nil {log.Logger.AddHook(conf.Hook)}// 设置日志打印位置log.Logger.SetReportCaller(true)return log
}type TestHook struct {}func (hook *TestHook) Levels() []logrus.Level {return []logrus.Level{logrus.InfoLevel}
}
func (hook *TestHook)  Fire(entry *logrus.Entry) error {log.Print("hook: %+v", entry)return nil
}

file_rotate.go

package logsimport (rotatelogs "github/lestrrat-go/file-rotatelogs""log""time"
)type fileRotateWriter struct {*rotatelogs.RotateLogs
}func (frw *fileRotateWriter) Flush() {frw.Close()
}func newFileRotateWriter() LogWriter {writer, err := getRotateLogs()if err != nil {log.Fatal(err)}return &fileRotateWriter{writer,}
}func getRotateLogs() (*rotatelogs.RotateLogs, error) {path := LOGPATHlogf, err := rotatelogs.New(path + ".%Y%m%d%H%M", // 指定文件格式//rotatelogs.WithLinkName(path),           // 将最新文件软链到path,windows环境不支持rotatelogs.WithMaxAge(time.Second*1800),     // 日志最长保存时长rotatelogs.WithRotationTime(time.Second*60), // 日志切分时间间隔)return logf, err
}func init() {RegisterInitWriterFunc("file-rotate", newFileRotateWriter)
}

main.go

package mainimport ("logrus-practice/logs""github/sirupsen/logrus"
)func main() {conf := logs.LogConf{Level: logrus.InfoLevel,AdapterName: "file-rotate",Hook: &logs.TestHook{},}log := logs.InitLog(conf)log.WithFields(logrus.Fields{"animal": "walrus","size":   10,}).Info("A group of walrus emerges from the ocean")log.WithFields(logrus.Fields{"omg":    true,"number": 122,}).Warn("The group's number increased tremendously!")log.WithFields(logrus.Fields{"omg":    true,"number": 100,}).Fatal("The ice breaks!")// A common pattern is to re-use fields between logging statements by re-using// the logrus.Entry returned from WithFields()contextLogger := log.WithFields(logrus.Fields{"common": "this is a common field","other": "I also should be logged always",})contextLogger.Info("I'll be logged with common and other field")contextLogger.Info("Me too")
}

hook机制

框架支持,在不同level的日志打印中进行hook。我们可以根据传入的*logrus.Entry里用户自定义的field进行不同的业务处理

上面代码已经含有hook的使用

type TestHook struct {}func (hook *TestHook) Levels() []logrus.Level {return []logrus.Level{logrus.InfoLevel}
}
func (hook *TestHook)  Fire(entry *logrus.Entry) error {// 可以根据data字段里的field 去做操作log.Print("hook: %+v", entry)return nil
}

生成环境中,很多公司都会采用ELK那一套,把日志转发录入到ES中,在kibana按条件搜索

更多推荐

golang——工程组件logrus日志记录框架(结构化记录,支持文件切割,hook)

本文发布于:2023-12-06 04:49:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1666487.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:结构化   组件   框架   文件   工程

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!