What is the best practice to log request body on failed requests in Application Insights?

六月ゝ 毕业季﹏ 提交于 2019-12-23 09:58:49

问题


What is the best way to log the HTTP request body when a request fails?

I'm logging unhandled exceptions by overriding the Exception logger:

 public class AiExceptionLogger : ExceptionLogger
{
    public override void Log(ExceptionLoggerContext context)
    {
        if (context != null && context.Exception != null)
        {
            ExceptionTelemetry telemetry = new ExceptionTelemetry(context.Exception);

            // the requestBody is always empty because the stream is non-rewinadable?
            string requestBody = context.Request.Content.ReadAsStringAsync().Result;
            telemetry.Properties.Add("Request Body", requestBody);

            Logger.LogException(telemetry);
        }
        base.Log(context);
    }
}

With the above code, the request content is always empty. I also tried this, but that throws an unsupported method exception due to calling GetBufferlessInputStream. So that doesn't work either.

I could log all request content using a DelegatingHandler, but I'd only like to log the request body on failed requests caused by unhandled exceptions.

Any ideas?


回答1:


With the above code, the request content is always empty.

You could get the request stream using ReadAsStreamAsync method and reset the position of this stream. After that, you can read the content from this steam using StreamReader. Code below is for your reference. I tested it and it worked fine on my side.

ExceptionTelemetry telemetry = new ExceptionTelemetry(context.Exception);

//Get request stream and reset the position of this stream
Stream requestBodyStream = context.Request.Content.ReadAsStreamAsync().Result;
requestBodyStream.Position = 0;
string requestBody = string.Empty;
using (StreamReader sr = new StreamReader(requestBodyStream))
{
    requestBody = sr.ReadToEnd();
}
telemetry.Properties.Add("Request Body", requestBody);



回答2:


You are right. You can't reset the Position property the same way you can with Streams. Instead, copy the content and read the copy.

if (context != null && context.Exception != null)
{
    HttpContent requestContent = new HttpContent();
    request.Content.CopyToAsync(requestContent);
    ExceptionTelemetry telemetry = new ExceptionTelemetry(context.Exception);

    // the requestBody is always empty because the stream is non-rewinadable?
    string requestBody = requestContent.ReadAsStringAsync().Result;
    telemetry.Properties.Add("Request Body", requestBody);

    Logger.LogException(context.Exception);
}



回答3:


Here's an alternative to Amor - MSFT's answer using CopyTo

public class AiExceptionLogger : ExceptionLogger
{
    public  override async void Log(ExceptionLoggerContext context)
    {
        if (context != null && context.Exception != null)
        {
            ExceptionTelemetry telemetry = new ExceptionTelemetry(context.Exception);

            using (var ms = new MemoryStream())
            {
                await context.Request.Content.CopyToAsync(ms);
                var requestBody = Encoding.UTF8.GetString(ms.ToArray());
                telemetry.Properties.Add("Request Body", requestBody);
            }


            Logger.LogException(telemetry);
        }
        base.Log(context);
    }
}


来源:https://stackoverflow.com/questions/43769413/what-is-the-best-practice-to-log-request-body-on-failed-requests-in-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!