拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Hono 如何用 timing 中间件输出 Server-Timing 响应指标?

Hono 如何用 timing 中间件输出 Server-Timing 响应指标【免费下载链接】honoWeb framework built on Web Standards项目地址: https://gitcode.com/GitHub_Trending/ho/hono如果你需要让 Hono 应用的每个 HTTP 响应都带上服务端耗时指标Hono 内置的timing中间件可以把这些数据写入响应的Server-Timing响应头既包括整次请求的总耗时也包括在 handler 里手动打点得到的分段指标。本文基于仓库中的中间件源码与测试文件讲清楚如何挂载中间件、添加自定义指标以及如何验证Server-Timing头的实际输出。准备项目并导入中间件npm 包的导出入口是hono/timing子路径package.json 的exports中声明了./timingJSR 端在 jsr.json 里同样有./timing导出对应源码 src/middleware/timing/timing.ts。模块共导出 5 个成员见 src/middleware/timing/index.tstiming、setMetric、startTime、endTime、wrapTime。import { Hono } from hono import { timing, setMetric, startTime, endTime, wrapTime } from hono/timing挂载 timing 中间件最小用法const app new Hono() // add the middleware to your router app.use(timing())timing()接收一个可选的配置对象TimingOptions各项默认值定义在源码 src/middleware/timing/timing.ts#L76-L84 中配置项默认值作用来自源码 JSDoctotaltrue是否输出总响应时间指标enabledtrue是否将指标写入响应头也可以传(c) boolean函数按请求判断totalDescriptionTotal Response Time总耗时指标的描述文本autoEndtrue请求结束时未结束的startTime计时器是否自动结束并计入crossOriginfalse是否追加Timing-Allow-Origin头可以是true、origin 字符串或函数如果想让总耗时指标带上自己的描述测试文件里的写法是app.use( *, timing({ totalDescription: my total DescRipTion!, }) )在 handler 中添加自定义指标仓库测试 src/middleware/timing/index.test.ts 给出了可直接参照的完整示例app.get(/api, async (c) { startTime(c, sleep) await new Promise((r) setTimeout(r, 30)) endTime(c, sleep) return c.text(api!) })三种添加指标的方式startTime/endTime手动打点按名字开启一个计时器处理完再结束耗时毫秒会在endTime时写入Server-Timing头。endTime和带数值参数的setMetric都可以传可选的precision参数控制小数位数源码中的格式化逻辑是valueDescription.toFixed(precision || 1)即不传precision时按 1 位小数格式化。wrapTime包装 Promise源码 JSDoc 示例为const data await wrapTime(c, query, db.findMany(...))其中db.findMany(...)替换为你要计时的任何 Promise。wrapTime内部先调用startTime并在try/finally中调用endTimePromise 被 reject 时也会记录耗时。setMetric静态值或无值标签// add custom metrics setMetric(c, region, europe-west3) // add custom metrics with timing, must be in milliseconds setMetric(c, custom, 23.8, My custom Metric)JSDoc 明确说明setMetric传数值时表示耗时必须以毫秒为单位。验证 Server-Timing 响应头仓库自己的测试用 Hono 内置的app.request()方法做验证——src/hono-base.ts 中的注释说明.request() is a useful method for testing。你可以按同样方式验证const res await app.request(http://localhost/api) res.headers.has(server-timing) // true res.headers.get(server-timing) // 包含 sleep;dur 与 total;dur测试文件中的断言就是验证标准总耗时指标头中包含total;dur以及totalDescription配置的文本自定义计时器头中包含sleep;dur无值指标头中包含region;desceurope-west3多条指标用逗号拼接后追加到同一个Server-Timing头源码为c.res.headers.append(Server-Timing, headers.join(,))。注意dur后面的数值是每次请求的运行时测量值测试只断言指标名;dur这种模式没有固定具体数字你也不需要把耗时和某个固定值比对。跨域读取Timing-Allow-Origin配置crossOrigin后中间件会额外写入Timing-Allow-Origin头。测试文件覆盖了三种写法timing({ crossOrigin: true }) // Timing-Allow-Origin: * timing({ crossOrigin: https://example.com }) // Timing-Allow-Origin: https://example.com timing({ crossOrigin: (c) c.req.header(origin) ?? * }) // 按请求的 origin 动态返回默认的crossOrigin: false只输出Server-Timing不写Timing-Allow-Origin这一点也有对应测试断言。边界行为与常见警告在未挂载timing()中间件的路由上调用setMetric/startTime/endTime不会抛异常而是打印Metrics not initialized! Please add the \timing() middleware to this route! 并跳过该次调用。endTime结束时如果计时器不存在名字拼错或从未startTime会打印Timer nonExistentTimer does not exist!并跳过。autoEnd: false时未手动结束的计时器不会被写进响应头——测试断言此时头中不包含test;dur。enabled为false或函数返回false时该请求不输出Server-Timing头中间件只在写入响应头前检查enabled指标本身仍记录在上下文里。父路由与子路由重复挂载timing()不会重复输出中间件发现上下文中已有 metric 状态时直接放行测试 Should not be enabled if the main app has the timing middleware 验证了子应用/sub仍只输出一次总指标且无警告。时间来源优先使用performance.now()当 performance API 不可用时回退到Date.now()这一点有专门的测试用例。下一步完整的选项列表、指标格式与 JSDoc 示例见 src/middleware/timing/timing.ts本文所有验证断言来自 src/middleware/timing/index.test.ts。仓库提供npm test脚本package.json中定义为tsc -p tsconfig.spec.json vitest --run可以运行包含上述 timing 用例在内的完整测试套件。【免费下载链接】honoWeb framework built on Web Standards项目地址: https://gitcode.com/GitHub_Trending/ho/hono创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门