当前位置: 首页 > news >正文

【go语言开发】loglus日志框架的使用

本文将简单介绍loglus框架的基本使用,并给出demo

文章目录

  • 前言
  • Loglus常见用法
    • 自定义日志级别
    • 使用字段钩子
    • 输出到多个位置
    • 使用钩子实现自定义日志处理
    • demo

前言

Logrus 是一个用于 Go 语言的结构化日志框架,它提供了丰富的日志级别、钩子和格式化选项。
环境搭建:

go get github.com/sirupsen/logrus

代码中导入Loglus

import ("github.com/sirupsen/logrus"
)

Loglus常见用法

自定义日志级别

可以添加一个 TraceLevel 级别来更详细地跟踪程序的执行流程

package mainimport ("github.com/sirupsen/logrus"
)var TraceLevel = logrus.Level(6)func main() {logger := logrus.New()logger.SetLevel(TraceLevel)logger.Trace("This is a trace level log")
}

使用字段钩子

使用字段钩子来在日志中添加额外的字段信息。例如,你可以添加一个钩子来记录每条日志的时间戳:

package mainimport ("github.com/sirupsen/logrus"
)func main() {logger := logrus.New()logger.SetFormatter(&logrus.JSONFormatter{})logger.AddHook(&logrus.FieldHook{Field: "timestamp",Func: func() (interface{}, error) {return time.Now().Format("2006-01-02T15:04:05.999Z07:00"), nil},})logger.Info("This is a log entry with timestamp field")
}

输出到多个位置

可以将日志同时输出到多个位置,比如标准输出和文件。以下是一个示例,将日志同时输出到控制台和文件中:

package mainimport ("os""io""github.com/sirupsen/logrus"
)func main() {logger := logrus.New()// 设置日志级别和输出格式// 输出到控制台logger.SetOutput(os.Stdout)// 输出到文件file, err := os.OpenFile("logfile.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)if err == nil {mw := io.MultiWriter(os.Stdout, file)logger.SetOutput(mw)} else {logger.Info("Failed to log to file, using default stderr")}logger.Info("This log entry will be output to both console and file")
}

使用钩子实现自定义日志处理

使用钩子来实现自定义的日志处理逻辑。例如,你可以添加一个邮件钩子,在产生错误日志时发送邮件通知:

package mainimport ("github.com/sirupsen/logrus""net/smtp"
)func main() {logger := logrus.New()// 设置日志级别和输出格式// 添加邮件钩子logger.AddHook(&logrus.Hook{Levels: []logrus.Level{logrus.ErrorLevel, logrus.FatalLevel},Fire: func(entry *logrus.Entry) error {sendEmailNotification(entry.Message)return nil},})logger.Error("An error occurred, email notification will be sent")
}func sendEmailNotification(message string) {// 实现发送邮件的逻辑
}

demo

这里给出一个保存日志到项目log文件的示例:

