Last active
February 16, 2023 13:24
-
-
Save mocella/9d11e3bffdd63df2443e7baa8d490eb4 to your computer and use it in GitHub Desktop.
.NET6 Middleware to log HttpContext request/response details
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
...... | |
"FeatureFlags": { | |
"HttpRequestLoggingEnabled": true | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class HttpContextLoggingMiddleware | |
{ | |
private readonly RequestDelegate _next; | |
private readonly ILogger _logger; | |
private const int BodyLogSizeLimit = 4096; | |
public HttpContextLoggingMiddleware( | |
RequestDelegate next, | |
ILogger logger) | |
{ | |
_next = next; | |
_logger = logger; | |
} | |
public async Task Invoke(HttpContext context) | |
{ | |
var requestBodyStream = new MemoryStream(); | |
var responseBodyStream = new MemoryStream(); | |
var requestLog = new StringBuilder(); | |
try | |
{ | |
requestLog.AppendLine($"REQUEST Host: {context.Request.Host} - Path: {context.Request.Path} - HttpMethod: {context.Request.Method}"); | |
if (context.Request.QueryString.HasValue) | |
{ | |
requestLog.AppendLine($"REQUEST QueryString: {context.Request.QueryString}"); | |
} | |
try | |
{ | |
using var bodyReader = new StreamReader(context.Request.Body); | |
var bodyAsText = await bodyReader.ReadToEndAsync(); | |
if (!string.IsNullOrWhiteSpace(bodyAsText)) | |
{ | |
if (bodyAsText.Length > BodyLogSizeLimit) | |
{ | |
// retain only first "BodyLogSizeLimit" characters so as to not blow up our logs too much | |
bodyAsText = bodyAsText[..BodyLogSizeLimit]; | |
} | |
requestLog.AppendLine($"REQUEST Body : {bodyAsText}"); | |
} | |
var bytesToWrite = Encoding.UTF8.GetBytes(bodyAsText); | |
requestBodyStream.Write(bytesToWrite, 0, bytesToWrite.Length); | |
requestBodyStream.Seek(0, SeekOrigin.Begin); | |
context.Request.Body = requestBodyStream; | |
} | |
catch (Exception) | |
{ | |
requestLog.AppendLine($"REQUEST Body : N/A"); | |
} | |
var originalBody = context.Response.Body; | |
using var newBody = new MemoryStream(); | |
context.Response.Body = newBody; | |
await _next.Invoke(context); // send the request so we can capture the Response details we care to log | |
requestLog.AppendLine($"RESPONSE Status: {context.Response.StatusCode}"); | |
try | |
{ | |
newBody.Seek(0, SeekOrigin.Begin); | |
using var bodyReader = new StreamReader(context.Response.Body); | |
var bodyAsText = await bodyReader.ReadToEndAsync(); | |
if (!string.IsNullOrWhiteSpace(bodyAsText)) | |
{ | |
if (bodyAsText.Length > BodyLogSizeLimit) | |
{ | |
// retain only first "BodyLogSizeLimit" characters so as to not blow up our logs too much | |
bodyAsText = bodyAsText[..BodyLogSizeLimit]; | |
} | |
requestLog.AppendLine($"RESPONSE Body : {bodyAsText}"); | |
} | |
newBody.Seek(0, SeekOrigin.Begin); | |
await newBody.CopyToAsync(originalBody); | |
} | |
catch (Exception) | |
{ | |
requestLog.AppendLine($"RESPONSE Body : N/A"); | |
} | |
_logger.LogInfo(requestLog.ToString()); | |
} | |
finally | |
{ | |
await requestBodyStream.DisposeAsync(); | |
await responseBodyStream.DisposeAsync(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.... | |
var app = builder.Build(); | |
// | |
var httpLoggingEnabled = builder.Configuration.GetValue<bool>("FeatureFlags:HttpRequestLoggingEnabled"); | |
if(httpLoggingEnabled) | |
{ | |
app.UseMiddleware<HttpContextLoggingMiddleware>(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment