c# - 在 Application Insights 中查看请求的响应正文

标签 c# azure azure-application-insights telemetry

是否可以在 Application Insights 中查看请求的响应正文? 我看过很多有关请求正文的问题/文章,但没有找到有关响应正文的问题/文章。

我正在构建 MVC core 2.1 Web Api。

相关文章:

View POST request body in Application Insights

这是我的代码,在从流创建读取器时出现异常,即“流不可读。”

public class ResponseBodyInitializer : ITelemetryInitializer
{
    readonly IHttpContextAccessor httpContextAccessor;

    public ResponseBodyInitializer(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    public void Initialize(ITelemetry telemetry)
    {
        if (telemetry is RequestTelemetry requestTelemetry)
        {
            HttpContext httpContext = httpContextAccessor.HttpContext;
            HttpRequest request = httpContext.Request;
            HttpResponse response = httpContext.Response;

            if (request.Method == HttpMethods.Post || 
                 request.Method == HttpMethods.Put)
            {
                //Log the response body
                if (httpContext.Response.HasStarted)
                {
                    const string responseBody = "ResponseBody";

                    if (requestTelemetry.Properties.ContainsKey(responseBody))
                    {
                        return;
                    }

                    try
                    {
                        var stream = new StreamReader(response.Body);
                        var body = stream.ReadToEnd();                            
                        response.Body.Position = 0;
                        requestTelemetry.Properties.Add(responseBody, body);
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }
        }
    }
}  

--------------------------------更新--------- -----------------------

这是我记录请求和响应正文的完整代码。请求正文已正确记录(使用 request.EnableRewind();),但是,响应部分在流读取器上引发异常流无法读取。

public class RequestBodyAndResponseBodyInitializer : ITelemetryInitializer
{
    readonly IHttpContextAccessor httpContextAccessor;

    public RequestBodyAndResponseBodyInitializer(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    public void Initialize(ITelemetry telemetry)
    {
        if (telemetry is RequestTelemetry requestTelemetry)
        {
            HttpContext httpContext = httpContextAccessor.HttpContext;
            HttpRequest request = httpContext.Request;
            HttpResponse response = httpContext.Response;

            if (request.Method == HttpMethods.Post ||
                 request.Method == HttpMethods.Put)
            {
                //1- Log the request body
                if (request.Body.CanRead)
                {
                    const string requestBody = "RequestBody";
                    if (requestTelemetry.Properties.ContainsKey(requestBody))
                    {
                        return;
                    }

                    //Allows re-usage of the stream
                    request.EnableRewind();

                    var stream = new StreamReader(request.Body);
                    var body = stream.ReadToEnd();

                    //Reset the stream so data is not lost
                    request.Body.Position = 0;
                    requestTelemetry.Properties.Add(requestBody, body);
                }
                //2- Log the response body
                else if (httpContext.Response.HasStarted)
                {
                    //Allows re-usage of the stream
                    //request.EnableRewind();

                    const string responseBody = "ResponseBody";

                    if (requestTelemetry.Properties.ContainsKey(responseBody))
                    {
                        return;
                    }

                    try
                    {
                        //var stream = new StreamReader(response.Body);
                        //var body = stream.ReadToEnd();                            
                        //response.Body.Position = 0;
                        //requestTelemetry.Properties.Add(responseBody, body);

                        using (var memoryStream = new MemoryStream())
                        {
                            var stream = response.Body;
                            response.Body = memoryStream;

                            await next(context);

                            var body = new StreamReader(memoryStream).ReadToEnd();
                            //logger?.LogDebug($"Response: {responseBody}");

                            response.Body = stream;
                        }


                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                else { }
            }
        }
    }
}

最佳答案

您必须实现ITelemetryInitializer。将 IHttpContextAccessor 注入(inject)到类中,并在 Initialize 方法中读取响应流。确保传递的 ITelemetry 对象来自 RequestTelemetry 类型,并且 HttpRequest 是 Post 或 Put。然后,您可以使用 IHttpContext.HttpContext.Response.Body 属性读取响应并使用 Application Insight 记录它。

最后,在 Startup.cs 的 ConfigureService 方法中注册您的类

关于c# - 在 Application Insights 中查看请求的响应正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51671154/

相关文章:

c# - 在 Universal Apps 中捕获当前网站的屏幕截图

c# - 反射参数名称 : abuse of C# lambda expressions or syntax brilliance?

c# - 如何取消异步调用?

c# - 当我们设置掩码时,有什么方法可以删除 MASKEDTEXTBOX 字段中显示的行吗?

azure - 当我的应用服务在 Azure 上收到错误 500 时向我发送电子邮件

azure - Microsoft.ApplicationInsights.DependencyCollector 是否可以与 Azure Functions 配合使用?

azure - 使用 az-cli 查询未按预期运行

azure - 一天后删除旧的 Azure Blob

Azure - 是否可以使用企业应用程序设置环境变量?

azure AI QUERY结合开始和响应来计算平均值