news 2026/8/22 14:57:07

ApplicationInsights-dotnet 内置 ActivityProcessor 全解:Session、User、ClientIp 等处理器原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ApplicationInsights-dotnet 内置 ActivityProcessor 全解:Session、User、ClientIp 等处理器原理

ApplicationInsights-dotnet 内置 ActivityProcessor 全解:Session、User、ClientIp 等处理器原理

【免费下载链接】ApplicationInsights-dotnetApplicationInsights-dotnet项目地址: https://gitcode.com/gh_mirrors/ap/ApplicationInsights-dotnet

ApplicationInsights-dotnet 是微软的 .NET 应用性能监控(APM)SDK。本文完整解析其内置的 7 个 ActivityProcessor(Activity 处理器):SessionActivityProcessor、UserActivityProcessor、ClientIpHeaderActivityProcessor 等,讲清每个处理器读取什么数据、写入哪个遥测标签,以及执行顺序与自定义扩展方法。

什么是 ActivityProcessor?为什么需要它 🧩

在 ASP.NET 经典 Web 应用中,每次 HTTP 请求都会产生一个 OpenTelemetryActivity对象(即一次"链路")。但裸的 Activity 只知道"发生了什么请求",并不天然携带用户是谁、属于哪个会话、IP 地址是什么这类业务上下文。

ActivityProcessor 就是挂在 Activity 生命周期上的"加工器":当一次请求的 Activity 结束时(OnEnd),处理器从HttpContext中读取 Cookie、请求头等数据,把它们以标签(Tag)的形式写入遥测数据,最终随请求遥测一起上报到监控平台。

🔎 全部 7 个内置处理器统一注册在 Extensions/ApplicationInsightsExtensions.cs(完整路径:WEB/Src/Web/Web/Extensions/ApplicationInsightsExtensions.cs)中:

AddProcessor(new WebTestActivityProcessor()) AddProcessor(new SyntheticUserAgentActivityProcessor()) AddProcessor(new SessionActivityProcessor()) AddProcessor(new UserActivityProcessor()) AddProcessor(new AuthenticatedUserIdActivityProcessor()) AddProcessor(new AccountIdActivityProcessor()) AddProcessor(new ClientIpHeaderActivityProcessor())

也就是说:无需任何手动配置,安装 SDK 后这些处理器就自动生效。整个初始化由WEB/Src/Web/Web/WebApplicationInsightsInitializer.cs通过 ASP.NET 的 PreApplicationStartMethod 机制在Application_Start之前自动完成,WEB/Src/Web/Web/ApplicationInsightsHttpModule.cs则是每个请求的入口模块。

内置 ActivityProcessor 一览表

处理器数据来源写入的标签作用
WebTestActivityProcessor请求头 SyntheticTest-RunId / SyntheticTest-Locationai.operation.syntheticSourceai.user.idsession.id识别 Azure 可用性探测流量
SyntheticUserAgentActivityProcessorUser-Agent 请求头ai.operation.syntheticSource识别爬虫/机器人流量
SessionActivityProcessorai_sessionCookiesession.idsession.isFirst会话追踪
UserActivityProcessorai_userCookieai.user.id匿名用户识别
AuthenticatedUserIdActivityProcessorai_authUserCookieenduser.id登录用户 ID
AccountIdActivityProcessorai_authUserCookieenduser.account用户账号标识
ClientIpHeaderActivityProcessorX-Forwarded-For等请求头client.address客户端 IP 地址

Cookie 与常量的定义见WEB/Src/Web/Web/Implementation/RequestTrackingConstants.cs及各处理器源文件(均位于WEB/Src/Web/Web/目录下)。

执行顺序与"不覆盖"原则 ⚠️

理解内置处理器的两个关键设计:

  1. 顺序有意义WebTestActivityProcessor排在SyntheticUserAgentActivityProcessor之前:如果请求带可用性探测的请求头,就优先判定为 GSM 探测流量,后面的机器人检测检测到标签已存在会直接跳过,避免误判。
  2. 不覆盖已有值。每个处理器都遵循"先检查标签是否已设置,已设置则跳过"的模式。这意味着你完全可以在业务代码中手动SetTag覆盖 SDK 的默认行为,SDK 不会强行改写。

逐个解析 7 个处理器原理

1. WebTestActivityProcessor:识别可用性探测流量

