V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zzh2036
V2EX  ›  Node.js

nestjs 日志问题 traceId

  •  
  •   zzh2036 · 261 天前 · 1982 次点击
    这是一个创建于 261 天前的主题,其中的信息可能已经有所发展或是发生改变。

    nestjs(express)做了一个简单的服务
    目前用 winston替换了 nestjs的默认日志及 typeorm的日志
    有时候需要查看日志定位问题,所以想在日志中添加 traceId用于追踪一次 request的完整链路,最好是无代码侵入的
    有查到使用 Async hooks进行 request上下文保存的
    大家有没有已实现的方案?

    23 条回复    2023-08-22 13:55:33 +08:00
    lzgshsj
        1
    lzgshsj  
       261 天前
    没用 winston ,用的 pino ,自带了 genReqId 的方法
    NessajCN
        2
    NessajCN  
       261 天前
    既然是你自己做的服务那你就在 logger.log()的时候把你要的 traceId 加进去呗....
    没怎么看懂你有什么进一步需求
    zzh2036
        3
    zzh2036  
    OP
       261 天前
    @NessajCN 需要调用其他函数的时候,traceId 要当做参数继续传递下去吗?因为之前没有做过 traceId 这些,所以想知道一些详细的方案。traceId 的生成能和 jwt 中的 userId 做一些关联吗?
    zzh2036
        4
    zzh2036  
    OP
       261 天前
    @lzgshsj 你是用了 fastify 还是 express 配合 pino 使用的?
    NessajCN
        5
    NessajCN  
       261 天前
    @zzh2036 哦所以你问的是 tracerId 的生成问题而不是怎么在日志里加 id 的问题是吧?
    这个讲道理没有什么固定规则呀当然你怎么看得顺眼怎么来。要我的话函数名加个时间戳么差不多了...最多再加个 api 名
    thynson
        6
    thynson  
       261 天前
    nestjs 是不太好做的,所以我自己实现了一个类似的框架 sensejs
    进一步了解: https://sensejs.io 或者 https://github.com/sensejs/sensejs
    thynson
        7
    thynson  
       261 天前
    zzh2036
        8
    zzh2036  
    OP
       261 天前
    @NessajCN 有如何在日志中加 id 的疑问,刚才说的 logger.log()直接加 traceId ,那如果调用其它函数,traceId 要当做参数继续往下传递是吧?
    thynson
        9
    thynson  
       260 天前
    @zzh2036 NestJS 印象中我是这么做的,在依赖注入框架下,然后在每个类初始化的时候用,可以把 requestId 注入进来,并关联到 Logger 上,requestId 的产生需要定义一个 provider 。当然这种做法还是有一定的侵入性
    NessajCN
        10
    NessajCN  
       260 天前 via Android
    @zzh2036 这个都是你自己决定的…你想接着用这个 id 就往下传,想用个新的就再生成一个呗
    zzh2036
        11
    zzh2036  
    OP
       260 天前
    @thynson 感谢大佬,我去试试
    zzh2036
        12
    zzh2036  
    OP
       260 天前
    @NessajCN 感谢大佬,大概了解一些了
    victimsss
        13
    victimsss  
       260 天前
    @NessajCN 大概是在中间件使用 continuation-local-storage 或者 cls-hooked 记录 jwt 的 id 或者 生产的 reqId 然后供上下文使用,然后 logger 记录的时候不需要显式传参。
    crysislinux
        14
    crysislinux  
       260 天前 via Android
    async hooks 不是 100%可靠的。这点比较坑,打日志可以用,但是不要做业务,比如存储 tenant id 之类的
    zzh2036
        15
    zzh2036  
    OP
       260 天前
    @victimsss 总结的太棒了😀
    Helios0
        16
    Helios0  
       260 天前
    nestjs-cls https://papooch.github.io/nestjs-cls/
    或者自己实现一个中间件也是一样的
    zurmokeeper
        17
    zurmokeeper  
       260 天前
    个人暂时还是比较笨的方法实现,把 logger 对象挂在 req 上,请求的开头自己生成一个 traceid,挂上去,后续这个 req ,在 nestjs 的生命周期里都是能拿到的,然后用类似 req.logger.debug() 这种方式打印,整个生命周期就都是用 traceid 关联的了。如果还有其他服务,也可以把这个 traceid 放到请求头或者其他地方,一路传下去,也可以实现多个服务被一个 traceid 串起来的功能
    owen800q
        18
    owen800q  
       260 天前 via iPhone
    @z
    @zurmokeeper 把 logger 放到 req 是個不錯的想法,反正 req 都要一直往下傳的
    zzh2036
        19
    zzh2036  
    OP
       258 天前
    @Helios0 感谢大佬,这个 nestjs-cls 中 requestID 的 case ,比较符合我想要的效果
    zzh2036
        20
    zzh2036  
    OP
       258 天前
    @zurmokeeper 很实用的想法,我之前想到在请求拦截中生成 traceId ,挂在 req 对象上,controller 里解出来,后续一直在 service 中做传递。但觉得应该有更优雅的实现
    guiling
        21
    guiling  
       250 天前
    当初网上确实找不到成熟方案,所以自己实现的,核心就是利用 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 那样的把模块方法名也打印出来
    zzh2036
        22
    zzh2036  
    OP
       250 天前
    @guiling 不错的实现方式。我目前直接引用了 nestjs-cls 这个包,全局注册时自定义了 traceid 生成规则,在 winston logger 的 printf 方法中通过 cls 取出 traceid 进行打印。
    guiling
        23
    guiling  
       250 天前
    @zzh2036 看了下原理一样的,也是基于 AsyncLocalStorage ,可惜当初做的时候这包还没出来,不然就省事了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4326 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 10:11 · PVG 18:11 · LAX 03:11 · JFK 06:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.