【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())
相关文章:
【go语言开发】loglus日志框架的使用
本文将简单介绍loglus框架的基本使用,并给出demo 文章目录 前言Loglus常见用法自定义日志级别使用字段钩子输出到多个位置使用钩子实现自定义日志处理demo 前言 Logrus 是一个用于 Go 语言的结构化日志框架,它提供了丰富的日志级别、钩子和格式化选项。…...
【Unity动画】Unity 动画播放的流程
本文以2D为案例,讲解Unity 播放动画的流程 准备和导入2D动画资源 外部导入序列帧生成的 Unity内部制作的 外部导入的3D动画 2.创建动画过程 打开时间轴Ctrl6 选中场景中的一个未来需要播放动画的物体 回到时间轴点击Create一个新动画片段 拖动2D动画资源放入…...
深度学习——第3章 Python程序设计语言(3.2 Python程序流程控制)
3.2 Python程序流程控制 目录 1.布尔数据类型及相关运算 2.顺序结构 3.选择(分支)结构 4.循环结构 无论是在机器学习还是深度学习中,Python已经成为主导性的编程语言。而且,现在许多主流的深度学习框架,例如PyTorc…...
EasyExcel生成多sheet页的excel
一、controller层 ApiOperation(value "明细查询导出") PostMapping(value "/SummaryDetailExport") public void summaryDetailExport(RequestBody SearchDTO dto, HttpServletResponse response) throws IOException {reportService.deptPackagingSum…...
家用小型洗衣机哪款性价比高?内衣洗衣机品牌推荐
近日,国内著名的电子商务平台公布了“内衣洗衣机产业趋势”的研究报告。该报告指出,由于消费者对生活质量的要求越来越高,内衣洗衣机的行业也有了长足的发展,特别是在今年以来,内衣洗衣机的销售额同比上涨了830%&#…...
为何Go爬虫依然远没有Python爬虫流行
目录 一、Go与Python的比较 1、语言生态 2、易用性 3、库支持 二、Go爬虫的优势 1、性能与并发性 2、跨平台性 3、内存占用 三、Go爬虫的潜力与未来发展 1、社区支持与库完善 2、跨平台移动应用开发 3、大数据处理与实时分析 四、代码示例 五、结论 在当今的互联…...
【华为OD题库-057】MELON的难题-java
题目 MELON有一堆精美的雨花石(数量为n,重量各异),准备送给S和W。MELON希望送给俩人的雨花石重星一致,请你设计一个程序帮MELON确认是否能将雨花石平均分配。 输入描述 第1行输入为雨花石个数:n,0<n <31. 第2行输入为空格分…...
OGG实现Oracle19C到postgreSQL14的实时同步
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...
windows 你的电脑不能投影到其他屏幕,请尝试重新安装驱动程序
注意 千万不要去下载什么驱动精灵,太垃圾不好用还一堆附带的软件。按以下步骤进行解决: 解决方法 可能是显卡驱动的问题,我的笔记本按照如下步骤重启一下驱动后解决了,步骤如下: 右键点击桌面的开始菜单,选择”设备…...
2023-简单点-树莓派中的硬件通讯
树莓派中的通讯方式 串口通讯什么是串口通讯?串口通讯的特点 tips并行通讯?基于网络的通讯?socket通讯 串口通讯 什么是串口通讯? 串行通信每次传输一个位元数据,并在连续进行单次过程的基础上进行通信。根据数据的传送方向&am…...
游戏反Frida注入检测方案
在游戏安全对抗过程中,有不少外挂的实现基于对游戏内存模块进行修改,这类外挂通常会使用内存修改器,除此之外,还有一种门槛相对更高、也更难检测的「注入挂」。 据FairGuard游戏安全数据统计,在游戏面临的众多安全风险…...
观海微电子---AF、AG、AR 的差别和作用
一、名称解释及原理 1.AF ---- Anti-fingerprint,中文为抗指纹。一般 SiO2AF 材料(DON,M4、道康宁 AF 材料),一般采用真空蒸发镀膜法。 原理:AF 防污防指纹玻璃是根据荷叶原理,在玻璃外表面涂制…...
颠覆性语音识别:单词级时间戳和说话人分离
vbenjs/vue-vben-admin[1] Stars: 19.7k License: MIT Vue Vben Admin 是一个免费开源的中后台模板,使用最新的 vue3、vite4 和 TypeScript 等主流技术进行开发。该项目提供了现成的中后台前端解决方案,并可用于学习参考。 使用先进的前端技术如 Vue3/…...
吉利展厅 | 透明OLED拼接2x2:科技与艺术的完美融合
产品:4块55寸OLED透明拼接屏 项目地点:南宁 项目时间:2023年11月 应用场景:吉利展厅 在2023年11月的南宁,吉利展厅以其独特的展示设计吸引了众多参观者的目光。其中最引人注目的亮点是展厅中央一个由四块55寸OLED透…...
qnx修改tcp和udp缓冲区默认大小
拷贝/home/test/qnx/qos223/target/qnx7/aarch64le/sbin/sysctl进系统中 https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.utilities/topic/s/sysctl.html kern.sbmax 默认262144,这个限制住了发送、接收缓冲器大小 ./sysctl -w kern.sbmax10000…...
vscode的eslint检查代码格式不严谨的快速修复
问题: 原因:复制的代码,esLint检查代码格式不正确。或者写的代码位置不严谨,总是提示 解决 设置在Ctrl S保存时自动格式化代码 1、vscode设置 2、点击右上角,切换json模式 3、添加设置 "editor.codeActionsOn…...
OpenAI GPT-4 Turbo发布:开创AI新时代
🎥 屿小夏 : 个人主页 🔥个人专栏 : IT杂谈 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一. GPT-4 Turbo的突破1.1上下文长度和控制手段的加强:1.2多模态支持:…...
基于c 实现 FIFO
功能: 1、读和写长度不限制 2、数据操作 和 指针操作分开(如先操作数据,再操作指针) 适用场景: 单向通信模式,一方写、一方读,可用于任务间单向通信(无需锁) 如&…...
tortoisegit 报错:server refused to start a shell/command
原因:阿里云的云效不支持TortoiseGit 使用 TortoiseGitPlink,请修改为 OpenSSH。 官网修改教程:TortoiseGit 工具相关报错如何处理? 基本流程: 选择设置(Settings),选择通用&#x…...
电商平台API接口指南,京东商品详情接口,京东详情页接口,宝贝详情页接口,商品属性接口,商品信息查询,商品详细信息接口,h5实时详情页数据展示
京东商品详情API接口是京东开放平台提供的一种API接口,通过该接口,可以获取到京东商品的详细信息,如商品名称、价格、图片和描述等信息。 使用方法如下: 注册并获取API密钥:首先需要在京东开放平台上注册并获取API密…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
