Automatically inject log4net named logger using Ninject

February 25, 2015

tags: , , , ,
3 comments

When working with log4net you usually want that each class will have a named logger with the class full name (Namespace+Name).

the Log4Net examples shows this pattern:

public class MyClass
{
    // Define a static logger variable so that it references the
    // Logger instance named "MyClass".
    private static readonly ILog log = LogManager.GetLogger(typeof(MyClass));

   //Rest of the Class
}

 

this will create a logger instance with the class name and now in my log4net configuration I can write something like this:

 

<log4net>
    <!-- A1 is set to be a ConsoleAppender -->
    <appender name="A1" type="log4net.Appender.ConsoleAppender">

        <!-- A1 uses PatternLayout -->
        <layout type="log4net.Layout.PatternLayout">
            <!-- Print the date in ISO 8601 format -->
            <conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
        </layout>
    </appender>
    
    <!-- Set root logger level to DEBUG and its only appender to A1 -->
    <root>
        <level value="DEBUG" />
        <appender-ref ref="A1" />
    </root>
    
    <!-- Print only messages of level WARN or above in the Namespace.SubNamespace.MyClass -->
    <logger name="Namespace.SubNamespace.MyClass">
        <level value="WARN" />
    </logger>
</log4net>

this configuration says that log messages for MyClass will only be written if they are in level WARN or up, all other loggers will be configured to DEBUG and up. the nice thing here is that I can now change logger name to “Namespace.SubNamespace” and this will affect all the loggers that their name is under “Namespace.SubNamespace”.

in my system I would like to loosen the coupling between MyClass and the Log4Net classes and take the creation process outside. the best way to achieve that is using Dependency Injection (DI).

but I still want each class to receive its own log (with logger name as class name). this is how It can be achieved using Ninject

var kernel = new StandardKernel();
kernel.Bind<IMyLogger>().ToMethod(ctx =>
{              
    var name = ctx.Request.Target.Member.DeclaringType.FullName;
    var loggerFactory = ctx.Kernel.Get<ILoggerFactory>();
    var log4Netlogger = loggerFactory.GetLogger(name);
    return new MyLogger(log4Netlogger);
});

IMyLogger is for the case you don’t want to your classes to know about log4net and prefer to stay with your own abstractions

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

3 comments

  1. gil100March 5, 2015 ב 23:44

    ניסית את הכלי של – Stackify למיטב הבנתי יש להם תוספת ל- log4net שמאפשרת למשתמשים בקלות לאחד לוגים והודעות שגיאה

    Reply
    1. IBlogger
      IBloggerMarch 6, 2015 ב 00:01

      haven’t worked with stackify, but libraries provides their appender for log4net. its also not very difficult to create appender of your own.
      still you need to define but will be logged into that appender, and the method i mentioned in the post will allow fine-grain selection of log messages.

      Reply
  2. dor cohenNovember 20, 2016 ב 13:07

    fantastic points altogether, you simply received a brand new reader. What may you recommend in regards to your post that you simply made a few days in the past? Any sure?

    Reply