ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Fastify 如何用 diagnostics_channel 订阅请求追踪事件?

Fastify 如何用 diagnostics_channel 订阅请求追踪事件? Fastify 如何用 diagnostics_channel 订阅请求追踪事件【免费下载链接】fastifyFast and low overhead web framework, for Node.js项目地址: https://gitcode.com/GitHub_Trending/fa/fastify在已经跑起来的 Fastify 服务里你往往需要在不改动任何 handler 代码的前提下追踪请求生命周期请求进入、进入异步阶段、出错、结束分别发生在什么时刻。Fastify v5 起原生支持 Node.js 内置的diagnostics_channel模块按请求发布一组固定的追踪事件外部包如链路追踪工具通过订阅这些 channel 即可拿到每个请求的request、reply和路由信息。本文基于仓库中的 Hooks 参考文档 与 v5 迁移指南 给出订阅、验证和初始化事件的完整做法。Fastify 发布的事件有哪些fastify.initialization事件在实例初始化时发布一次其余五个事件按请求发布遵循 Tracing Channel 命名。事件名、触发条件和 payload 如下来自 Hooks.md 的 Diagnostics Channel Hooks 章节事件触发条件payloadfastify.initialization初始化时{ fastify }tracing:fastify.request.handler:start始终触发{ request, reply, route: { url, method } }tracing:fastify.request.handler:end始终触发{ request, reply, route: { url, method }, async: Bool }tracing:fastify.request.handler:asyncStartpromise/async handler{ request, reply, route: { url, method } }tracing:fastify.request.handler:asyncEndpromise/async handler{ request, reply, route: { url, method } }tracing:fastify.request.handler:error请求出错时{ request, reply, route: { url, method }, error: Error }几个需要注意的行为同一个请求的所有事件携带的是同一个消息对象实例route.url是匹配到的路由模式例如/collection/:id而不是实际请求路径route.method是 HTTP 方法例如GEThandler 是async函数或返回Promise时才会触发asyncStart/asyncEnd。订阅追踪事件并验证下面的脚本把订阅逻辑放在创建 Fastify 实例之前“instrumentation tools first”的常见方式定义一个路由后监听随机端口并发请求验证。结构上参考了 v5 迁移指南的示例 和 同步请求测试、错误场景测试 的写法use strict const diagnostics require(node:diagnostics_channel) const Fastify require(fastify) diagnostics.subscribe(tracing:fastify.request.handler:start, (msg) { console.log(start, msg.route.url, msg.route.method) }) diagnostics.subscribe(tracing:fastify.request.handler:end, (msg) { console.log(end, msg.route.url, msg.route.method, async:, msg.async) }) diagnostics.subscribe(tracing:fastify.request.handler:error, (msg) { console.log(error, msg.error) }) const fastify Fastify() fastify.route({ method: GET, url: /:id, handler: function (req, reply) { return { hello: world } } }) async function main () { const server await fastify.listen({ port: 0 }) const response await fetch(server /7) console.log(response.status, await response.text()) await fastify.close() } main()运行后可以看到文档示例中给出的输出形态start事件打印出路由模式/:id与方法GET请求完成后end事件打印同样的route.url/route.method并额外携带async布尔属性此处为同步 handler故为false。请求本身返回200和{hello:world}说明订阅没有干扰正常处理。验证事件行为时以仓库测试的断言为准正常同步请求start与end各触发一次且携带同一消息对象errorchannel 不触发见 sync-request 测试。handler 抛错如throw new Error(borked)error事件触发且msg.error instanceof Error、error.message为borked随后end仍然触发响应为500见 error-request 测试。async handler在start/end之外还会触发asyncStart与asyncEnd四个事件同为同一消息对象见 async-request 测试。用fastify.initialization订阅初始化事件对于追踪类插件更典型的做法是订阅fastify.initialization在实例创建时给它挂上onRequest/onResponse钩子而不是逐个请求手动管理 span。这是 Hooks.md 给出的示例已按文档原样保留const tracer /* retrieved from elsewhere in the package */ const dc require(node:diagnostics_channel) const channel dc.channel(fastify.initialization) const spans new WeakMap() channel.subscribe(function ({ fastify }) { fastify.addHook(onRequest, (request, reply, done) { const span tracer.startSpan(fastify.request.handler) spans.set(request, span) done() }) fastify.addHook(onResponse, (request, reply, done) { const span spans.get(request) span.finish() done() }) })这段代码需要在创建 Fastify 实例之前加载即文档所说的典型 “require instrumentation tools first” 方式此时可以通过拿到的fastify实例添加钩子、插件、路由或做任何其他修改。tracer是追踪包自身提供的对象需要替换为你自己包的实现。限制与注意事项文档明确提示Node.js 的 TracingChannel 类 API 目前是实验性的可能在 Node.js 的 semver-patch 版本中发生破坏性变更升级 Node.js 后需要回归验证这些事件名和 payload 结构。实现上请求处理代码只在存在订阅者时才发布事件见 handle-request.js 中对channels.hasSubscribers的判断没有订阅者时这些追踪事件不会发布因此对未接入追踪的应用没有运行时影响同理fastify.initialization也没有订阅者时不会发布见 init 测试。事件对象是同一实例的复用不要跨请求缓存消息对象跨请求保存数据如 span应使用WeakMap以request为键这正是fastify.initialization示例的做法。需要继续深入了解钩子与追踪事件的配合方式时可完整阅读 Diagnostics Channel Hooks 一节以及 v5 迁移指南中 Diagnostic Channel support 章节。【免费下载链接】fastifyFast and low overhead web framework, for Node.js项目地址: https://gitcode.com/GitHub_Trending/fa/fastify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表