Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microsoft Owin Logging - Web Api 2 - How do I create the logger?

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.

like image 493
Daniel Avatar asked Sep 06 '15 23:09

Daniel


1 Answers

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.

like image 196
Sam Nicholl Avatar answered Oct 20 '22 01:10

Sam Nicholl