源码:WEB/Src/Web/Web/WebTestActivityProcessor.cs

如果请求同时携带SyntheticTest-RunIdSyntheticTest-Location两个请求头,说明流量来自 Azure 可用性监控,处理器会写入:

  • ai.operation.syntheticSource= "Application Insights Availability Monitoring"
  • session.id= RunId(同一次探测的所有请求归入同一会话)
  • ai.user.id=Location_RunId(拼接 Pop 位置名与 RunId,注释中说明了原因:单独用 Location 无法应对采样)

2. SyntheticUserAgentActivityProcessor:机器人流量识别

源码:WEB/Src/Web/Web/SyntheticUserAgentActivityProcessor.cs

检查请求的 User-Agent,命中过滤词就标记为合成流量(ai.operation.syntheticSource= "Bot")。默认过滤词为:

search|spider|crawl|Bot|Monitor|BrowserMob|PhantomJS|HeadlessChrome|Selenium|URLNormalization
  • 过滤词可通过Filters属性自定义(竖线分隔的多个模式,不区分大小写)
  • 匹配结果会缓存到HttpContext.Items,同一请求内只匹配一次,避免重复计算
  • 这个标签的价值在于:报表中可以把机器人流量与真实用户流量分开统计

3. SessionActivityProcessor:会话追踪原理

源码:WEB/Src/Web/Web/SessionActivityProcessor.cs

读取ai_sessionCookie(通常由前端脚本注入),Cookie 值以竖线分隔:

sessionId|acquisitionDate|renewalDate
  • 取第 1 段作为session.id
  • 若获取日期与续期日期相同,说明是用户第一次访问,额外写入session.isFirst = true—— 这是"新用户/回访用户"分析的基础数据

4. UserActivityProcessor:匿名用户识别原理

源码:WEB/Src/Web/Web/UserActivityProcessor.cs

读取ai_userCookie,格式为:

userId|ISO8601时间戳

处理器会校验时间戳可解析为DateTimeOffset,通过后才把 userId 写入ai.user.id。这个匿名 ID 让平台能把同一个访客的多次请求串起来,即使访客从未登录。

5. AuthenticatedUserIdActivityProcessor:登录用户 ID

源码:WEB/Src/Web/Web/AuthenticatedUserIdActivityProcessor.cs

针对登录用户,读取ai_authUserCookie(先做 URL 解码),按竖线拆分后取第 1 段写入enduser.id。典型用法是在用户登录时由代码写入该 Cookie,实现"谁在用你的系统"的分析。

6. AccountIdActivityProcessor:用户账号标识

源码:WEB/Src/Web/Web/AccountIdActivityProcessor.cs

与上一个处理器读取同一个ai_authUserCookie,但取第 2 段写入enduser.accountenduser.idenduser.account配合使用,可以同时支撑"身份"和"账号体系"两个维度的分析。

7. ClientIpHeaderActivityProcessor:客户端 IP 获取原理

源码:WEB/Src/Web/Web/ClientIpHeaderActivityProcessor.cs

这是唯一支持较多运行时配置的处理器,属性包括:

属性默认值说明
HeaderNamesX-Forwarded-For依次尝试的 IP 请求头列表
HeaderValueSeparators,多 IP 的分割符
UseFirstIptrue取列表第一个还是最后一个 IP

工作流程:

  1. 按顺序检查各请求头,取到第一个有效值后按分割符拆分
  2. 根据UseFirstIp决定取第一个(通常是客户端真实 IP)或最后一个(通常是上游代理)
  3. tcp://URI 方式校验 IP 合法性(支持带端口、IPv6 方括号形式)
  4. 所有请求头都取不到时,回退到request.GetUserHostAddress()(直连 IP)
  5. 最终写入client.address

📌 部署在反向代理/负载均衡后面时,如果 IP 全是内网地址,需要在这个处理器上添加实际的转发头名称并调整UseFirstIp

如何自定义自己的 ActivityProcessor ✍️

内置处理器均继承自BaseProcessor<Activity>并只重写OnEnd方法,自定义处理器可以照葫芦画瓢:读取HttpContext中的业务数据(如租户 ID、部门 ID),调用activity.SetTag("your.tag", value)写入标签,然后通过TelemetryConfigurationConfigureOpenTelemetryBuilderAddProcessor注册即可。

