在 .NET Core 上使用 Elastic APM 进行分布式跟踪,非 HTTP

Distributed tracing with Elastic APM on .NET Core, non-HTTP

我有兴趣在 ASP.NET 核心中使用 Elastic APM 来检测一组通过混合协议(HTTP、SQS、SNS)进行通信的服务的跟踪记录。尽管查看了文档,但我不清楚如何使用 Elastic APM Public API 将发生在 HTTP 之外的事务相互连接(Elastic APM 自动检测 HttpClient 以进行跟踪)。

根据文档,我应该能够在调用者上序列化 CurrentTransaction.OutgoingDistributedTracingData 然后反序列化它以在被调用者上恢复事务,但是尽管在内存中实现了这种模式,但我在 Kibana 中的踪迹是除了最终交易之外的所有交易都缺少跨度。

// transaction 1
var trans1 = Agent.Tracer.StartTransaction("Dist Trans 2", ApiConstants.TypeRequest);

await trans1.CaptureSpan("step 1 processing", ApiConstants.ActionExec, async () => await Task.Delay(30));

// transaction 2
var trans2 = Agent.Tracer.StartTransaction("Dist Trans 2", ApiConstants.TypeRequest,
    DistributedTracingData.TryDeserializeFromString(trans1.OutgoingDistributedTracingData.SerializeToString()));

await trans2.CaptureSpan("step 2 processing", ApiConstants.ActionExec, async () => await Task.Delay(30));

// transaction 3
var trans3 = Agent.Tracer.StartTransaction("Dist Trans 2", ApiConstants.TypeRequest,
    DistributedTracingData.TryDeserializeFromString(trans2.OutgoingDistributedTracingData.SerializeToString()));

await trans3.CaptureSpan("step 3 processing", ApiConstants.ActionExec, async () => await Task.Delay(30));

trans3.End();

我的实现峰值可以在 Github 上找到。

你没有结束 trans1trans2

只需将这两行放在它们结束的地方,一切都会正常显示:

trans1.End();
trans2.End();

CaptureTransaction,这是一种方便的方法,可以包装您的任何代码并确保交易结束并捕获所有异常 - 所以您使用该方法并且它确实 "everything" 给你。

然后是 StartTransaction 方法 - 这是您在代码中使用的方法 - 它启动事务并且不执行任何其他操作。这里的优点是您可以获得一个 ITransaction 实例,您可以随时随地使用它。但在这种情况下,您需要在交易(也就是您要捕获的代码)执行后手动调用 .End()

CaptureSpan and StartSpan相同。

所以你使用 CaptureSpan 作为你的跨度,所以当 Task.Delay 的 lambda 完成时那些会自动结束,另一方面你使用 StartTransaction 开始你的事务但只调用.End() trans3 而不是其他 2 笔交易。

有一些演示和演示 here - sample code of that demo is here