简体   繁体   中英

Dynamic Logger per Type in Log4Net

I'm using (possibly abusing) log4net in an ASP.NET MVC website. I want to have one logger per class ( which the docs suggest ), but it seems that I need to pre-configure a logger for each class.

Is that right? Do I need to predefine every logger?

I'm appending to SqlServer & can see the column named Logger in the schema. It seems like it should be so easy to put whatever I want in that field, but the only dynamic logger creation I can find is here . Am I missing something?

You don't need to pre-define each logger. Rather, the conventional method is to use a standard pattern for the log4net logger that uses reflection in the consuming class to declare the logger by Type . Just dump this property into each class and you're good to go:

private static log4net.ILog _logger;
private static log4net.ILog Logger
{
    get
    {
        if( _logger == null )
        {
            Type type = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType;
            _logger = log4net.LogManager.GetLogger( type );
        }
        return _logger;
    }
}

When you say 1 logger per class, you are referring to the programmatic ILog, which is used to create the log messages. These do in fact need to be predefined, but it is as simple as the approach that Metro Smurf has given, or even simpler if you don't care about defining an ILog that might not be used:

private static ILog logger = 
   LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Either of these approaches will configure a logger. Reflection is used to get the classname of the current method, which is then used as the logger name, hence calling the approach "dynamic". This could also be coded as the following (but then the code would be different in each class, and the reflection method makes it easy to do as a snippet).

private static ILog logger = LogManager.GetLogger(typeof(MyCurrentClass));

Per your comment about "put whatever I want", you can very easily do that also when you create the ILog instance (and pardon the pun).

private static ILog logger = LogManager.GetLogger("whatever I want");

The link that you include not only creates an ILog logger, but it creates an appender to go along with it. I would not consider that to be a good practice, since appenders can be more easily configured at runtime in web.config or app.config, and it is normally not necessary to have more than one or two appenders, with all of the logger output going to the appenders.

What is the "dynamic" aspect here? You do need to instantiate a logger to use it, just as you would have to instantiate a database connection to use it. The rest is just a question of naming.

Log4net makes it easy to name loggers by software component. This can be accomplished by statically instantiating a logger in each class, with the logger name equal to the fully qualified name of the class. This is a useful and straightforward method of defining loggers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM