Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save LSTANCZYK/da9779dddbbe9ed925de5dcd84a5d655 to your computer and use it in GitHub Desktop.
Save LSTANCZYK/da9779dddbbe9ed925de5dcd84a5d655 to your computer and use it in GitHub Desktop.
Owin Middleware Logging
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Owin;
using NLog; // in this example, we use NLog
namespace net.github.gist.coenm
{
public class LoggingMiddleware : OwinMiddleware
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public LoggingMiddleware(OwinMiddleware next) : base(next)
{ }
public override async Task Invoke(IOwinContext context)
{
LogRequestResponseHelper.LogDebugRequest(Logger, context.Request);
var responseBody = "";
if(Logger.IsTraceEnabled) //use trace for logging the response
{
using (var captureResponseBody = new CaptureResponseBody(context))
{
await Next.Invoke(context);
responseBody = await captureResponseBody.GetBody();
}
}
else
await Next.Invoke(context);
LogRequestResponseHelper.LogDebugResponse(Logger, context.Response);
if (Logger.IsTraceEnabled
&& !string.IsNullOrEmpty(context.Response.ContentType) && context.Response.ContentType.ToLower().StartsWith("application/json"))
LogRequestResponseHelper.LogTraceResponse(Logger, responseBody);
}
private class CaptureResponseBody : IDisposable
{
// Response body is a write-only network stream by default for Katana hosts.
// You will need to replace context.Response.Body with a MemoryStream,
// read the stream, log the content and then copy the memory stream content
// back into the original network stream
private readonly Stream stream;
private readonly MemoryStream buffer;
public CaptureResponseBody(IOwinContext context)
{
stream = context.Response.Body;
buffer = new MemoryStream();
context.Response.Body = buffer;
}
public async Task<string> GetBody()
{
buffer.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(buffer);
return await reader.ReadToEndAsync();
}
public async void Dispose()
{
await GetBody();
// You need to do this so that the response we buffered
// is flushed out to the client application.
buffer.Seek(0, SeekOrigin.Begin);
await buffer.CopyToAsync(stream);
}
}
}
}
using System;
using Microsoft.Owin;
using NLog; // Using NLog in this example
namespace com.github.gist.coenm
{
public static class LogRequestResponseHelper
{
public static void LogDebugResponse(Logger logger, IOwinResponse response)
{
if (!logger.IsDebugEnabled)
return;
MappedDiagnosticsContext.Clear();
MappedDiagnosticsContext.Set("response.StatusCode", response.StatusCode.ToString());
logger.Debug(String.Format("Response statuscode:'{0}'.", response.StatusCode));
MappedDiagnosticsContext.Clear();
}
public static void LogTraceResponse(Logger logger, string body)
{
if (!logger.IsTraceEnabled)
return;
logger.Trace("Response body: {0}", body);
}
public static void LogDebugRequest(Logger logger, IOwinRequest request)
{
if (!logger.IsDebugEnabled)
return;
MappedDiagnosticsContext.Clear();
MappedDiagnosticsContext.Set("request.MediaType", request.MediaType);
MappedDiagnosticsContext.Set("request.Host", request.Host.ToString());
MappedDiagnosticsContext.Set("request.ContentType", request.ContentType);
MappedDiagnosticsContext.Set("request.Scheme", request.Scheme);
MappedDiagnosticsContext.Set("request.Method", request.Method);
MappedDiagnosticsContext.Set("request.Path", request.Path.ToString());
MappedDiagnosticsContext.Set("request.QueryString", request.QueryString.ToString());
MappedDiagnosticsContext.Set("request.Accept", request.Accept);
var logMsg = string.Format("Request scheme:'{0}'; method:'{1}'; path:'{2}'; query:'{3}'; accept:'{4}'",
request.Scheme,
request.Method,
request.Path,
request.QueryString,
request.Accept);
logger.Debug(logMsg);
MappedDiagnosticsContext.Clear();
}
}
}
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http;
using Owin;
namespace com.github.gist.coen
{
public class Startup
{
private readonly Container container = new Container();
public void Configuration(IAppBuilder appBuilder)
{
// ....
appBuilder.Use<LoggingMiddleware>();
// ....
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment