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

Azure Functions App中使用OpenTelemetry通过Activity.Current.SetTag添加自定义标签未显示在App Insights customDimension的问题

Azure Functions App中使用OpenTelemetry通过Activity.Current.SetTag添加自定义标签未显示在App Insights customDimension的问题

我来帮你分析这个问题并给出解决方案,结合你的MRE一步步梳理:

为什么直接SetTag不生效?

你的配置和隔离工作者模型的遥测机制冲突,导致标签无法同步到App Insights的customDimensions:

  1. 你同时启用了Application Insights原生遥测(AddApplicationInsightsTelemetryWorkerService())和OpenTelemetry遥测(AddOpenTelemetry().UseAzureMonitor()),两者的遥测通道完全独立,标签无法跨通道同步。
  2. 你已经在host.json中设置了telemetryMode": "openTelemetry",这已经指定Azure Functions用OpenTelemetry处理遥测,原生App Insights的配置反而会干扰遥测流程。
  3. 你看到的两条请求记录是隔离模式Functions的正常现象:一条是触发器的系统初始化活动,一条是实际的请求处理活动,你设置的标签没有关联到正确的活动实例。

解决方案一:修正配置,让函数内的SetTag标签显示在customDimensions

先清理配置,让OpenTelemetry和Functions的遥测机制完全对齐:

1. 重构Program.cs的配置

移除原生App Insights的配置,只保留OpenTelemetry的正确配置(适配隔离模式Functions):

using Azure.Monitor.OpenTelemetry.AspNetCore;
using OpenTelemetry.Trace;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        services.AddOpenTelemetry()
            .WithTracing(tracerProviderBuilder =>
            {
                tracerProviderBuilder
                    // 启用隔离模式Functions的OpenTelemetry Instrumentation
                    .AddAzureFunctionsWorkerInstrumentation()
                    // 将遥测导出到Azure Monitor
                    .UseAzureMonitor();
            });
    })
    .Build();

host.Run();

2. 确认host.json的遥测配置

确保host.json的telemetryMode正确指向OpenTelemetry:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "telemetryMode": "openTelemetry"
    }
  }
}

3. 在函数中正确设置标签(支持获取请求上下文)

现在你可以直接在函数中通过Activity.Current设置标签,还能通过FunctionContext获取请求的动态数据(比如请求体):

using System.Diagnostics;
using System.IO;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace MRE_Custom_Tag;

public class SimpleEndPoint
{
    private readonly ILogger<SimpleEndPoint> _logger;

    public SimpleEndPoint(ILogger<SimpleEndPoint> logger)
    {
        _logger = logger;
    }

    [Function("SimpleEndPoint")]
    public IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req,
        FunctionContext context) // 注入FunctionContext获取请求上下文
    {
        if (Activity.Current == null)
        {
            _logger.LogError("Activity.Current is null. Cannot set custom tags.");
            return new BadRequestResult();
        }

        // 示例:获取POST请求体并设置为标签
        string requestBody = string.Empty;
        if (req.Method.Equals(HttpMethods.Post, StringComparison.OrdinalIgnoreCase))
        {
            req.Body.Position = 0; // 重置流位置,避免读取为空
            requestBody = new StreamReader(req.Body).ReadToEndAsync().GetAwaiter().GetResult();
            Activity.Current.SetTag("Request_Body", requestBody);
        }

        // 设置自定义固定标签
        Activity.Current.SetTag("MY_TEST_TAG", "TEST_TAG_VALUE");

        return new OkObjectResult("Hello from SimpleEndPoint!");
    }
}

解决方案二:在Processor中获取请求上下文

如果你需要用统一的Processor处理标签,同时要获取请求动态数据,可以通过Activity Baggage传递上下文信息:

1. 在函数中把请求数据存入Activity Baggage

[Function("SimpleEndPoint")]
public IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req,
    FunctionContext context)
{
    if (Activity.Current == null)
    {
        _logger.LogError("Activity.Current is null.");
        return new BadRequestResult();
    }

    req.Body.Position = 0;
    string requestBody = new StreamReader(req.Body).ReadToEndAsync().GetAwaiter().GetResult();
    // 将请求数据存入Activity Baggage,供Processor读取
    Activity.Current.AddBaggage("Request_Body", requestBody);

    return new OkObjectResult("Hello from SimpleEndPoint!");
}

2. 实现Processor读取Baggage并设置标签

using System.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Trace;

public class ActivityEnrichingProcessor : BaseProcessor<Activity>
{
    public override void OnEnd(Activity activity)
    {
        // 从Baggage中读取请求上下文数据
        if (activity.Baggage.TryGetValue("Request_Body", out var requestBody))
        {
            activity.SetTag("Custom_Request_Body", requestBody);
        }

        // 添加通用自定义标签
        activity.SetTag("CustomDimension1", "Value1");
    }
}

3. 在Program.cs中注册Processor

在OpenTelemetry的Tracing配置中添加自定义Processor:

services.AddOpenTelemetry()
    .WithTracing(tracerProviderBuilder =>
    {
        tracerProviderBuilder
            .AddAzureFunctionsWorkerInstrumentation()
            .AddProcessor<ActivityEnrichingProcessor>() // 注册自定义Processor
            .UseAzureMonitor();
    });

验证结果

发布函数到Azure后,在App Insights的Logs中用Kusto查询验证标签是否存在:

requests
| where customDimensions.MY_TEST_TAG == "TEST_TAG_VALUE"
| project timestamp, name, customDimensions

你会看到自定义标签已经出现在customDimensions字段中,另外注意:

  • 两条请求记录中,标签会出现在函数处理活动(name为GET /api/SimpleEndPoint或POST /api/SimpleEndPoint)的customDimensions里,另一条是触发器的系统活动,不会包含业务标签。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 12:39:36