@cjanietz/cls-rtracer

中文文档
2.6.0发布于 2021/02/22MITCommonJS近 30 天下载 5853

为基于 CLS 请求的 id 生成、 包括电池在内的 Express & Koa 中间软件并快速化 & Hapi 插件

中文使用文档
文档目录15 节
  1. 支持的 Node.js 版本
  2. 如何使用 - 步骤一
  3. 如何使用 - 第2步(共同指令)
  4. 如何使用它 - 第2步( Express users)
  5. 如何使用 - 第2步(快活用户)
  6. 后遗症 :
  7. 如何使用 - 第2步(Koa用户)
  8. Koa v1 支持
  9. 如何使用它 - 步骤 2 (Hapi 用户)
  10. 与伐木机整合
  11. 配置
  12. 高级特性
  13. 解决问题
  14. 业绩影响
  15. 许可证

travis Coverage Status npm npm

cls-rtracer 读取器

请求跟踪器 - 为基于 CLS 的请求 id 生成,包括电池, Express & Koa 中间软件并快速化 & Hapi 插件. 用于在日志中添加请求ID的外框解决方案 。 检查出来 这个博客文章 说明其背后的理由 cls-rtracer。 。 。 .

自动生成一个 UUID V1 值, 作为每个请求的 ID , 并将其保存在 AsyncLocalStorage (CLS核心 API,见 这个博客文章) (中文(简体) ). 如果请求中包含 X-Request-Id 页眉, 使用它的值 。 允许稍后在路线的任何地方获取生成的请求ID,并用于伐木或任何其他目的.

与快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取快取.

支持的 Node.js 版本

作为 cls-rtracer v2 取决于 AsyncLocalStorage API,它要求节点 12.1.7.0+, 13.14.0+,或 14.0.0+. 如果你碰巧使用一个更古老的Node.js版本,你应该使用 cls-rtracer 单曲 基础 cls-hooked。 。 。 .

如何使用 - 步骤一

安装 :

npm install --save cls-rtracer

TypeScript用户的说明:包含打字.

如何使用 - 第2步(共同指令)

使用库在第一个需要访问请求ID的中间软件之前提供的中间软件(或插件). 注意一些中间软件,可能导致CLS上下文(即Async Hooks执行路径)丢失. 为避免这类问题,您应当使用不需要访问的第三方中间软件来请求ID 在此之前 你用这个中间软件。 参见第20期作例.

如何使用它 - 第2步( Express users)

使用库提供的中间软件 :

const express = require('express')
const rTracer = require('cls-rtracer')

const app = express()
// any third party middleware that does not need access to request ids goes here
// ...

app.use(rTracer.expressMiddleware())
// optionally, you can override default middleware config:
// app.use(rTracer.expressMiddleware({
//   useHeader: true,
//   headerName: 'X-Your-Request-Header'
// }))

// all code in middlewares, starting from here, has access to request ids

在收到的请求中获取请求ID:

// an example middleware for a generic find entity endpoint
app.get('/api/v1/entity/{id}', (req, res, next) => {
  entityService.find(req.params.id)
    .then((entity) => {
      // you can obtain the request id here
      const requestId = rTracer.id()
      console.log(`requestId: ${requestId}`)
      
      res.json(entity)
    })
    .catch(next)
})

您可以从无法访问快递的代码获取相同的请求ID' req 对象.

// an imaginary entity-service.js
async function find (entityId) {
  // you can obtain the request id here
  const requestId = rTracer.id()
  // ...
}

如何使用 - 第2步(快活用户)

使用库提供的插件 :

const fastify = require('fastify')()
const rTracer = require('cls-rtracer')

// any third party plugin that does not need access to request ids goes here
// ...

fastify.register(rTracer.fastifyPlugin)
// optionally, you can override default plugin config:
// fastify.register(rTracer.fastifyPlugin, {
//   useHeader: true,
//   headerName: 'X-Your-Request-Header'
// }))

// all code in plugins or handlers, starting from here, has access to request ids

处理者收到请求时获取请求编号 :

