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

为何Application Insights将Azure Function的400请求标记为成功且不记录异常?

我之前也碰到过一模一样的问题!Azure Function集成Application Insights时,默认的成功判定逻辑确实容易让人困惑——它只看函数本身是否完整走完执行流程,哪怕你返回400/500这类错误状态码,只要函数没崩溃退出,AI就会把这条请求标记为"成功"。

下面是我亲测有效的几种解决方式,你可以根据自己的场景选:

1. 手动在函数内标记请求状态(适合单函数定制)

直接在返回错误响应时,用TelemetryClient手动追踪请求并标记为失败。以C#为例:

using Microsoft.ApplicationInsights;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

public class ValidationFunction
{
    private readonly TelemetryClient _telemetryClient;

    // 依赖注入TelemetryClient
    public ValidationFunction(TelemetryClient telemetryClient)
    {
        _telemetryClient = telemetryClient;
    }

    [FunctionName("ValidateInput")]
    public IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        try
        {
            // 模拟校验失败场景
            var input = req.Query["input"];
            if (string.IsNullOrEmpty(input))
            {
                // 手动追踪失败请求,指定状态码400
                _telemetryClient.TrackRequest(
                    name: $"{req.Method} {req.Path}",
                    url: req.Path,
                    timestamp: System.DateTime.UtcNow,
                    duration: System.TimeSpan.Zero,
                    success: false,
                    responseCode: "400"
                );
                // 记得flush确保数据发送
                _telemetryClient.Flush();
                
                return new BadRequestObjectResult("Input cannot be empty");
            }

            return new OkObjectResult("Input validated successfully");
        }
        catch (Exception ex)
        {
            // 异常场景同时记录异常和失败请求
            _telemetryClient.TrackException(ex);
            _telemetryClient.TrackRequest(
                name: $"{req.Method} {req.Path}",
                url: req.Path,
                timestamp: System.DateTime.UtcNow,
                duration: System.TimeSpan.Zero,
                success: false,
                responseCode: "500"
            );
            _telemetryClient.Flush();
            
            return new StatusCodeResult(500);
        }
    }
}

2. 全局自定义遥测初始器(适合批量处理所有函数)

如果不想每个函数都写重复代码,可以用遥测初始器统一处理HTTP状态码,自动把4xx/5xx的请求标记为失败。

第一步:创建初始器类

using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.AspNetCore.Http;

public class HttpStatusFailureInitializer : ITelemetryInitializer
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public HttpStatusFailureInitializer(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void Initialize(ITelemetry telemetry)
    {
        if (telemetry is RequestTelemetry requestTelemetry)
        {
            var httpContext = _httpContextAccessor.HttpContext;
            if (httpContext?.Response.StatusCode >= 400)
            {
                // 标记请求为失败
                requestTelemetry.Success = false;
                // 额外添加状态码属性,方便后续筛选分析
                requestTelemetry.Properties["HttpStatusCode"] = httpContext.Response.StatusCode.ToString();
            }
        }
    }
}

第二步:注册初始器(In-Process模型用Startup.cs)

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(YourNamespace.Startup))]
namespace YourNamespace
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            // 注册HttpContextAccessor和自定义初始器
            builder.Services.AddHttpContextAccessor();
            builder.Services.AddSingleton<ITelemetryInitializer, HttpStatusFailureInitializer>();
        }
    }
}

如果是隔离进程模型,则在Program.cs里注册:

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        services.AddHttpContextAccessor();
        services.AddSingleton<ITelemetryInitializer, HttpStatusFailureInitializer>();
    })
    .Build();

host.Run();

3. Python版本的快速解决思路

如果你用的是Python函数,逻辑是一样的——手动调用Application Insights SDK标记失败请求:

import azure.functions as func
from azure.applicationinsights import TelemetryClient
import os
import time

def main(req: func.HttpRequest) -> func.HttpResponse:
    tc = TelemetryClient(os.environ["APPINSIGHTS_INSTRUMENTATIONKEY"])
    start_time = time.time()

    try:
        input_data = req.params.get("data")
        if not input_data:
            # 计算请求耗时
            duration = time.time() - start_time
            tc.track_request(
                name=f"{req.method} {req.path}",
                url=str(req.url),
                success=False,
                response_code="400",
                duration=duration
            )
            tc.flush()
            return func.HttpResponse("Missing required data", status_code=400)
        
        return func.HttpResponse("Success", status_code=200)
    except Exception as e:
        duration = time.time() - start_time
        tc.track_exception()
        tc.track_request(
            name=f"{req.method} {req.path}",
            url=str(req.url),
            success=False,
            response_code="500",
            duration=duration
        )
        tc.flush()
        return func.HttpResponse("Internal error", status_code=500)

最后提醒一下:不管用哪种方式,都要确保函数的应用设置里已经正确配置了Application Insights的连接字符串(APPLICATIONINSIGHTS_CONNECTION_STRING)或者旧版的 instrumentation key,否则遥测数据根本发不出去。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:14:14