You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 REST API中EF Core拦截器慢查询日志无法写入Azure Application Insights

问题诊断与解决方案

核心问题1:计时逻辑错误,未捕获真实查询耗时

你的拦截器在ReaderExecuting/ReaderExecutingAsync中启动并停止秒表——这两个钩子是查询执行前触发的,此时SQL还没发送到数据库执行。你测的只是拦截器方法本身的耗时,不是SQL查询的真实耗时。哪怕你看到LogSlowQuery执行,也大概率是误判(比如拦截逻辑本身耗时超过阈值),或者后续日志因上下文问题无法上报。

修复:改用ReaderExecuted/ReaderExecutedAsync钩子

这两个方法在查询执行完成后触发,EF Core还直接提供了Duration属性,无需自己维护秒表:

public override InterceptionResult<DbDataReader> ReaderExecuted(
    DbCommand command,
    CommandExecutedEventData eventData,
    InterceptionResult<DbDataReader> result)
{
    long elapsedMs = (long)eventData.Duration.TotalMilliseconds;
    if (elapsedMs > _slowQueryThreshold)
    {
        LogSlowQuery(command, elapsedMs);
    }
    return base.ReaderExecuted(command, eventData, result);
}

public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutedAsync(
    DbCommand command,
    CommandExecutedEventData eventData,
    InterceptionResult<DbDataReader> result,
    CancellationToken cancellationToken = default)
{
    long elapsedMs = (long)eventData.Duration.TotalMilliseconds;
    if (elapsedMs > _slowQueryThreshold)
    {
        LogSlowQuery(command, elapsedMs);
    }
    return base.ReaderExecutedAsync(command, eventData, result, cancellationToken);
}

核心问题2:异步拦截方法实现错误

原ReaderExecutingAsync中,你没有等待base.ReaderExecutingAsync的异步结果就停止秒表,直接返回新的ValueTask,这会破坏EF Core的异步执行流程,导致日志上下文丢失或查询执行异常。

日志未到Application Insights的配置排查

即使修复计时逻辑,仍需检查以下配置:

1. Serilog日志级别过滤

确保appsettings.json中Serilog允许Information级别日志,且未排除拦截器的日志类别:

"Serilog": {
  "MinimumLevel": {
    "Default": "Information",
    "Override": {
      "Microsoft": "Warning",
      "System": "Warning"
    }
  },
  "WriteTo": [
    {
      "Name": "ApplicationInsights",
      "Args": {
        "telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights",
        "connectionString": "你的Application Insights连接字符串"
      }
    }
  ]
}

2. Application Insights SDK配置验证

  • 确认Program.cs中正确注册服务:
    builder.Services.AddApplicationInsightsTelemetry();
    
  • 环境变量或配置文件中的ApplicationInsights:ConnectionString必须正确设置。

3. 日志上下文与批量发送延迟

  • 异步场景下日志Scope可能丢失,确保拦截器的ILogger是通过DI注入的具体实例(比如ILogger<QueryPerformanceInterceptor>)。
  • Application Insights默认批量发送日志,调试时可开启开发者模式立即上报:
    builder.Services.Configure<TelemetryConfiguration>(config =>
    {
        config.TelemetryChannel.DeveloperMode = true;
    });
    

验证步骤

  1. 替换拦截器的计时逻辑,改用ReaderExecuted系列方法。
  2. 触发慢查询,确认LogSlowQuery输出的耗时是真实的SQL执行时间(而非毫秒级的拦截逻辑耗时)。
  3. 登录Application Insights门户,在“跟踪”面板或用日志查询traces | where message contains "Slow Query"查看结果。

内容的提问来源于stack exchange,提问作者santosh kumar patro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 14:31:00