// an example handler for a generic find entity endpoint
// router config is skipped for the sake of simplicity
app.get('/test', async (request, reply) => {
  const entity = await entityService.find(request.params.id)
  // you can obtain the request id here
  const requestId = rTracer.id()
  console.log(`requestId: ${requestId}`)

  reply.send(entity)
})

您可以从无法访问 Fastify 的代码访问相同的请求 ID request 对象.

// an imaginary entity-service.js
async function find (entityId) {
  // you can obtain the request id here
  const requestId = rTracer.id()
  // ...
}

后遗症 :

有一种连接式的中间软件可供Fastify v2使用,但它被贬值并可能在即将发布的版本中被移除. 如果您碰巧在应用程序中使用了它,应当迁移到快取插件.

fastify.use(rTracer.fastifyMiddleware())

如何使用 - 第2步(Koa用户)

使用库提供的中间软件 :

const Koa = require('koa')
const rTracer = require('cls-rtracer')

const app = new Koa()
// any third party middleware that does not need access to request ids goes here
// ...

app.use(rTracer.koaMiddleware())
// optionally, you can override default middleware config:
// app.use(rTracer.koaMiddleware({
//   useHeader: true,
//   headerName: 'X-Your-Request-Header'
// }))

// all code in middlewares, starting from here, has access to request ids

在收到的请求中获取请求ID:

// an example middleware for a generic find entity endpoint
// router config is skipped for the sake of simplicity
app.use(async (ctx) => {
  const entity = await entityService.find(req.params.id)
  // you can obtain the request id here
  const requestId = rTracer.id()
  console.log(`requestId: ${requestId}`)

  ctx.body = entity
})

您可以从无法访问 Koa 代码的代码获取相同的请求 ID ctx 对象.

// an imaginary entity-service.js
async function find (entityId) {
  // you can obtain the request id here
  const requestId = rTracer.id()
  // ...
}

Koa v1 支持

对 Koa v1 使用 koaV1Middleware(options) 函数.

如何使用它 - 步骤 2 (Hapi 用户)

使用库提供的插件 :

const Hapi = require('@hapi/hapi')
const rTracer = require('cls-rtracer')

const init = async () => {
  const server = Hapi.server({
    port: 3000,
    host: 'localhost'
  })
  // any third party plugin that does not need access to request ids goes here
  // ...

  await server.register({
    plugin: rTracer.hapiPlugin
  })

  // optionally, you can override default middleware config:
  //  await server.register({
  //    plugin: rTracer.hapiPlugin,
  //    options: {
  //      useHeader: true,
  //      headerName: 'X-Your-Request-Header'
  //    }
  //  })

  // all code in routes, starting from here, has access to request ids
}

init()

根据收到的请求在路由处理器中获取请求ID:

// an example route for a generic find entity endpoint
server.route({
  method: 'GET',
  path: '/test',
  handler: async (request, h) => {
    const entity = await entityService.find(request.params.id)
    // you can obtain the request id here
    const requestId = rTracer.id()
    console.log(`requestId: ${requestId}`)

    return entity
  }
})

您可以从无法访问 Hapi 的代码获取相同的请求 ID request 对象.

// an imaginary entity-service.js
async function find (entityId) {
  // you can obtain the request id here
  const requestId = rTracer.id()
  // ...
}

与伐木机整合

这个库的主要用途是请求id生成和日志自动化. 您可以在一个地方与任何日志库整合,并在您的应用程序的日志中获取请求ID.

在日志中没有请求 id 作为关联值, 您将无法确定哪些日志条目属于处理同一请求的代码 。 你可以手动生成请求代号,并将其存储在快递中' req 对象(或快取) request,或者科亚的 ctx),但随后您必须明确将对象传入路由上所有其他模块. 这时候 cls-rtracer 来救援!

这就是你如何融入 cls-rtracer 与 温通最受欢迎的伐木图书馆之一.

const { createLogger, format, transports } = require('winston')
const { combine, timestamp, printf } = format

// a custom format that outputs request id
const rTracerFormat = printf((info) => {
  const rid = rTracer.id()
  return rid
    ? `${info.timestamp} [request-id:${rid}]: ${info.message}`
    : `${info.timestamp}: ${info.message}`
})

const logger = createLogger({
  format: combine(
    timestamp(),
    rTracerFormat
  ),
  transports: [new transports.Console()]
})