package middlewareimport ("fmt""github.com/gin-gonic/gin"retalog "github.com/lestrrat-go/file-rotatelogs""github.com/rifflock/lfshook""github.com/sirupsen/logrus""log""math""os""path""time"
)// SetOutputFile 设置输出文件名称,如果没有就创建
func SetOutputFile() (*os.File, string, error) {now := time.Now()logFilePath := ""if dir, err := os.Getwd(); err == nil {logFilePath = dir + "/logs"}_, err := os.Stat(logFilePath)if os.IsNotExist(err) {if err := os.MkdirAll(logFilePath, 0777); err != nil {log.Println(err.Error())return nil, "", err}}logFileName := now.Format("2006-01-02") + ".log"filePath := path.Join(logFilePath, logFileName)if _, err := os.Stat(filePath); err != nil {if _, err := os.Create(filePath); err != nil {log.Println(err.Error())return nil, "", err}}src, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0755)if err != nil {fmt.Println("err: ", err)return nil, "", err}log.Println("create log path: ", filePath)return src, filePath, nil
}// Logger 日志,此操作可以复用
func Logger() gin.HandlerFunc {//建立软连接,需要管理员权限linkName := "latest_log.log"//设置日志文件的路径src, filePath, _ := SetOutputFile()//创建日志logger := logrus.New()//输出logger.Out = src//设置日志级别logger.SetLevel(logrus.DebugLevel)// 显示日志行数//logger.SetReportCaller(true)//添加时间分割logWriter, _ := retalog.New(filePath,retalog.WithMaxAge(14*24*time.Hour),    //日志保留时间:2周retalog.WithRotationTime(24*time.Hour), //24小时分割一次retalog.WithLinkName(linkName),         //建立软连接)writeMap := lfshook.WriterMap{logrus.InfoLevel:  logWriter,logrus.FatalLevel: logWriter,logrus.DebugLevel: logWriter,logrus.WarnLevel:  logWriter,logrus.ErrorLevel: logWriter,logrus.PanicLevel: logWriter,}//实例化Hook := lfshook.NewHook(writeMap, &logrus.TextFormatter{TimestampFormat: "2006-01-02 15:04:05",})logger.AddHook(Hook)return func(c *gin.Context) {startTime := time.Now()c.Next()stopTime := time.Since(startTime)spendTime := fmt.Sprintf("%d ms", int(math.Ceil(float64(stopTime.Nanoseconds()/1000000.0))))hostName, err := os.Hostname()if err != nil {hostName = "unknown"}statusCode := c.Writer.Status()clientIp := c.ClientIP()//userAgent := c.Request.UserAgent()dataSize := c.Writer.Size()if dataSize < 0 {dataSize = 0}method := c.Request.MethodrequestPath := c.Request.RequestURIentry := logger.WithFields(logrus.Fields{"HostName":  hostName,"status":    statusCode,"SpendTime": spendTime,"Ip":        clientIp,"Method":    method,"Path":      requestPath,"DataSize":  dataSize,//"Agent":     userAgent, // TODO: UA})if len(c.Errors) > 0 {entry.Error(c.Errors.ByType(gin.ErrorTypePrivate).String())}if statusCode >= 500 {entry.Error()} else if statusCode >= 400 {entry.Warn()} else {entry.Info()}}
}

在gin中调用Logger()

	r := gin.New()r.Use(gin.Recovery())r.Use(middleware.Logger())
http://www.lryc.cn/news/252019.html

相关文章:

  • 【Unity动画】Unity 动画播放的流程
  • 深度学习——第3章 Python程序设计语言(3.2 Python程序流程控制)
  • EasyExcel生成多sheet页的excel
  • 家用小型洗衣机哪款性价比高?内衣洗衣机品牌推荐
  • 为何Go爬虫依然远没有Python爬虫流行
  • 【华为OD题库-057】MELON的难题-java
  • OGG实现Oracle19C到postgreSQL14的实时同步
  • windows 你的电脑不能投影到其他屏幕,请尝试重新安装驱动程序
  • 2023-简单点-树莓派中的硬件通讯
  • 游戏反Frida注入检测方案
  • 观海微电子---AF、AG、AR 的差别和作用
  • 颠覆性语音识别:单词级时间戳和说话人分离
  • 吉利展厅 | 透明OLED拼接2x2:科技与艺术的完美融合
  • qnx修改tcp和udp缓冲区默认大小
  • vscode的eslint检查代码格式不严谨的快速修复
  • OpenAI GPT-4 Turbo发布:开创AI新时代
  • 基于c 实现 FIFO
  • tortoisegit 报错:server refused to start a shell/command
  • 电商平台API接口指南,京东商品详情接口,京东详情页接口,宝贝详情页接口,商品属性接口,商品信息查询,商品详细信息接口,h5实时详情页数据展示
  • 什么是迁移学习
  • 万宾科技水环境综合治理监测系统的融合与应用
  • 【EI会议征稿】第三届图像,信号处理与模式识别国际学术会议(ISPP 2024)
  • 继阿里云、滴滴、语雀后,腾讯视频也出现重大系统故障
  • kotlin中sealed语句的使用
  • 软信天成:数据泄露日趋严重 “资产”保护何去何从
  • GitHub打不开的解决方案(百试不爽法)
  • 一文入门Python面向对象编程(干货满满)
  • qiankun: 关于ElementUI字体图标加载不出来的问题
  • 【智能家居】四、网络服务器线程控制功能点
  • localForage使用 IndexedDB / WebSQL存储