I am trying to add logging to my app using Web Api 2 and Owin, so I started using Microsoft Owin Logging, which requires an ILogger
and ILoggerFactory
, that has been implemented and it works great when I need to log anything inside the STARTUP method or any of the Owin Middleware components.
For example, when I am in the Startup
method I can create the logger using:
public void Configuration(IAppBuilder app)
{
// Creates configuration
var configuration = new HttpConfiguration();
// Configure WebApi Settings
WebApiConfig.Register(configuration);
app.SetLoggerFactory(new OwinLog4NetLoggerFactory("Default"));
var logger = app.CreateLogger<Startup>();
logger.WriteInformation("test log");
// Enabled WebApi in OWIN
app.UseWebApi(configuration);
}
Where "OwinLog4NetLoggerFactory" is my custom ILoggerFactory implementation.
So far, so good... but... How can I create the logger when I am in the actual web api action method?... I tried accessing the Request.GetOwinEnvironment()
and the logger factory is not in the dictionary.
For example:
public class AccountController : ApiController
{
public int Get(int id)
{
// Create logger here
return id + 1;
}
}
I know I can create a static class with a reference to the Logger Factory or even Injection to add the logger to the api controller, but that seems too complicated for something that should be already there.
Any ideas would be appreciated.
I'd recommend writing your middleware so that you can handle the logging outside of the controller:
public class LoggingMiddleware : OwinMiddleware
{
public LoggingMiddleware(OwinMiddleware next)
: base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
//handle request logging
await Next.Invoke(context);
//handle response logging
}
}
Then in Startup class:
public class Startup
{
// ReSharper disable once UnusedMember.Global
public void Configuration(IAppBuilder appBuilder)
{
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
appBuilder.Use<LoggingMiddleware>();
appBuilder.UseWebApi(config);
}
}
The request would then come in, hit the request logging code in the LoggingMiddleware, hit the controller code and then response would be logged on the LoggingMiddleware on the way back.
However, if all you are wanting to do is send an object through from middleware to the controller you can use context.Set("loggingObject", loggingObject);
in the middleware and then
var loggingObject = Request.GetOwinContext().Get<LoggerClass>("loggingObject");
in the controller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With