问题描述
我使用 OpenTelemetry 和 AWS X-Ray 来跟踪以下之间的 E2E 消息传递:
生产者 (JVM) -> Kafka broker -> 消费者(多个,基于 Python)
然后将生成的跟踪发送到 AWS OTEL Collector,后者将它们转发到 AWS X-Ray。
但是,当我从 X-Ray 消费者跟踪中看到它们时,它们显示为生产者的子段:
我希望将消费者视为一个单独的部分。
我还尝试在消费者端使用 AWS X-Ray SDK 显式初始化一个新段,如下所示:
val traceId = TraceIdData(String(record.headers().headers("X-Amzn-Trace-Id").first().value()))
logger.debug("Trace Id {},Parent Id {}",traceId.root,traceId.parent)
AWSXRay.beginSegment("Simple Kafka Consumer",traceId.parent)
... some processing ...
AWSXRay.endSegment()
然而,即使我正在开始一个新段并指定:trace_id
和 parent_id
,这仍然显示为 AWS X-Ray 中的一个子段。我已经确认这两个属性都不为空且有效。
如何在 AWS X-Ray 中为该持续跟踪生成新的分段?最好,我想使用 OpenTelemetry (agent/sdk/collector) 来做到这一点,但也可以使用 AWS X-Ray SDK。
解决方法
我与 AWS X-Ray 团队进行了交谈,他们帮助我解决了问题。
此问题的原因是 awsxray exporter
仅在 kind=SpanKind.SERVER
时为 Span 创建新段。
我已经使用 OpenTelemetry SDK 实现了这个(在 Python 中),并在创建新的跨度时明确声明了 kind=SpanKind.SERVER
processing_span = self.tracer.start_span(self.service_name,context=current_context,kind=SpanKind.SERVER)
不幸的是,OpenTelemetry java instrumentation for Kafka on consumer side 会自动创建一个新的跨度,其中 kind=CONSUMER 无法修改(作为自动检测的一部分),因此获得我想要的结果的唯一方法是通过手动检测。