大项目之日志中间件 | 青训营笔记

75 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天

在开发大项目的过程中,我发现日志很头疼,打印的日志重启之后就不见了,有没有一种方法能将日志持久化的保存下来呢?

比如:什么时候出现的错误?错误发生在哪一行?是哪个请求引起的?携带的参数又是什么?等待信息都要记录下来,方便出问题的时候查看和分析原因,那么有没有办法呢?

答案是当然有,gin也有自己本身的日志中间件,gin.Default就已经默认调用用了日志中间件的,与之一起调用的还有recover中间件。

image.png

但是这个日志中间件的功能并不能满足我们的需求,而我在官方文档中翻阅到可以自定义日志文件,如同所示:

image.png

但是我最后弄完后发现如果是GET请求,参数在url路径中,我们很容易拿到,但是如果是POST请求,就拿不到参数,或者很麻烦,写在这里代码会很多,然后我就将这个其封装成一个中间件,所以访问进来的请求都会经过这个中间件。

image.png

代码如下:

image.png

代码详解:

通过定义一个函数,返回gin.HandlerFunc就算是自定义了一个中间件,在其中我们可以写自己的逻辑。

首先return了一个func,参数传入gin.Context,先给日志一个id,方便后续我们根据日志id去在海量的日志中查询具体的错误,这个日志id设置在gin的上下文中,在一个接口调用的整个过程,该日志id都会伴随,那个地方出现错误,我们可以直接根据日志id定位到。

然后是记录接口调用的开始时间,请求路径,结束时间。

下面这里的body可能有点疑惑,这里是我make了一个切片,长度就是请求时的content长度,因为我发现,如果未携带了参数,这个长度就是0,反之则有长度。

下面我判断长度大于0,表示有参数进入,因为有些请求的参数,我发现带有\r\n符号,打印出来的日志占好几行,很不好看,还有的会带有大量空格,总之我就想让参数在一排显示,看起来规整一点。

然后我在下面将请求方法,请求状态,结束时间,ip地址,请求路径,参数,日志id,错误和请求头等信息放入一个map中,最后调用InfoJson这个自己定义的方法,将这条日志以json的格式输出。

虽然整个过程看起来可能有点复杂,没有用到一些常用的日志库, logrus或zap等,但收获还是非常大的,除了学会自定义中间件外,在调试怎么才能获取参数的时候,对gin的context携带了那些信息,有了更多的了解。