记录.net core使用elastic apm链路追踪,sql执行没有记录到apm的原因及问题排查记录,包含部分源码阅读理解

项目场景:.net 7  sqlserver  apm-server版本7.7  Elastic.Apm.NetCoreAll版本1.25.3


问题描述

题主最近使用了Elastic Apm的net core版本代理,但是对分布式追踪概念没了解,以为只是简单的记录日志和耗时等操作,但是发现本地调接口是可以正常记录sql,http等日志,但是部署到服务器发现别的服务调用没有记录sql相关日志,于是进行了断断续续的排查过程..

一、有apm记录的应用启用了加密中间件,没有日志时一开始以为时加解密中间件问题,因为这个加密会替换request的body,后面测试取消解密也是一样没记录,只能转向其他方向排查

二、升级Elastic.Apm.NetCoreAll版本,以为是包版本太低了,进行了了一个升级,发现还是没有记录

三、查看官方文档:HTTP configuration options | APM .NET Agent Reference [1.x] | Elastic

由于题主此时还是认为是加解密的问题,所以看了文档也没发现什么配置和加解密或请求body有关

四、以上方式都没定位到问题,只能试试查看源码看看能不能有点发现了,接下来就进入漫长的源码阅读理解了.....

1、首先下载APM Dotnet代理的源码  GitHub - elastic/apm-agent-dotnet

2、查看源码,因为我们用的sqlsugar(底层用的是Microsoft.Data.SqlClient),而APM .NET支持Microsoft.Data.SqlClient和System.Data.SqlClient包的追踪

所以题主看的就是下图这些类了,代码中的Span就是一个操作,多个Span组合就可以组合出调用链,SqlClientDiagnosticListener类中的HandleStartCommand、HandleStopCommand顾名思义就是命令执行前后,既然题主的sql没监控到那就看看HandleStopCommand的逻辑,可以看到里面有一个EndSpan调用

看到上图断点位置,有个判断是否发送到ApmServer,再点击到这个定义,判断IsSampled和!_isDropped,重点就是IsSampled取值,这里取的Transaction的IsSampled(Transaction我理解是Span的集合,多个Span组合就成了Transaction),也就是说Transaction如果IsSampled为True就表示会进行采样,现在就要看看哪里赋值了这个字段

直接查看Transaction类的构造函数引用,是直接由Trace(表示整个请求的最顶层)直接生成的Transaction,查看Trace有一个StartTransaction,也就是每次请求都会生成一个Transaction?所以题主又找了找,发现确实是这样,有一个AspNetCoreDiagnosticListener类会调用WebRequestTransactionCreator.StartTransactionAsync其实也是调用Trace的StartTransaction

重点来啦!!!这里就是读取请求头的traceparent、tracestate来判断当前请求要不要进行采样记录,然后会包装DistributedTracingData数据传给Transaction,而.NET 5后HttpClient默认不采样,导致跨服务Http调用没保存到APM Server!!!

APM  .NET Agent的源码其实也说明了在TraceContext类中TryExtractTracingData方法,感兴趣可以自己研究下


解决方案:

知道原因就很简单啦!按照官网配置下 "TraceContinuationStrategy": "restart_external"就好了

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值