插桩队列

了解如何手动插桩代码以使用 Sentry 的 Queues 模块

为了确保你有关于消息队列的性能数据,你需要在队列生产者和消费者周围插桩自定义跨度和事务。

为了开始捕获性能指标,使用 Sentry.startSpan 函数包装你的队列生产者事件。你的跨度 op 必须设置为 queue.publish。包含以下属性以丰富你的生产者跨度并添加队列指标:

属性类型描述
messaging.message.idstring消息标识符
messaging.destination.namestring队列或主题名称
messaging.message.body.sizeint消息体的大小(以字节为单位)

你还需要使用 spanToTraceHeaderspanToBaggageHeader 在消息中包含跟踪头,以便消费者在接收到消息后可以继续你的跟踪。

你的 queue.publish 跨度必须作为父跨度的子跨度存在,才能被识别为生产者跨度。如果你还没有父生产者跨度,可以使用 Sentry.startSpan 启动一个新的。

my-queue.js
Copied
app.post("/publish", async (req, res) => {
  // Route handler automatically instruments a parent span
  await Sentry.startSpan(
    {
      name: "queue_producer",
      op: "queue.publish",
      attributes: {
        "messaging.message.id": messageId,
        "messaging.destination.name": "messages",
        "messaging.message.body.size": messageBodySize,
      },
    },
    async () => {
      const { "sentry-trace": sentryTrace, baggage: sentryBaggage } =
        Sentry.getTraceData();
      await redisClient.lPush(
        "messages",
        JSON.stringify({
          sentryTrace,
          sentryBaggage,
          timestamp: Date.now(),
          messageId,
        }),
      );
    },
  );
});

为了开始捕获性能指标,使用 Sentry.startSpan 函数包装你的队列消费者。你的跨度 op 必须设置为 queue.process。包含以下属性以丰富你的消费者跨度并添加队列指标:

属性类型描述
messaging.message.idstring消息标识符
messaging.destination.namestring队列或主题名称
messaging.message.body.sizenumber消息体的大小(以字节为单位)
messaging.message.retry.countnumber消息尝试处理的次数
messaging.message.receive.latencynumber消息在队列中等待处理的时间(以毫秒为单位)

使用 Sentry.continueTrace 将你的消费者跨度连接到其关联的生产者跨度,并使用 setStatus 标记消息的跟踪为成功或失败。

你的 queue.process 跨度必须作为父跨度的子跨度存在,才能被识别为消费者跨度。如果你没有父跨度,可以使用 Sentry.startSpan 创建一个父跨度来包装消费者跨度。

my-consumer.js
Copied
const message = JSON.parse(await redisClient.lPop(QUEUE_KEY));
const latency = Date.now() - message.timestamp;

Sentry.continueTrace(
    { sentryTrace: message.sentryTrace, baggage: message.sentryBaggage },
    () => {
        Sentry.startSpan({
                name: 'queue_consumer_transaction',
            },
            (parent) => {
                Sentry.startSpan({
                    name: 'queue_consumer',
                    op: 'queue.process',
                    attributes: {
                        'messaging.message.id': message.messageId,
                        'messaging.destination.name': 'messages',
                        'messaging.message.body.size': message.messageBodySize,
                        'messaging.message.receive.latency': latency,
                        'messaging.message.retry.count': 0,
                    }
                }, (span) => {
                    ... // Continue message processing
                    parent.setStatus({code: 1, message: 'ok'});
                });
            },
        ),
    },
)