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

Azure Functions日志写入Application Insights问题咨询

Azure Function 接入 Application Insights 问题排查

测试代码与基础配置

验证场景使用的函数代码如下:

public class AzureAppInsightsExplore
{
    private readonly ILogger<AzureAppInsightsExplore> logger;
    public AzureAppInsightsExplore(ILogger<AzureAppInsightsExplore> logger)
    {
        this.logger = logger;
    }
    [FunctionName("AzureAppInsightsExplore")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) 
    {
        logger.LogInformation("C# HTTP trigger function processed a request.");
        int a = 0, b = 0;
        // 触发未处理除零异常
        int c = a / b;
        return new OkObjectResult(string.Empty);
    }
}

对应host.json配置:

{
    "version": "2.0",
    "logging": {
      "applicationInsights": {
        "samplingSettings": {
          "isEnabled": true,
          "excludedTypes": "Request"
        }
      }
    }
}

问题1:未处理异常在Application Insights中重复记录两次

这是In-process托管模型Azure Function的已知默认行为,不是配置错误:

  • Functions运行时本身在函数执行管道层会捕获所有逃逸的未处理异常,自动生成1条错误日志
  • Application Insights SDK默认开启自动异常收集,会从AppDomain未处理异常事件中再抓1次同一条异常,最终就出现两条重复记录

解决方式二选一即可:

  • 代码内加try/catch块手动捕获异常,用logger.LogError主动记录,不要让异常逃逸到外层自动捕获逻辑
  • 在host.json的applicationInsights配置节点下加"enableAutoCollectExceptions": false,关闭SDK层的自动异常收集,只保留Functions运行时记录的单条异常即可。

问题2:构造函数注入的ILogger与Run方法参数的ILogger差异

二者核心功能没有区别,最终都会把日志写入同一个Application Insights实例,唯一差异是日志附带的Category属性和适用场景不同:

  • 构造函数注入的ILogger<ClassName>,日志Category固定为类的完整名,适合在构造函数、类的自定义通用方法中复用,不需要依赖函数执行上下文
  • Run方法参数传入的ILogger是Functions运行时针对单次函数执行生成的,Category固定为Function.<函数名>,会自动附带当前执行的InvocationId、触发源、函数实例ID等上下文信息,不需要手动埋点

日常写业务逻辑优先用方法参数传入的ILogger即可,省掉注入步骤,自带的上下文信息排障时更实用;只有需要在函数执行方法外写日志的时候,才需要注入类级别的ILogger。

问题3:Trace表存在大量非业务写入的冗余日志,如何过滤

Trace表中默认会混入Functions运行时、WebJobs SDK、依赖组件输出的系统日志,默认日志级别为Information,不需要修改代码,直接在host.json中配置日志级别过滤规则即可,只保留业务相关的日志输出:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "Default": "Warning", // 全局默认只记录Warning及以上级别日志,屏蔽所有系统默认的Information级日志
      "AzureAppInsightsExplore": "Information", // 业务类日志保留Information级别
      "Function.AzureAppInsightsExplore": "Information" // 函数执行类别的日志(即Run参数ILogger写入的日志)保留Information级别
    },
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  }
}

如果还有零散的冗余日志,可以查询Trace表中冗余条目的customDimensions.Category字段,把对应的类别名加到logLevel配置中,将级别设为Warning/Error即可屏蔽。这种配置方式是性能损耗最低的过滤方案,不需要额外写自定义日志处理器。

问题4:自定义日志在Live Metrics可见,但Trace表长时间查询不到

这个问题是日志通道的机制差异导致的,按以下优先级排查即可:

  • 先排查采样规则:当前开启的采样虽然排除了Request类型,但Trace日志默认参与采样。Live Metrics走独立的实时通道,完全不走采样逻辑,所以能看到全量日志;但持久化到Trace表的日志会被采样逻辑按比例丢弃。可以临时把samplingSettings.isEnabled设为false关闭采样测试,如果关闭后日志正常入库,就调整采样比例,或者把Trace也加入excludedTypes不参与采样即可。
  • 排查日志缓冲区刷新问题:普通持久化日志走SDK的批量发送通道,默认攒满500条或者等30秒才会发往后端,如果你用的是构造函数注入的类级别ILogger,在消费计划下函数执行完被回收时,缓冲区可能没来得及刷新就被释放,导致日志丢失。换成Run方法参数传入的ILogger写日志即可,这个实例在函数执行完成后运行时会主动触发缓冲区刷新,不会丢日志。
  • 排查过滤规则冲突:检查函数应用的应用设置、Azure门户的函数诊断配置中是否有覆盖host.json的日志级别规则,把Information级别的业务日志拦截了——这类拦截规则只作用于持久化通道,不会影响Live Metrics的实时传输。
  • 排查后端摄入延迟:如果你用的是工作区集成型Application Insights,日志最终会写入关联的Log Analytics工作区,极端情况下摄入延迟可能达到15分钟,如果超过20分钟还查不到再排除这个可能性,同时检查工作区是否配置了数据收集规则,主动丢弃了Information级别的Trace日志。

内容的提问来源于stack exchange,提问作者JackFrost

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:33:25