背景
现在的一个node项目目前只是简单的配置了log4js,使用起来体验不是很好
。请求与请求之间没有特殊标识,当需要查找某个请求的全部日志的时候,相当费劲
ps: 使用的web框架是koa2
尝试的解决方案
- 使用koa-request-id, weekly download(2020年2月21日数据)有4000+, 而且有比较多文章都说这个靠谱,但实际上我发现,这个库只是往context中加了一个request id,并不是说可以再打印日志的时候,自动绑定context中生成的id. 示例代码如下:
const Koa = require('koa');
const requestId = require('koa-requestid');
const app = new Koa();
app.use(requestId());
app.use(async ctx => {
ctx.body = ctx.state.id;
});
app.listen(3000);
返回的结果:
❯ curl -v http://localhost:3000
< HTTP/1.1 200 OK
< Request-Id: cc0f12c7-f3b6-4c86-94c2-8c4ce7751651
cc0f12c7-f3b6-4c86-94c2-8c4ce7751651
- 使用connectLogger方法,查看官方资料发现这个方法是connect/express服务器用来连接log4js的,与koa没有半毛钱关系
- 使用Logger的addContext方法,网上很多的例子都是个半成品,在实际使用过程你发现以下几个坑:
- 如果使用log4js.getLogger(category) 去获取logger,然后打印日志,你发现实际上只有一个context中会有你设置的请求id
- 即使你是log4js.getLogger()方法去获取logger,但只要你在每个文件中使用的logger是这样获取的,那么也还是只有一个context中有请求id
为什么会有这些坑呢? 因为logger.addContext方法是一个实例方法,只要logger实例不一样,那么context就不一样,因此context中的数据不能共享。
解决方案
还是使用addContext方法,但是得做一些调整:
- 系统中使用的logger必须是单例的,这里可以有一个helper类,用于返回单例的logger
- logger的category必须是固定的
示例代码
第一,在app.js中加上中间件,给logger的context加上请求id
const uuidV4 = require('uuid/v4')