如何将Application Insights遥测数据保存到产生端的本地文件
实现方案
核心原理
Application Insights的遥测处理管道按注册顺序执行处理器,内置采样逻辑属于处理器的一环。我们可以在采样逻辑之前插入自定义处理器,拦截100%全量遥测数据写入本地文件,后续采样、发往Azure的逻辑不受影响,最终实现本地存全量、云端仅收采样子集的需求。
具体实现步骤
1. 安装必要NuGet包
已安装Application Insights的前提下,无需额外安装依赖,若需要更稳定的本地文件写入能力,可按需引入Serilog.AspNetCore、NLog.Web.AspNetCore等成熟日志库。
2. 实现自定义遥测处理器
using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.Extensibility; using System.Text.Json; public class LocalFileTelemetryProcessor : ITelemetryProcessor { private readonly ITelemetryProcessor _next; private readonly string _localLogPath; public LocalFileTelemetryProcessor(ITelemetryProcessor next) { _next = next; // 建议从配置文件读取路径,此处为示例 _localLogPath = Path.Combine(AppContext.BaseDirectory, "ai-full-telemetry.log"); } public void Process(ITelemetry telemetry) { // 全量写入本地文件,异常捕获避免影响遥测正常发送 try { // 可按需裁剪序列化字段,减少本地存储占用 var telemetryEntry = new { Time = telemetry.Timestamp, Type = telemetry.GetType().Name, CustomProperties = telemetry.Properties, RawContent = telemetry.SerializeToString() }; var logLine = JsonSerializer.Serialize(telemetryEntry) + Environment.NewLine; // 生产环境建议替换为日志库的异步写入,避免IO阻塞、文件锁问题 File.AppendAllText(_localLogPath, logLine); } catch (Exception ex) { // 可在此处添加本地错误告警逻辑,不要抛出异常 System.Diagnostics.Trace.WriteLine($"本地遥测写入失败:{ex.Message}"); } // 传递到下一级处理器,后续采样、发云逻辑正常执行 _next.Process(telemetry); } }
3. 注册处理器到AI管道
在Program.cs中注册,保证自定义处理器执行顺序在采样处理器之前:
var builder = WebApplication.CreateBuilder(args); // 注册Application Insights基础服务 builder.Services.AddApplicationInsightsTelemetry(); // 注册自定义全量遥测处理器,必须在采样配置之前注册 builder.Services.AddApplicationInsightsTelemetryProcessor<LocalFileTelemetryProcessor>(); // 配置发往Azure的采样规则,不影响本地全量存储 builder.Services.Configure<TelemetryConfiguration>(config => { // 示例:设置发往Azure的采样率为10%,可按需调整 var samplingProcessor = new SamplingTelemetryProcessor(config.DefaultTelemetrySink.TelemetryProcessorChainBuilder.Next) { SamplingPercentage = 10 }; config.DefaultTelemetrySink.TelemetryProcessorChainBuilder.Use(_ => samplingProcessor); config.DefaultTelemetrySink.TelemetryProcessorChainBuilder.Build(); }); // 其余服务注册、中间件配置逻辑保持不变 var app = builder.Build(); app.Run();
你也可以直接在appsettings.json中配置采样率,无需硬编码:
{ "ApplicationInsights": { "InstrumentationKey": "你的Application Insights密钥", "EnableAdaptiveSampling": true, "SamplingSettings": { "SamplingPercentage": 10 } } }
注意事项
- 生产环境不要直接使用
File.AppendAllText写入文件,建议用成熟日志库实现异步写入、日志滚动、自动清理等能力,避免IO阻塞、磁盘占满问题。 - 可根据业务需求裁剪遥测序列化字段,降低本地存储占用。
- 确保自定义处理器的执行顺序在采样处理器之前,否则无法拦截到全量未采样数据。
内容的提问来源于stack exchange,提问作者Ivan Koshelev
相关产品推荐
相关产品推荐

