如何将http请求体添加到tracing span中?

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

我想将请求正文添加到我的跟踪范围中,以便在出现问题时更轻松地进行调试。 这是我当前的跟踪配置。

        var resourceBuilder = ResourceBuilder.CreateDefault()
            .AddService(serviceName);


        services.AddOpenTelemetry().WithTracing(cfg =>
        {
            cfg.SetResourceBuilder(resourceBuilder);
           
            cfg.AddHttpClientInstrumentation(opt =>
            {
                opt.FilterHttpRequestMessage = Filters.AllowAll;
                opt.EnrichWithHttpRequestMessage = async (activity, httpRequestMessage) =>
                {
                    activity.DisplayName = $"{httpRequestMessage.Method} {httpRequestMessage.RequestUri?.Host}{httpRequestMessage.RequestUri?.AbsolutePath}";

                    // here's my attemptt:
                    if (httpRequestMessage.Content is not null) {
                        activity.SetTag("request_body", await httpRequestMessage.Content.ReadAsStringAsync());
                    }
                };
            });
            cfg.AddSource(serviceName);
            cfg.AddJaegerExporter(options =>
            {
                options.MaxPayloadSizeInBytes = 65000;
            });
            cfg.SetErrorStatusOnException();
        });

您可以在上面看到我尝试将正文添加为标签,但我不确定这是否是最佳解决方案。

EnrichWithHttpRequestMessage
是一个
Action
,因此将其设置为异步委托可能是一件坏事。

c# .net open-telemetry distributed-tracing
1个回答
0
投票
`var resourceBuilder = ResourceBuilder.CreateDefault()
    .AddService(serviceName);

services.AddOpenTelemetry().WithTracing(cfg =>
{
    cfg.SetResourceBuilder(resourceBuilder);

    cfg.AddHttpClientInstrumentation(opt =>
    {
        opt.FilterHttpRequestMessage = Filters.AllowAll;

        opt.EnrichWithHttpRequestMessage = async (activity, httpRequestMessage) =>
        {
            // Set Display Name for the activity
            activity.DisplayName = $"{httpRequestMessage.Method} {httpRequestMessage.RequestUri?.Host}{httpRequestMessage.RequestUri?.AbsolutePath}";

            try
            {
                if (httpRequestMessage.Content != null)
                {
                    var contentType = httpRequestMessage.Content.Headers.ContentType?.MediaType;
                    
                    // Only log supported content types (e.g., JSON)
                    if (contentType != null && contentType.Contains("application/json"))
                    {
                        // Limit request body size (e.g., 10 KB)
                        const int maxBodySize = 10 * 1024; 
                        var body = await httpRequestMessage.Content.ReadAsStringAsync();
                        
                        if (body.Length > maxBodySize)
                        {
                            activity.SetTag("request_body_truncated", true);
                            activity.SetTag("request_body", body.Substring(0, maxBodySize) + "...");
                        }
                        else
                        {
                            activity.SetTag("request_body", body);
                        }
                    }
                    else
                    {
                        activity.SetTag("request_body_skipped", "Unsupported content type or empty body.");
                    }
                }
            }
            catch (Exception ex)
            {
                activity.SetTag("request_body_error", ex.Message);
            }
        };
    });

    cfg.AddSource(serviceName);
    cfg.AddJaegerExporter(options =>
    {
        options.MaxPayloadSizeInBytes = 65000;
    });

    cfg.SetErrorStatusOnException();
});

`

请检查以上代码

您当前的跟踪配置处于正确的轨道上,可以将请求正文包含在跟踪范围中,但需要注意一些注意事项才能确保其按预期工作

ReadAsStringAsync 稍后可能无法重新读取,因为流已被消耗。

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