用nestjs(express)
做了一个简单的服务
目前用 winston
替换了 nestjs
的默认日志及 typeorm
的日志
有时候需要查看日志定位问题,所以想在日志中添加 traceId
用于追踪一次 request
的完整链路,最好是无代码侵入的
有查到使用 Async hooks
进行 request
上下文保存的
大家有没有已实现的方案?
1
lzgshsj 2023-08-11 17:50:43 +08:00
没用 winston ,用的 pino ,自带了 genReqId 的方法
|
2
NessajCN 2023-08-11 17:51:15 +08:00
既然是你自己做的服务那你就在 logger.log()的时候把你要的 traceId 加进去呗....
没怎么看懂你有什么进一步需求 |
3
zzh2036 OP @NessajCN 需要调用其他函数的时候,traceId 要当做参数继续传递下去吗?因为之前没有做过 traceId 这些,所以想知道一些详细的方案。traceId 的生成能和 jwt 中的 userId 做一些关联吗?
|
5
NessajCN 2023-08-11 18:05:02 +08:00
@zzh2036 哦所以你问的是 tracerId 的生成问题而不是怎么在日志里加 id 的问题是吧?
这个讲道理没有什么固定规则呀当然你怎么看得顺眼怎么来。要我的话函数名加个时间戳么差不多了...最多再加个 api 名 |
6
thynson 2023-08-11 18:05:40 +08:00
nestjs 是不太好做的,所以我自己实现了一个类似的框架 sensejs
进一步了解: https://sensejs.io 或者 https://github.com/sensejs/sensejs |
7
thynson 2023-08-11 18:07:05 +08:00
|
8
zzh2036 OP @NessajCN 有如何在日志中加 id 的疑问,刚才说的 logger.log()直接加 traceId ,那如果调用其它函数,traceId 要当做参数继续往下传递是吧?
|
9
thynson 2023-08-11 18:14:30 +08:00
@zzh2036 NestJS 印象中我是这么做的,在依赖注入框架下,然后在每个类初始化的时候用,可以把 requestId 注入进来,并关联到 Logger 上,requestId 的产生需要定义一个 provider 。当然这种做法还是有一定的侵入性
|
13
victimsss 2023-08-11 18:19:54 +08:00
@NessajCN 大概是在中间件使用 continuation-local-storage 或者 cls-hooked 记录 jwt 的 id 或者 生产的 reqId 然后供上下文使用,然后 logger 记录的时候不需要显式传参。
|
14
crysislinux 2023-08-11 18:27:11 +08:00 via Android
async hooks 不是 100%可靠的。这点比较坑,打日志可以用,但是不要做业务,比如存储 tenant id 之类的
|
16
Helios0 2023-08-11 21:20:13 +08:00
nestjs-cls https://papooch.github.io/nestjs-cls/
或者自己实现一个中间件也是一样的 |
17
zurmokeeper 2023-08-11 21:32:06 +08:00
个人暂时还是比较笨的方法实现,把 logger 对象挂在 req 上,请求的开头自己生成一个 traceid,挂上去,后续这个 req ,在 nestjs 的生命周期里都是能拿到的,然后用类似 req.logger.debug() 这种方式打印,整个生命周期就都是用 traceid 关联的了。如果还有其他服务,也可以把这个 traceid 放到请求头或者其他地方,一路传下去,也可以实现多个服务被一个 traceid 串起来的功能
|
18
owen800q 2023-08-12 00:25:39 +08:00 via iPhone
|
20
zzh2036 OP @zurmokeeper 很实用的想法,我之前想到在请求拦截中生成 traceId ,挂在 req 对象上,controller 里解出来,后续一直在 service 中做传递。但觉得应该有更优雅的实现
|
21
guiling 2023-08-22 10:59:54 +08:00
当初网上确实找不到成熟方案,所以自己实现的,核心就是利用 AsyncLocalStorage
1 使用 express-request-id 作为日志的 traceid 2 基于 AsyncLocalStorage 自己写一个中间件,获取请求头里的 traceid 并赋值到 AsyncLocalStorage 的实例中,这个是最核心的,代码不多,node 版本好想要 14 以上,网上有相关教程 3 重写 console 的 log 合 error 方法,日志就用这两个,没用第三方 logger ,这样所有请求默认的日志就会带 traceid 4 关于定时任务因为不走请求所以没有 traceid ,需要自己随机生成一个然后在最外层包进去(我是机器时间+任务名) 最终效果大概这样 https://s2.loli.net/2023/08/22/9EOeUzQD5XvAqWj.png 定时任务的 https://s2.loli.net/2023/08/22/x4dHy8wcLiM5mP3.png 理论上最终可以做成想 java 那样的把模块方法名也打印出来 |