Express、Fastify和Koa的完整样本见 /samples/ 目录.

配置

这些是用于中件/插件函数的现有配置选项 。 所有配置条目都是可选的 .

{
  // Add request id to response header (default: false).
  // If set to true, the middleware/plugin will add request id to the specified
  // header. Use headerName option to specify header name.
  echoHeader: false,
  // Respect request header flag (default: false).
  // If set to true, the middleware/plugin will always use a value from
  // the specified header (if the value is present).
  useHeader: false,
  // Request/response header name, case insensitive (default: 'X-Request-Id').
  // Used if useHeader/echoHeader is set to true.
  headerName: 'X-Request-Id',
  // A custom function to generate your request ids (default: UUID v1).
  // The function will receive the intercepted request (as-is from the framework
  // being used) as its first argument. The returned id could be a usual string,
  // or a number, or any custom object, like in the example below.
  // Ignored if useHeader is set to true.
  requestIdFactory: (req) => ({
    id: 'Your request id',
    customHeader: req.headers['X-Custom-Header']
  }),
  // Use request id generated by Fastify instead of generating a new id.
  // Only available for the Fastify plugin.
  useFastifyRequestId: false,
}

高级特性

在某些情况下,您可能想要在请求处理器范围之外,比如在作为背景工作的代码中提供身份标识。 在这种情况下,你可以使用 runWithId() 函数 :

const rTracer = require('cls-rtracer')

rTracer.runWithId(() => {
  console.log(rTracer.id()) // id is available here
  setInterval(() => {
    console.log(rTracer.id()) // and here
  }, 1000)
})

// you may override id by providing the 2nd argument
rTracer.runWithId(() => {
  // ...
}, 42) // 42 is the id override here

// async/await syntax is also supported, as `runWithId()`
// returns the result of `fn`
await rTracer.runWithId(myAsyncFn)

解决问题

为了避免奇怪的行为:

  • 确保您使用任何不需要访问的第三方中间软件( 或插件) 来请求 ID 在此之前 您使用时 cls-rtracer。见 本节。 。 。 .

注意:你使用一个难得的图书馆的机会很小, 所以,如果在上下文(因此,请求id)在某处Async调用链被丢失时面临问题,请将GitHub问题提交详细描述.

业绩影响

注意,由于Async Hooks API的使用,这个库对您的应用具有一定的性能影响. 因此,你需要决定,在没有任何锅炉板的木头中追踪请求的好处,是否比性能影响的缺点,对您更有价值.

这个图书馆的作者做了一些基本的性能测试. 见 这个推特 看结果。 间接费用也有所减少 cls-rtracer v2 由于迁移到核心API. 见 这个推特 学习更多.

许可证

根据麻省理工学院的许可.

版本与发布记录

@cjanietz/cls-rtracer 共发布 1 个版本,首次发布于 2021/02/22;过去 12 个月发布了 0 个版本。

版本发布日期距今
2.6.0latest2021/02/225 年前

关于 @cjanietz/cls-rtracer 的常见问题

@cjanietz/cls-rtracer 是什么?

为基于 CLS 请求的 id 生成、 包括电池在内的 Express & Koa 中间软件并快速化 & Hapi 插件

如何安装 @cjanietz/cls-rtracer?

在项目目录运行 npm install @cjanietz/cls-rtracer,或使用 pnpm add / yarn add / bun add。

@cjanietz/cls-rtracer 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/cjanietz__cls-rtracer 是否存在。

@cjanietz/cls-rtracer 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@cjanietz/cls-rtracer 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=12.17.0 <13.0.0 || >=13.14.0 <14.0.0 || >=14.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cjanietz/cls-rtracer 可以商用吗?

@cjanietz/cls-rtracer 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cjanietz/cls-rtracer 的下载量有多少?

根据 npm 官方下载统计,@cjanietz/cls-rtracer 在 2026/10/10 – 2026/11/08 这 30 天内被下载 5,853 次,日均约 195 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cjanietz/cls-rtracer 还在维护吗?

最新版本 2.6.0 发布于 2021/02/22(5 年前);至今共发布 1 个版本,其中过去 12 个月发布了 0 个;首次发布于 2021/02/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。