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

Azure C#独立工作者模型函数:如何将499请求日志设为非错误

解决Azure独立工作者模型HTTP函数中请求取消(499)被标记为AI错误的问题

核心原因

在独立工作者模型中,当客户端取消请求时,函数宿主会先于你的代码处理逻辑向Application Insights上报HTTP 499的错误遥测。即便你在代码中捕获TaskCancelledException并返回200状态码,已上报的错误条目也不会被自动覆盖。

具体解决方案

1. 禁用自动HTTP请求遥测,手动控制上报

通过配置关闭宿主自动收集HTTP请求遥测,改为在函数代码中手动创建并提交符合预期的遥测数据:

步骤1:在Program.cs中禁用自动遥测

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(builder =>
    {
        // 关闭默认的HTTP请求遥测收集
        builder.Services.Configure<HttpTelemetryOptions>(options =>
        {
            options.DisableRequestTracking = true;
        });
    })
    .Build();

host.Run();

步骤2:在函数中手动上报请求遥测

注入TelemetryClient,在处理完取消异常后,手动构造并提交正确的请求遥测:

using Microsoft.ApplicationInsights;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using System.Net;
using System.Linq;

public class MyHttpFunction
{
    private readonly TelemetryClient _telemetryClient;

    public MyHttpFunction(TelemetryClient telemetryClient)
    {
        _telemetryClient = telemetryClient;
    }

    [Function("MyHttpTrigger")]
    public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req)
    {
        var requestId = req.Headers.TryGetValues("Request-Id", out var values) 
            ? values.FirstOrDefault() 
            : Guid.NewGuid().ToString();
        var startTime = DateTimeOffset.UtcNow;
        HttpResponseData response = null;

        try
        {
            // 执行并发任务,绑定请求取消令牌
            var task1 = GeneratePart1Async(req.RequestAborted);
            var task2 = GeneratePart2Async(req.RequestAborted);
            await Task.WhenAll(task1, task2);

            response = req.CreateResponse(HttpStatusCode.OK);
            await response.WriteAsJsonAsync(new { Part1 = task1.Result, Part2 = task2.Result });
        }
        catch (OperationCanceledException)
        {
            // 捕获取消异常,返回200状态码
            response = req.CreateResponse(HttpStatusCode.OK);
            await response.WriteAsJsonAsync(new { Status = "请求被客户端取消", PartialData = "可返回已生成的部分数据" });
        }
        finally
        {
            // 手动构造并上报请求遥测
            var requestTelemetry = new RequestTelemetry
            {
                Id = requestId,
                Name = "MyHttpTrigger",
                Timestamp = startTime,
                Duration = DateTimeOffset.UtcNow - startTime,
                ResponseCode = ((int)response.StatusCode).ToString(),
                Success = true // 强制标记为成功
            };

            // 关联请求上下文,确保遥测能正确聚合
            _telemetryClient.Context.Operation.Id = requestId;
            _telemetryClient.TrackRequest(requestTelemetry);
        }

        return response;
    }

    private async Task<string> GeneratePart1Async(CancellationToken cancellationToken)
    {
        await Task.Delay(5000, cancellationToken);
        return "Part1 数据";
    }

    private async Task<string> GeneratePart2Async(CancellationToken cancellationToken)
    {
        await Task.Delay(5000, cancellationToken);
        return "Part2 数据";
    }
}

2. 覆盖自动遥测的错误状态(保留部分自动收集功能)

如果不想完全禁用自动遥测,可以通过自定义遥测处理器,将499状态的请求标记为成功:

创建自定义遥测处理器

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

public class CanceledRequestTelemetryProcessor : ITelemetryProcessor
{
    private readonly ITelemetryProcessor _next;

    public CanceledRequestTelemetryProcessor(ITelemetryProcessor next)
    {
        _next = next;
    }

    public void Process(ITelemetry item)
    {
        if (item is RequestTelemetry requestTelemetry)
        {
            // 将HTTP 499请求标记为成功,并添加自定义属性
            if (requestTelemetry.ResponseCode == "499")
            {
                requestTelemetry.Success = true;
                requestTelemetry.Properties["CanceledByClient"] = "True";
            }
        }

        _next.Process(item);
    }
}

在Program.cs中注册处理器

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        // 注册自定义遥测处理器
        services.AddSingleton<ITelemetryProcessor, CanceledRequestTelemetryProcessor>();
    })
    .Build();

host.Run();

关键注意事项

  • 所有并发任务必须绑定req.RequestAborted令牌,确保能及时响应取消信号,避免资源浪费。
  • 手动上报遥测时,必须关联Operation.Id,否则遥测数据无法正确聚合到单个请求。
  • 自定义遥测处理器会全局生效,若需针对特定函数过滤,可在遥测属性中添加函数名称进行区分。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:27:27