log4js-node给每个请求加一个id标识符

背景

现在的一个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')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当使用axios或node-fetch时,你可以封装一个常用的请求函数来简化代码和提高可重用性。以下是一个使用axios或node-fetch封装请求的示例: 使用axios封装请求的示例: ```javascript const axios = require('axios'); async function sendRequest(url, method, data) { try { const response = await axios({ method: method, url: url, data: data }); return response.data; } catch (error) { throw new Error(error.message); } } // 使用示例 sendRequest('https://api.example.com/users', 'GET') .then(data => { console.log(data); }) .catch(error => { console.error(error); }); ``` 使用node-fetch封装请求的示例: ```javascript const fetch = require('node-fetch'); async function sendRequest(url, method, data) { try { const response = await fetch(url, { method: method, body: JSON.stringify(data), headers: { 'Content-Type': 'application/json' } }); const responseData = await response.json(); return responseData; } catch (error) { throw new Error(error.message); } } // 使用示例 sendRequest('https://api.example.com/users', 'GET') .then(data => { console.log(data); }) .catch(error => { console.error(error); }); ``` 在上述示例中,我们封装了一个名为`sendRequest`的函数,该函数接受三个参数:URL、请求方法(GET、POST等)和请求数据(可选)。函数内部使用了axios或node-fetch来发送请求,并处理返回的响应数据。如果请求出现错误,将抛出一个包含错误消息的异常。 你可以根据自己的需求进一步扩展和定制这个封装函数,例如添请求头、处理其他类型的响应数据等。 希望这个示例对你有帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值