注册时注意:你添加的处理器会在内置处理器之后执行,因此可以读取到内置处理器已写入的标签,也可以对业务上更精确的值做覆盖。

配置项参考:

  • 经典 Web 配置读取逻辑:WEB/Src/Web/Web/Implementation/ApplicationInsightsConfigurationReader.cs
  • 配置选项定义:WEB/Src/Web/Web/Implementation/ApplicationInsightsConfigOptions.cs
  • 示例配置:WEB/Src/Web/Web/applicationinsights.config.sample
  • 各处理器单元测试(可直接参考预期行为):WEB/Src/Web/Web.Tests/SessionActivityProcessorTests.csClientIpHeaderActivityProcessorTests.csWebTestActivityProcessorTests.cs

另外,NETCORE/src/Shared/ActivityFilterProcessor.cs中还有一个ActivityFilterProcessor,用于按配置关闭依赖追踪或请求追踪(对应配置中的 EnableDependencyTrackingTelemetryModule / EnableRequestTrackingTelemetryModule),属于"过滤型"处理器,与上面 7 个"打标签型"处理器职责不同。

常见问题 FAQ 💬

Q1:为什么遥测里看不到 session.id 或 ai.user.id?这两个值依赖ai_session/ai_userCookie,而 Cookie 通常由 Application Insights 前端脚本(JS SDK)在浏览器端生成。如果页面没有引入前端脚本,或爬虫/Postman 直接请求,Cookie 不存在时处理器会静默跳过(可通过 ETW 事件源WebEventSource查看诊断日志,定义见WEB/Src/Web/Web/Implementation/WebEventSource.cs)。

Q2:登录用户的 enduser.id 没有值?需要你在登录逻辑中手动写入ai_authUserCookie(值格式:userId|accountId),SDK 不会替你猜。

Q3:这些处理器影响性能吗?影响很小。所有处理只在请求结束的OnEnd时刻执行一次,只读取 Cookie/请求头这类内存数据,没有 IO 操作;机器人匹配的过滤词还会缓存复用。

总结 🏁

ApplicationInsights-dotnet 内置的 7 个 ActivityProcessor 构成了经典 ASP.NET 场景下完整的"请求上下文补全"链路:先判定流量性质(可用性探测 → 机器人),再补全会话、用户、账号、IP 四类上下文,全部默认开启、顺序固定、支持业务覆盖。理解这套机制,既能解释报表中各个上下文字段的来龙去脉,也为扩展自定义标签处理器打下了基础。

【免费下载链接】ApplicationInsights-dotnetApplicationInsights-dotnet项目地址: https://gitcode.com/gh_mirrors/ap/ApplicationInsights-dotnet

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

webdav 轻量级 WebDAV 服务器:从安装到生产部署的完整路径

webdav 轻量级 WebDAV 服务器&#xff1a;从安装到生产部署的完整路径 【免费下载链接】webdav A simple and standalone WebDAV server. 项目地址: https://gitcode.com/gh_mirrors/we/webdav webdav 是一个用 Go 编写的轻量级 WebDAV 服务器&#xff0c;编译后就是一个…

作者头像 李华
网站建设 2026/8/22 14:50:03

FSearch 完整指南:从安装到精通的 Linux 文件搜索工具

FSearch 完整指南&#xff1a;从安装到精通的 Linux 文件搜索工具 【免费下载链接】fsearch A fast file search utility for Unix-like systems based on GTK3 项目地址: https://gitcode.com/gh_mirrors/fs/fsearch 找上个月下载的那份报告&#xff0c;文件管理器要翻…

作者头像 李华
网站建设 2026/8/22 14:50:00

基于SpringBoot的足球训练营系统的设计与实现(源码+文档+部署+讲解)

温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台…

作者头像 李华
网站建设 2026/8/22 14:49:27

NTPClient如何适配各种WiFi开发板:ESP32、ESP8266与MKR1000完整指南

NTPClient如何适配各种WiFi开发板&#xff1a;ESP32、ESP8266与MKR1000完整指南 【免费下载链接】NTPClient Connect to a NTP server 项目地址: https://gitcode.com/gh_mirrors/ntpc/NTPClient NTPClient 是一款轻量级 Arduino 时间同步库&#xff0c;能让 ESP32、ESP…

作者头像 李华