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-Location | ai.operation.syntheticSource、ai.user.id、session.id | 识别 Azure 可用性探测流量 |
| SyntheticUserAgentActivityProcessor | User-Agent 请求头 | ai.operation.syntheticSource | 识别爬虫/机器人流量 |
| SessionActivityProcessor | ai_sessionCookie | session.id、session.isFirst | 会话追踪 |
| UserActivityProcessor | ai_userCookie | ai.user.id | 匿名用户识别 |
| AuthenticatedUserIdActivityProcessor | ai_authUserCookie | enduser.id | 登录用户 ID |
| AccountIdActivityProcessor | ai_authUserCookie | enduser.account | 用户账号标识 |
| ClientIpHeaderActivityProcessor | X-Forwarded-For等请求头 | client.address | 客户端 IP 地址 |
Cookie 与常量的定义见WEB/Src/Web/Web/Implementation/RequestTrackingConstants.cs及各处理器源文件(均位于WEB/Src/Web/Web/目录下)。
执行顺序与"不覆盖"原则 ⚠️
理解内置处理器的两个关键设计:
- 顺序有意义。
WebTestActivityProcessor排在SyntheticUserAgentActivityProcessor之前:如果请求带可用性探测的请求头,就优先判定为 GSM 探测流量,后面的机器人检测检测到标签已存在会直接跳过,避免误判。 - 不覆盖已有值。每个处理器都遵循"先检查标签是否已设置,已设置则跳过"的模式。这意味着你完全可以在业务代码中手动
SetTag覆盖 SDK 的默认行为,SDK 不会强行改写。
逐个解析 7 个处理器原理
1. WebTestActivityProcessor:识别可用性探测流量
源码:WEB/Src/Web/Web/WebTestActivityProcessor.cs
如果请求同时携带SyntheticTest-RunId和SyntheticTest-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.account。enduser.id与enduser.account配合使用,可以同时支撑"身份"和"账号体系"两个维度的分析。
7. ClientIpHeaderActivityProcessor:客户端 IP 获取原理
源码:WEB/Src/Web/Web/ClientIpHeaderActivityProcessor.cs
这是唯一支持较多运行时配置的处理器,属性包括:
| 属性 | 默认值 | 说明 |
|---|---|---|
| HeaderNames | X-Forwarded-For | 依次尝试的 IP 请求头列表 |
| HeaderValueSeparators | , | 多 IP 的分割符 |
| UseFirstIp | true | 取列表第一个还是最后一个 IP |
工作流程:
- 按顺序检查各请求头,取到第一个有效值后按分割符拆分
- 根据
UseFirstIp决定取第一个(通常是客户端真实 IP)或最后一个(通常是上游代理) - 用
tcp://URI 方式校验 IP 合法性(支持带端口、IPv6 方括号形式) - 所有请求头都取不到时,回退到
request.GetUserHostAddress()(直连 IP) - 最终写入
client.address
📌 部署在反向代理/负载均衡后面时,如果 IP 全是内网地址,需要在这个处理器上添加实际的转发头名称并调整UseFirstIp。
如何自定义自己的 ActivityProcessor ✍️
内置处理器均继承自BaseProcessor<Activity>并只重写OnEnd方法,自定义处理器可以照葫芦画瓢:读取HttpContext中的业务数据(如租户 ID、部门 ID),调用activity.SetTag("your.tag", value)写入标签,然后通过TelemetryConfiguration的ConfigureOpenTelemetryBuilder用AddProcessor注册即可。
注册时注意:你添加的处理器会在内置处理器之后执行,因此可以读取到内置处理器已写入的标签,也可以对业务上更精确的值做覆盖。
配置项参考:
- 经典 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.cs、ClientIpHeaderActivityProcessorTests.cs、WebTestActivityProcessorTests.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),仅供参考