在 .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 上找到。
你没有结束 trans1
和 trans2
。
只需将这两行放在它们结束的地方,一切都会正常显示:
trans1.End();
trans2.End();
有 CaptureTransaction
,这是一种方便的方法,可以包装您的任何代码并确保交易结束并捕获所有异常 - 所以您使用该方法并且它确实 "everything" 给你。
然后是 StartTransaction
方法 - 这是您在代码中使用的方法 - 它启动事务并且不执行任何其他操作。这里的优点是您可以获得一个 ITransaction
实例,您可以随时随地使用它。但在这种情况下,您需要在交易(也就是您要捕获的代码)执行后手动调用 .End()
。
与CaptureSpan
and StartSpan
相同。
所以你使用 CaptureSpan
作为你的跨度,所以当 Task.Delay
的 lambda 完成时那些会自动结束,另一方面你使用 StartTransaction
开始你的事务但只调用.End()
trans3
而不是其他 2 笔交易。
我有兴趣在 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 上找到。
你没有结束 trans1
和 trans2
。
只需将这两行放在它们结束的地方,一切都会正常显示:
trans1.End();
trans2.End();
有 CaptureTransaction
,这是一种方便的方法,可以包装您的任何代码并确保交易结束并捕获所有异常 - 所以您使用该方法并且它确实 "everything" 给你。
然后是 StartTransaction
方法 - 这是您在代码中使用的方法 - 它启动事务并且不执行任何其他操作。这里的优点是您可以获得一个 ITransaction
实例,您可以随时随地使用它。但在这种情况下,您需要在交易(也就是您要捕获的代码)执行后手动调用 .End()
。
与CaptureSpan
and StartSpan
相同。
所以你使用 CaptureSpan
作为你的跨度,所以当 Task.Delay
的 lambda 完成时那些会自动结束,另一方面你使用 StartTransaction
开始你的事务但只调用.End()
trans3
而不是其他 2 笔交易。