4
\$\begingroup\$

I want to implement a Logger and use Serilog as Provider. My Project is ASP.NET MVC Framework (not core).

Initially I tried to replicate ASP.Net Core Logging framework. I created a LogConfig static class, and initialized it from Global.asax.

public static class LogConfig {
  public static LoggerFactory LoggerFactory = new LoggerFactory();
  public static void RegisterLogger() {
  LoggerFactory = new LoggerFactory();
  Logger = new LoggerConfiguration().ReadFrom.AppSettings().CreateLogger();
  LoggerFactory.AddSerilog();
  }

   public static ILogger<T> CreateLogger<T>() {
        return LoggerFactory.CreateLogger<T>();
    }
}

Initially I wanted to inject the logger into controller, using ninject, but could not figure out how to do this.

For example, something like this:

private static void RegisterServices(IKernel kernel) {
kernel.Bind<typeof(ILogger<>).ToProvider(LogConfig.LoggerFactory.CreateLogger<>());
}

But it did not work and I found it very complicated. Then, I decided to just use my logger factory and initialize it the controller like this:

ILogger<MyController> logger = LogConfig.CreateLogger<MyCotroller>();

But then, I wanted to access this logger in my ExceptionLoggingFilter, but again it started to get complicated. So in the end I got rid of Microsoft LoggerFactory and just used Serilog.

This is my final code:

Logconfig.cs, which is in App_start and is called from Global.asax:

public static class LogConfig 
{
    public static ILogger Logger { get; set; }

    public static void RegisterLogger() 
    {
        Logger = new LoggerConfiguration().ReadFrom.AppSettings().CreateLogger();
    }
 }

ExceptionLoggingFilter.cs, which is in the Filters folder:

public class ExceptionLoggingFilter : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        var controllerName = filterContext.RouteData.Values["controller"];
        var actionName = filterContext.RouteData.Values["action"];

        // send ajax response
        if (string.Equals(filterContext.HttpContext.Request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.InvariantCultureIgnoreCase))
        {
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    Message = "An error has occured, please try again later.",
                }
            };
        }

        LogConfig.Logger.Error(filterContext.Exception, $"Exception occured in Controller: {controllerName}, Action: {actionName}.", filterContext.Controller.GetType());
        filterContext.HttpContext.Response.StatusCode = 500;
        filterContext.ExceptionHandled = true;
    }
}

So, finally, there is no injection, and no logger factory, only a static global logger which can be accessed everywhere. Is this a good solution?

\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review! With regards to asking for a review and opinions about your code, this is specifically what this site is for, so I hope you get good answers! \$\endgroup\$ – Phrancis Oct 22 '17 at 12:38
  • 1
    \$\begingroup\$ I think, the "static class vs injected class" question is primarily opinion based. Each developer has their own level of tolerance towards the global state. Inversion of Control and Dependency Injection were invented for a reason. If you use the IoC containers, this will help in at least a few scenarios I met in real life. 1: Changing the logging framework across entire project -- much cheaper that with static class. 2: Scaling your logging framework is as well much simpler in this case. (You may have n loggers writing to n files in parallel). \$\endgroup\$ – Igor Soloydenko Oct 23 '17 at 6:46
  • 1
    \$\begingroup\$ I personally do not tolerate static classes at all. I curse a lot when I have to deal with a static classes which are out of my control (come from the framework). They are often pain in the neck when it comes to testing (well, I exaggerate a bit, but they add unnecessary work). \$\endgroup\$ – Igor Soloydenko Oct 23 '17 at 6:51
  • \$\begingroup\$ Thanks a lot Igor, appreciate your time and feedback... Sounds like I need to spend more time to figure out how to inject the LoggerFactory using ninject... but one question, I agree that a Logger being injected is a good thing. But is it also a good idea to inject a factory? \$\endgroup\$ – Hooman Bahreini Oct 23 '17 at 6:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.