Application Insights中Request Telemetry未记录自定义属性问题
在ASP.NET WebForms项目中集成Application Insights时,自定义ITelemetryInitializer为两类遥测数据添加自定义属性,其中PageViewTelemetry的属性可以正常上报,RequestTelemetry的自定义属性始终无法记录。
当前实现的遥测初始化器代码如下:
public class CustomTelemetry : ITelemetryInitializer { public void Initialize(ITelemetry telemetry) { var requestTelemetry = telemetry as RequestTelemetry; var pageViewTelemetry = telemetry as PageViewTelemetry; if (requestTelemetry != null) { SetRequestTelemetry(requestTelemetry); } if (pageViewTelemetry != null) { SetPageViewTelemetry(pageViewTelemetry); } } private void SetRequestTelemetry(RequestTelemetry requestTelemetry) { // 已尝试过多种属性写入写法均不生效 //requestTelemetry.Context.Properties["RequestTelemetryUser"] = "RequestTelemetryUser"; //requestTelemetry.Properties.Add("LoggedInUserName", "DummyUser"); requestTelemetry.Properties["RequestTelemetryUser"] = "RequestTelemetryUser"; } private void SetPageViewTelemetry(PageViewTelemetry pageViewTelemetry) { pageViewTelemetry.Properties["PageViewTelemetryUser"] = "PageViewTelemetryUser"; } }
当前注册逻辑写在Global.asax中:
TelemetryConfiguration.Active.TelemetryInitializers.Add(new CustomTelemetry());
已排查WCF场景相关的解决方案,不适用于当前普通WebForms项目,无法解决问题。
这是经典.NET Framework ASP.NET场景下Application Insights的常见兼容问题,和WCF场景的故障原因完全无关:
安装Microsoft.ApplicationInsights.Web NuGet包后,服务端请求遥测的收集工作由内置HttpModule完成,这个模块加载配置的逻辑和全局静态TelemetryConfiguration.Active实例不互通:
- PageViewTelemetry要么是客户端JS上报,要么是页面渲染阶段走全局Active配置生成,所以现有初始化逻辑能正常生效
- RequestTelemetry是HttpModule在请求管道最开始就创建的,默认读取项目根目录
ApplicationInsights.config加载的专属配置实例,写在Global.asax里往Active实例注册的初始化器根本不会被请求收集管道执行,属性自然加不上去。
少数情况下如果初始化器注册时机晚于自适应采样判定,也会丢属性,但当前场景下所有RequestTelemetry都没有自定义属性,核心原因就是初始化器注册到了错误的配置实例。
二选一即可,优先选择第一种,稳定性最高:
方案1:在ApplicationInsights.config中直接注册初始化器
这是.NET Framework ASP.NET场景下最推荐的注册方式,不会出现配置实例不匹配的问题。
打开项目根目录下自动生成的ApplicationInsights.config,找到<TelemetryInitializers>节点,把自定义初始化器加进去,注意不要删掉节点里原有的默认初始化器配置:
<TelemetryInitializers> <!-- 原有默认配置保留,不要删除修改 --> <Add Type="你的项目全命名空间.CustomTelemetry, 你的项目程序集名称"/> </TelemetryInitializers>
举个实际例子:如果你的项目叫MyWebApp,CustomTelemetry类直接写在项目根目录,没有嵌套命名空间,那Type属性的值就是MyWebApp.CustomTelemetry, MyWebApp。
方案2:调整注册代码的执行位置,绑定到实际生效的配置实例
如果不想修改config文件,就把Global.asax里的注册代码从Application_Start方法移到Init方法里执行,保证在AI的HttpModule初始化完成后,再往实际运行的配置实例注册初始化器:
首先引入对应命名空间:
using Microsoft.ApplicationInsights.Extensibility; using System.Linq;
然后重写Global的Init方法:
public override void Init() { base.Init(); // 判重,避免应用域重启时重复注册 if (!TelemetryConfiguration.Active.TelemetryInitializers.Any(t => t is CustomTelemetry)) { TelemetryConfiguration.Active.TelemetryInitializers.Add(new CustomTelemetry()); } }
注意:用这个方案必须保证项目里所有Microsoft.ApplicationInsights.*开头的NuGet包版本完全一致,版本差超过2个小版本依然会出现配置实例不匹配的问题
- 调整配置后必须清理项目bin目录重新编译,避免旧版本dll缓存导致配置不生效
- 如果站点部署在IIS上,需要重启对应应用程序池,保证新的配置被加载
- 验证时可以先临时关闭自适应采样,排除采样过滤导致的属性丢失误判
内容的提问来源于stack exchange,提问作者Massey

