配置Visual Studio SDK后,App Insights门户未显示ASP.NET Web API请求
我有一个目标框架为.NET 4.8的ASP.NET Web API项目,该项目额外添加了ASP.NET Core的ConfigureServices及Startup.cs文件,使用app.config进行配置。我已在Azure门户创建App Insights资源,安装了Microsoft.ApplicationInsights.AspNetCore NuGet包,并将该资源的Instrumentation Key配置到app.config中。但使用Postman向API发送请求后,App Insights门户并未显示对应的请求及探查器数据。
相关代码
Startup.cs
/* * API * * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) * * The version of the OpenAPI document: 1.0.0 * * Generated by: https://openapi-generator.tech */ using System; using System.IO; using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.SwaggerGen; using Microsoft.AspNetCore.Authorization; using Microsoft.IdentityModel.Tokens; using Microsoft.AspNetCore.Authentication.JwtBearer; using System.Text; using System.Linq; using Microsoft.ApplicationInsights.Extensibility; using System.Web.Configuration; namespace MyNamespace { /// <summary> /// Startup /// </summary> public class Startup { /// <summary> /// Constructor /// </summary> /// <param name="configuration"></param> public Startup(IConfiguration configuration) { Configuration = configuration; } /// <summary> /// The application configuration. /// </summary> public IConfiguration Configuration { get; } /// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services"></param> public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddCors(options => { options.AddDefaultPolicy( builder => { builder .WithExposedHeaders("Wtoken") .AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod(); }); }); TelemetryConfiguration.Active.InstrumentationKey = WebConfigurationManager.AppSettings["InstrumentationKey"]; services.AddApplicationInsightsTelemetry(Configuration); var secretKey = System.Configuration.ConfigurationManager.AppSettings["TokenSecret"]; //var issuer = System.Configuration.ConfigurationManager.AppSettings["Issuer"]; //var audience = System.Configuration.ConfigurationManager.AppSettings["Audience"]; services .AddAuthentication(opt => { opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; opt.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = System.Configuration.ConfigurationManager.AppSettings["Issuer"], ValidAudience = System.Configuration.ConfigurationManager.AppSettings["Audience"], ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)), }; }); services .AddMvc(opts => { opts.InputFormatters.Insert(0, new InputFormatterStream()); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .AddJsonOptions(opts => { opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); opts.SerializerSettings.Converters.Add(new StringEnumConverter { CamelCaseText = true }); }); services .AddSwaggerGen(c => { c.SwaggerDoc("1.0.0", new Info { Version = "1.0.0", Title = "API", Description = "API (ASP.NET Core 2.1)", TermsOfService = "" }); c.CustomSchemaIds(type => type.FriendlyId(true)); c.DescribeAllEnumsAsStrings(); c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{Assembly.GetEntryAssembly().GetName().Name}.xml"); c.OperationFilter<GeneratePathParamsValidationFilter>(); }); } /// <summary> /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. /// </summary> /// <param name="app"></param> /// <param name="env"></param> public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseHttpsRedirection(); app .UseCors() .UseMvc() .UseDefaultFiles() .UseStaticFiles() .UseSwagger(c => { c.RouteTemplate = "swagger/{documentName}/openapi.json"; }) .UseSwaggerUI(c => { //TODO: Either use the SwaggerGen generated Swagger contract (generated from C# classes) c.SwaggerEndpoint("/swagger/1.0.0/openapi.json", "API"); //TODO: Or alternatively use the original Swagger contract that's included in the static files // c.SwaggerEndpoint("/openapi-original.json", "API Original"); }); app.UseApplicationInsightsRequestTelemetry(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } } } }
App.Config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> </configSections> <appSettings> <add key="EFConnstringKey" value=""/> <!-- settings below here are global --> <add key="InstrumentationKey" value="27bafd84450"/> <add key="SmtpServer" value=""/> <add key="TokenSecret" value=" "/> <add key="Issuer" value=" "/> <add key="Audience" value=" "/> <add key=" " value=" "/> <add key=" " value=" "/> </appSettings> <connectionStrings> <!-- leaving as sample, not used in code. 'connectionString' value is stored in connstring manager after replacing " with ' --> </connectionStrings> <runtime> <gcServer enabled="true"/> </runtime> </configuration>
1. 替换适配的NuGet包
你的项目是基于.NET Framework 4.8的ASP.NET Web API,Microsoft.ApplicationInsights.AspNetCore是为纯ASP.NET Core项目设计的,需替换为.NET Framework专用包:
- 卸载
Microsoft.ApplicationInsights.AspNetCore - 安装
Microsoft.ApplicationInsights.Web(最新稳定版)
2. 修正配置读取逻辑
ASP.NET Core的IConfiguration默认不会自动加载app.config,需手动配置加载该文件,同时修正Telemetry初始化:
public Startup(IConfiguration configuration) { // 将app.config加载到IConfiguration中 var builder = new ConfigurationBuilder() .AddConfiguration(configuration) .AddXmlFile("app.config", optional: false, reloadOnChange: true); Configuration = builder.Build(); } public void ConfigureServices(IServiceCollection services) { // ... 保留Cors、认证等原有代码 ... // 移除原有的TelemetryConfiguration.Active设置,改用以下方式初始化 services.AddApplicationInsightsTelemetry(options => { options.InstrumentationKey = Configuration["appSettings:InstrumentationKey"]; }); // ... 保留Mvc、Swagger等原有代码 ... }
3. 调整中间件顺序
UseApplicationInsightsRequestTelemetry必须放在UseMvc之前,才能捕获完整的请求链路:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseHttpsRedirection(); app.UseApplicationInsightsRequestTelemetry(); // 移至UseMvc之前 app.UseCors(); app.UseMvc(); // 静态文件、Swagger等中间件放在UseMvc之后 app.UseDefaultFiles() .UseStaticFiles() .UseSwagger(c => { c.RouteTemplate = "swagger/{documentName}/openapi.json"; }) .UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/1.0.0/openapi.json", "API"); }); }
4. 补全Instrumentation Key
当前app.config中的27bafd84450不完整,Instrumentation Key应为32位GUID格式(如27bafd84-xxxx-xxxx-xxxx-xxxx450xxxx),需替换为Azure门户中App Insights资源的完整密钥。
5. 启用探查器
若需获取探查器数据:
- 在Azure门户的App Insights资源中,进入性能 > 探查器开启功能
- 若项目依赖ASP.NET Core中间件,安装
Microsoft.ApplicationInsights.Profiler.AspNetCore包 - 纯.NET Framework场景,可在对应App Service的诊断设置中开启传统探查器
验证步骤
- 清理并重新生成项目
- 启动API,用Postman发送测试请求
- 等待5-10分钟(Application Insights数据存在延迟),查看Azure门户的日志 > 跟踪或性能 > 请求页面确认数据是否上报
内容的提问来源于stack exchange,提问作者user575219

