news 2026/7/2 5:56:26

无侵入自动化探针原理和主流实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
无侵入自动化探针原理和主流实现

平台相关指标采集#

那么APM探针都是如何采集 .NET 平台相关指标呢?其实采集这些指标在 .NET 上是非常简单的,因为.NET提供了相关的API接口,我们可以直接获得这些指标,这里指的平台指标是如 CPU 占用率、线程数量、GC 次数等指标。

比如在 SkyAPM-dotne t项目中,我们可以查看 SkyApm.Core 项目中的 Common 文件夹,文件夹中就有诸如里面有 CPU 指标、GC 指标等平台相关指标采集实现帮助类。

同样,在 OpenTelemetry-dotnet-contrib 项目中,我们可以在 Process 和 Runtime 文件夹中,查看进程和运行时等平台相关指标采集的实现。

这些都是简单的 API 调用,有兴趣的同学可以自行查看代码,本文就不再赘述这些内容。

组件相关指标采集#

除了平台相关指标采集,还有组件相关的指标,这里所指的组件相关指标拿 ASP.NET Core 应用程序举例,我们接口秒并发是多少、一个请求执行了多久,在这个请求执行的时候访问了哪些中间件( Redis 、MySql 、Http 调用、RPC 等等),访问中间件时传递的参数(Redis 命令、Sql 语句、请求响应体等等)是什么,访问中间件花费了多少时间。

在 SkyAPM-dotnet 项目中,我们可以直接在src目录找到这些组件相关指标采集的实现代码。

同样在 OpenTelemetry-dotnet-contrib 项目中,我们也可以在src目录找到这些组件相关指标采集代码。

如果看过这两个APM探针实现的朋友应该都知道,组件指标采集是非常依赖DiagnosticSource技术。.NET官方社区一直推荐的的方式是组件开发者自己在组件的关键路径进行埋点,使用DiagnosticSource的方式将事件传播出去,然后其它监测软件工具可以订阅DiagnosticListener来获取组件运行状态。

就拿 ASP.NET Core 来举例,组件源码中有[HostingApplicationDiagnostics.cs](https://github.com/dotnet/aspnetcore/blob/main/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs)这样一个类,这个类中定义了 Hosting 在请求处理过程中的几个事件。

internal const string ActivityName = "Microsoft.AspNetCore.Hosting.HttpRequestIn"; private const string ActivityStartKey = ActivityName + ".Start"; private const string ActivityStopKey = ActivityName + ".Stop";

当 Hosting 开始处理请求时,会检测当前是否有监听者监听这些事件,如果有的话就会写入事件,事件也会携带当前的一些上下文信息,代码如下所示:

以 SkyAPM-dotnet 举例,有对应的HostingTracingDiagnosticProcessor.cs监听事件,然后获取上下文信息记录 APM 埋点信息,代码如下所示:

这种方式的优点有:

  • 高效和高性能:DiagnosticSource是 .NET 平台自带的框架,使用它硬编码可以享受到编译器和 JIT 相关优化可以避免一些性能开销。组件开发者可以控制事件传递的频率和内容,以达到最佳的性能和资源利用率。
  • 灵活:通过使用DiagnosticSource,组件开发者可以灵活地定义自己的事件模型,并按需发布事件。这意味着可以轻松地定制自己的监测需求,而不必担心过多的日志数据产生过大的开销。
  • 可扩展性:使用DiagnosticSource可以让组件的监测需求随着时间的推移而演变,而不必担心日志系统的限制。开发者可以根据自己的需要添加新的事件类型,以适应不断变化的监测需求。
  • 易用性:DiagnosticSource的 API 简单易用,订阅事件数据也很容易。这使得使用它进行组件监测变得非常容易,并且可以快速地集成到现有的监测系统中。
  • 可移植性:DiagnosticSource可以在多个平台上运行,包括 Windows、Linux 和 macOS 等。这意味着可以使用相同的事件模型来监测不同的应用程序和服务,从而简化了监测系统的设计和管理。

不过这种方式的缺点也很明显,就是必须由组件开发者显式的添加事件代码,探针的开发者也因此束手束脚,这就导致一些没有进行手动埋点的三方组件都无法添加事件监听,所以现阶段 SkyAPM-dotnet 支持的第三方组件还不是很丰富。

那么其实只要解决如何为没有进行手动埋点的组件库加入埋点就能解决 SkyAPM-dotnet 支持第三方组件多样性的问题。

.NET方法注入#

从上一节我们可以知道,目前制约APM支持组件不够丰富的原因之一就是很多组件库都没有进行可观测性的适配,没有在关键路径进行埋点。

那么要解决这个问题其实很简单,我们只需要修改组件库关键路径代码给加上一些埋点就可以了,那应该如何给这些第三方库的代码加点料呢?聊到这个问题我们需要知道一个 .NET 程序是怎么从源代码变得可以运行的。

通常情况下,一个 .NET 程序从源码到运行会经过两次编译(忽略 ReadyToRun 、NativeAOT 、分层编译等情况)。如下图所示:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/2 5:56:13

PADS 9.5封装库全部不显示的解决方法

问题描述不论是logic还是layout中的封装、元件、逻辑、线,都查看不到封装面如下图所示问题原因及解决方法:在应用上方的搜索框内少了通配符 * ,所以导致元器件都不显示,加上之后按回车就出来了(这软件也太曹丹了&#…

作者头像 李华
网站建设 2026/7/2 5:49:26

游戏编程十年总结(上)

自敲第一行代码起,已经十年多了,今天既不是十年整的日子,也不是一个有特定意义的日子,本来像这种大总结的文章,当择良辰吉日,斋戒沐浴三日,方可动笔。一开始计划是写一篇五年总结的,…

作者头像 李华
网站建设 2026/7/2 5:47:06

计算机毕业设计之基于大数据模型的大数据新闻摘要可视化系统的研究

基于大数据模型的大数据新闻摘要可视化系统的研究是一项重要而紧迫的任务。随着互联网的普及和信息技术的飞速发展,大量的新闻数据涌现出来,给人们获取和理解新闻带来了巨大的挑战。为了解决这一问题,大数据模型和可视化技术被广泛应用于新闻…

作者头像 李华
网站建设 2026/7/2 5:45:29

【ESP32】使用 MQTT 连接华为云 IoT (MQTT.fx 篇)

. 引言 最近正在学习 ESP32 联网操作,由于阿里云的物联网在 2025-2-1 就已经停止了 IoT 服务,然后腾讯云个人 IoT 服务购买有点小贵,所以就找到了个人免费的华为云 IoT 服务,网上的资料也相对较少,故写篇随笔记录。 …

作者头像 李华
网站建设 2026/7/2 5:45:26

重新理解微服务之终究绕不过这4个坎?(观点探讨)

写在前头 大家曾经有没有遇过日常技术交流的时候,会讨论某某技术之间的关系是什么,某些技术是否应该用到微服务。我相信热爱技术交流的您,就算不是在微服务这里领域,或多或少都会跟其他同行会做一些争议话题的探讨,而且…

作者头像 李华
网站建设 2026/7/2 5:44:32

一天一个Python库:isodate - 处理 ISO 8601 日期时间格式

一、什么是isodate ? **isodate ** 是一个用于解析和格式化 ISO 8601 日期、时间、日期时间、时间和持续时间字符串的 Python 库。 它可以帮助你: 轻松将 ISO 8601 字符串转换为 Python datetime, date, time, timedelta 对象。将 Python datetime 等对…

作者头像 李华