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

企业网站建设需要哪些费用科技创新与应用

企业网站建设需要哪些费用,科技创新与应用,企业官网开发公司,网页微信登陆首页本文介绍在 Golang 的 gin 框架中使用自定义日志模块的一些方法。 背景 很早之前就实现并使用了自己封装的日志模块,但一直没有将gin框架内部的日志和日志模块结合。gin的日志都是在终端上打印的,排查问题不方便。趁五一假期,集中研究把此事…

本文介绍在 Golang 的 gin 框架中使用自定义日志模块的一些方法。

背景

很早之前就实现并使用了自己封装的日志模块,但一直没有将gin框架内部的日志和日志模块结合。gin的日志都是在终端上打印的,排查问题不方便。趁五一假期,集中研究把此事了了。

实践

gin支持中间件,对于一些常用接口,也提供了自定义函数。本文主要是从这2方面着手。

据官方demo,在初始化时基本都使用如下语句初始化内部日志(Logger())和panic恢复功能(Recovery())。

router.Use(gin.Logger())
router.Use(gin.Recovery())

默认输出日志:

[GIN] 2024/05/08 - 09:09:13 | 200 |    1.082244ms |             ::1 | GET      "/info"

自定义Writer

gin对外提供了DefaultWriter,类型为io.Writer,默认输出终端,定义如下:

var DefaultWriter io.Writer = os.Stdout

因此可以修改该参数达到自定义输出日志的目的。代码如下:

f, _ := os.OpenFile(filepath.Join("./", "gin.log"), os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
gin.DefaultWriter = io.MultiWriter(f)

上述代码在当前目录创建gin.log文件,将gin的日志输出到该文件,效果如下:

[GIN] 2024/05/08 - 09:10:54 | 200 |     844.357µs |             ::1 | GET      "/info"

评:自由度不够。

使用中间件

调用语句router.Use(gin.Logger())中的gin.Logger()实际可理解为中间件函数。函数定义:

func XXX() HandlerFunc {
...
}type HandlerFunc func(*Context)

自定义的中间件函数模板:

func XXXs() gin.HandlerFunc {return func(c *gin.Context) {
...// 下一处理c.Next()
...}
}

日志中间件实现如下:

func filterLogs() gin.HandlerFunc {return func(c *gin.Context) {// Start timerstart := time.Now()path := c.Request.URL.Path// Process requestc.Next()// Stop timerlatency := time.Now().Sub(start)clientIP := c.ClientIP()method := c.Request.MethodstatusCode := c.Writer.Status()klog.Printf("middleware | %3d | %13v | %15s | %-7s %#v\n", statusCode, latency,clientIP, method, path)}
}调用:
router.Use(filterLogs())

注:klog.Printf为自封装的日志模块输出函数。源码可参考klog项目。

效果如下:

[2024-05-08 09:44:34 515] [INFO] middleware | 404 |         738ns |             ::1 | GET     "/info"

评:参数gin框架的日志中间件实现简洁版本,自由度较大。可在此函数中再做其它处理。如统计某path的次数,等。

使用日志格式化回调函数

gin中自带了日志格式化的函数LoggerWithFormatter,该函数参数为函数,原型为type LogFormatter func(params LogFormatterParams) string。其本意是可以自定义输出的日志的字段内容,因此返回值为字符串,默认输出还是使用gin.DefaultWriter

因此,可以在该函数中添加日志的打印,但不返回字符串,这样gin框架就不会输出日志了。代码如下:

router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {klog.Printf("| %3d | %13v | %15s | %-7s %#v\n%s", param.StatusCode, param.Latency,param.ClientIP, param.Method, param.Path, param.ErrorMessage)return ""
}))

效果如下:

[2024-05-08 09:44:34 516] [INFO] | 200 |    1.580895ms |             ::1 | GET     "/info"

评:利用现有的中间件,自实现部分代码较简洁。可在此函数中再做其它处理。如统计某path的次数,等。

Recovery中间件实现

