ASP.NET Core如何将Application Insights数据上报至自定义REST API
问题说明
- 运行环境:已启用Application Insights的ASP.NET Core 5.0 MVC Web应用
- 需求:将Application Insights采集的遥测数据上报至自建Node.js REST API,不使用默认Azure上报服务
- 异常现象:已在
appsettings.json中配置自定义上报端点,接口可被正常触发,但无法读取到请求体中携带的遥测数据
当前使用的appsettings.json配置如下:
{ "Logging": { "ApplicationInsights": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "ApplicationInsights": { "InstrumentationKey": "123", "TelemetryChannel": { "EndpointAddress": "http://localhost:3000/v2/track" } } }
调试请求截图:
解决方案
问题由Application Insights .NET SDK默认上报规则与Node端请求解析配置不匹配导致,核心原因有两点:
- SDK默认对上报请求体做gzip压缩,Node端未开启请求体解压时,会出现读不到内容、拿到乱码的情况
- SDK上报请求的默认
Content-Type为application/x-json-stream(换行分隔的JSON流格式,用于批量上报),多数Node.js Web框架的默认body解析规则仅处理application/json类型,会直接忽略该类型请求的请求体
按照以下步骤调整即可正常接收数据:
1. 修改Node.js端接口解析配置
以Express框架为例,需要调整body解析规则,同时开启gzip解压支持:
const express = require('express'); const app = express(); // 配置请求体解析:兼容AI上报的Content-Type,开启gzip解压 app.use(express.raw({ type: ['application/json', 'application/x-json-stream'], inflate: true, // 开启gzip压缩请求体解压,该配置默认即为true,显式声明避免被其他配置覆盖 limit: '10mb' // 调大请求体体积限制,避免批量上报时体积超限被截断 })); app.post('/v2/track', (req, res) => { // 原始buffer转字符串,按换行拆分单条遥测数据(批量上报时多条数据用换行分隔) const rawContent = req.body.toString('utf8'); const telemetryList = rawContent.split('\n').filter(Boolean).map(item => JSON.parse(item)); // 此处编写遥测数据存储、处理逻辑 console.log('接收到遥测数据:', telemetryList); // 必须返回200状态码,否则SDK会判定上报失败,自动触发重试逻辑 res.sendStatus(200); }); app.listen(3000, () => { console.log('遥测接收服务已启动,监听3000端口'); });
如果使用Koa、Fastify等其他Node.js框架,调整逻辑一致:添加对应Content-Type的body解析规则、开启gzip请求体解压、接口返回200状态码即可。
2. (可选)本地调试阶段临时调整SDK上报规则
本地调试时如果需要查看明文请求,可以在ASP.NET Core项目的Startup.cs中覆盖默认TelemetryChannel配置,开启开发者模式,关闭压缩和批量聚合逻辑,遥测产生后会立即上报:
public void ConfigureServices(IServiceCollection services) { // 原有其他服务配置 services.AddControllersWithViews(); // 覆盖默认TelemetryChannel配置 services.AddSingleton<ITelemetryChannel>(new ServerTelemetryChannel { EndpointAddress = "http://localhost:3000/v2/track", DeveloperMode = true // 开发者模式:关闭gzip压缩、取消批量缓冲立即上报,仅本地调试使用,生产环境务必关闭 }); services.AddApplicationInsightsTelemetry(); }
排查注意事项
appsettings.json中配置的InstrumentationKey填写任意非空字符串即可,自定义上报端点不会校验密钥有效性- 不要给自建接收接口添加严格的单JSON结构校验,SDK批量上报的是换行分隔的JSON流,不是单个JSON对象
- 上报接口仅需配置POST路由,SDK不会使用GET等其他请求方法上报数据
内容的提问来源于stack exchange,提问作者Natarajan Veerasekaran
相关产品推荐
相关产品推荐

