Is it possible to view request's response body in Application Insights? I have seen many questions/articles regarding Request body but found none directing about Response body.
I am building a MVC core 2.1 Web Api.
Related article:
View POST request body in Application Insights
Here is my code, getting exception while creating reader from stream i.e. "Stream was not readable.".
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;
}
}
}
}
}
}
----------------------------------UPDATE--------------------------------
Here is my full code to log Request and Response Body. Request body is logged properly (with request.EnableRewind();), However, response section is throwing exception on stream reader Stream was not readable.
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 { }
}
}
}
}