Azure Function .net core 6 Isolated - traceparent (W3C) correlation

问题描述 投票:0回答:1

我正在尝试拥有一个 azure 函数(.net core 6 隔离),我想在其中连接到应用程序洞察力和用户 W3C traceparent 作为我的关联方法。

我已经安装了 System.Diagnostics.DiagnosticSource (7.0.1)、Microsoft.Azure.Functions.Worker.ApplicationInsights (1.0.0-preview) 并将所需的代码添加到我的 program.cs

.ConfigureFunctionsWorkerDefaults(builder =>
{
    builder.AddApplicationInsights()
        .AddApplicationInsightsLogger();
})

虽然我看到 Activity.Id 确实包含一个 traceparent 格式字符串,但如果我发送一个 traceparent 标头,活动不会获取它,因此,我在应用程序洞察中看不到它。此外,响应不会发送回 traceparent 标头......

然后我被迫创建一个中间件来尝试这个,我很想知道这是否是实现目标的正确方法,记住这只适用于 http 触发器(更喜欢适用于所有触发器的东西)

public class TraceparentMiddleware : IFunctionsWorkerMiddleware
{
    private const string TraceParentPattern = "^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$";

    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        try
        {
            if (await TrySetActivityId(context))
                await next(context);
            else
            {
                var req = await context.GetHttpRequestDataAsync();
                var res = req!.CreateResponse(HttpStatusCode.BadRequest);
                await res.WriteStringAsync("Invalid traceparent format.");
                context.GetInvocationResult().Value = res;
            }

            SetTraceparentHeader(context);
        }
        catch
        {
            SetTraceparentHeader(context);
            throw; //because I don't know where the app insights code to log the exceptions happens.
        }
    }

    private static async Task<bool> TrySetActivityId(FunctionContext context)
    {
        var request = await context.GetHttpRequestDataAsync();

        if (request?.Headers?.TryGetValues("traceparent", out var values) ?? false && !string.IsNullOrWhiteSpace(values?.FirstOrDefault()))
        {
            var regex = new Regex(TraceParentPattern, RegexOptions.IgnoreCase);
            if (regex.IsMatch(values.FirstOrDefault()))
                Activity.Current.GetType()
                    .GetField("_id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
                    .SetValue(Activity.Current, values.FirstOrDefault());
            else
                return false;
        }
        return true;
    }

    private void SetTraceparentHeader(FunctionContext context)
    {
        var response = context.GetHttpResponseData();
        if (!response?.Headers?.Contains("traceparent") ?? false)
            response.Headers.Add("traceparent", Activity.Current.Id);
    }
}

如您所见...我什至被迫使用反射来设置 Activity.Current.Id,我想避免这种情况。

c# azure w3c asp.net-core-6.0 azure-functions-isolated
1个回答
0
投票

您还可以通过 HttpRequestData.FunctionContext.TraceContext 访问 TraceParent。

看看这是否适合你。

var traceParent = request.FunctionContext.TraceContext.TraceParent

watch中traceparent的例子

© www.soinside.com 2019 - 2024. All rights reserved.