我有一些微服务运行着一堆工作负载,并且我正在尝试跟踪给定工作负载的“路线”。我正在使用 .NET Aspire,并添加了 3 个后台工作项目和一个 Web API 项目。
第一个后台工作人员在工作负载到达时启动活动。完成后,它将其推送到 RabbitMQ 队列中。我获取当前活动的 ID 并将其推送到消息的标头中。 Worker 2 在向 Worker 3 推送消息时使用相同的方法。
basicProperties.Headers = new Dictionary<String, Object>();
if (Activity.Current?.Id != null)
{
basicProperties.Headers.Add(DiagnosticsHandlerLoggingStrings.TraceParentHeaderName, Activity.Current?.Id);
}
在工作人员 2 和 3 中,我以这种方式开始一项活动:
if (basicProperties.Headers?.TryGetValue(DiagnosticsHandlerLoggingStrings.TraceParentHeaderName, out var parentActivityIdRaw) == true &&
parentActivityIdRaw is Byte[] traceParentBytes) {
parentActivityId = Encoding.UTF8.GetString(traceParentBytes);
}
return activitySource.StartActivity("Incoming message from queue", kind: ActivityKind.Consumer, parentId: parentActivityId);
使用
HttpClient
,第三个也是最后一个工作线程调用 Web API。
Aspire 中的跟踪页面显示了工作程序 1、工作程序 3 和 Web API。不是工作人员 2。此外,我在工作人员 3 中添加的任何事件都不会显示在详细信息视图中,只有来自
HttpClient
的事件。
跨界继续活动的正确方法是什么?看起来
HttpClient
和 IHttpActivityFeature
也可以处理它,并且实际上正在继续该活动,但是当我在自己的代码中使用 Activity.Current
时,没有任何内容放入活动的事件中,至少它没有显示在跟踪详细信息。
查看跟踪,似乎我正确设置了活动,但不知何故,我无法自己向其中添加事件,尽管
HttpClient
可以。
查看 @martindotnet 提供的链接并进行一些修改后,我终于让它工作了。 这是 RabbitMQ(v7 之前)的解决方案,因此跨边界推送和弹出跟踪是为此完成的,但是!
重要的是您需要在接收端启动活动。
首先是消费者/接收者:
var context = Propagators.DefaultTextMapPropagator.Extract(new PropagationContext(
new ActivityContext(),
Baggage.Current),
ea.BasicProperties,
(properties, key) => {
if (properties.Headers?.TryGetValue(key, out var propertyValue) == true && propertyValue is Byte[] propertyValueBytes) {
return new List<String> { Encoding.UTF8.GetString(propertyValueBytes) };
}
return new List<String> { };
});
using var activity = this.transparencyObservability.ActivitySource.StartActivity(
"Consume Message",
ActivityKind.Consumer,
context.ActivityContext);
Activity.Current?.AddEvent(new ActivityEvent(
"Got message from queue, unpacked, ready to handle"));
出版商:
var basicProperties = channel.CreateBasicProperties();
Propagators.DefaultTextMapPropagator.Inject(
new PropagationContext(Activity.Current?.Context ?? default, Baggage.Current),
basicProperties, (msg, key, value) => {
msg.Headers.TryAdd(key, value);
});
就是这样。传播器是 OpenTelemetry 的一部分,所以没什么魔法!