gin框架默认的Recovery处理函数gin.Recovery()。与上类似,输出信息也是使用内部日志模块的。为保存可能出现的panic信息,因此需要重新实现。由于原代码已经很完备,只是日志与需求不符,因此并无大改,具体代码如下:

// panic日志记录 替换gin的Recovery函数
func filterRecovery() gin.HandlerFunc {return func(c *gin.Context) {defer func() {if err := recover(); err != nil {// Check for a broken connection, as it is not really a// condition that warrants a panic stack trace.var brokenPipe boolif ne, ok := err.(*net.OpError); ok {if se, ok := ne.Err.(*os.SyscallError); ok {if strings.Contains(strings.ToLower(se.Error()), "broken pipe") ||strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {brokenPipe = true}}}stack := com.GetStack(3)httpRequest, _ := httputil.DumpRequest(c.Request, false)headers := strings.Split(string(httpRequest), "\r\n")for idx, header := range headers {current := strings.Split(header, ":")if current[0] == "Authorization" {headers[idx] = current[0] + ": *"}}headersToStr := strings.Join(headers, "\r\n")if brokenPipe {klog.Printf("%s\n%s", err, headersToStr)} else {klog.Printf("[Recovery] panic recovered:\n%s\n%s", err, stack)}if brokenPipe {// If the connection is dead, we can't write a status to it.c.Error(err.(error)) // nolint: errcheckc.Abort()}}}()c.Next()}
}使用:
router.Use(filterRecovery())

小结

本文介绍的几种方法,基本上都可达到使用自定义日志的目的。笔者实际工程中使用中间件形式,可定制性较高。

附:gin框架日志源码跟踪

外部使用:router.Use(gin.Logger())
--> LoggerWithConfig--> 如未指定formatter,则用defaultLogFormatter--> 如未指定日志输出Write,则用DefaultWriter--> 记录无需要输出的path,存放于skip--> 有请求,遍历skip,如找不到,则组装LogFormatterParams,使用fmt.Fprint输出日志。

从上述流程可以看出,可以通过指定formatter在框架里内嵌自定义的函数,由于会调用fmt.Fprint,因此formatter不返回字符串。当然,可实现自己的中间件替换gin.Logger()

http://www.yayakq.cn/news/729130/

相关文章:

  • 怎么把网站的标题做的炫酷施工企业资质证书有效期
  • seo网站项目讲解安论坛网站建设
  • 越南的网站建设外国做的中国动画视频网站
  • 搭建个人视频网站招聘网站建设费用多少钱
  • 彩票网站wordpress模板wordpress授权登录
  • 大连网站建设运营wordpress源代码在哪里
  • 神州顺利办深一做网站使用session和cookie实现网站自动登录 .net
  • 网站首页flash模板帝国企业网站源码
  • 河南网站建设优化技术做外卖在哪个网站做好
  • 网站备案ip查询网站前端学校网站开发视频教程
  • 可以做软件的网站有哪些内容南阳专业网站制作费用
  • 海口仿站定制模板建站html5网站带后台
  • 巴中网站建设网站推广网站页面设计 8种常见的网站版面布局形式
  • 罗湖做网站运营乐云seowordpress+中文安装
  • 儿童做网站江西吉安建设监督网站
  • 做百度快照要先有网站吗科技股
  • 网页与网站设计实验总结游戏制作软件手机版下载
  • 商务网站业务流程wordpress导出全站链接
  • 亚马逊网网站建设规划报告假电影网站做注册
  • 织梦古典网站模板网络工程解决方案公司
  • vps看网站蜘蛛酒店网站的规划与建设方案
  • 肇庆有哪家做企业网站的长沙seo公司
  • 帮客户做网站挣钱吗舆情分析招聘
  • 网站分辨率建设个人信息网站
  • 网站建设简介淄博做网站工资高么
  • 网站制作公司的流程福建建筑人才服务中心
  • 个人网站怎么建立步骤网站头部固定
  • 免费生成网址白帽seo公司
  • 淄博网站建设高端企业做网站配什么电脑
  • 网站地图网页的制作深圳外网站建设