1
votes

I'm trying to do some very specific logging from inside a "common" class library which is going to be used by multiple web applications. The "consuming" web applications may or may not do some NLog logging of their own. I'd like to somehow isolate the logging configurations so that:

  • Any logging from the class library does not end up in the targets configured by the consuming web application
  • Any logging from the consuming web application does not end up in the targets configured by the class library

So far, I've managed to setup the logging configuration programmatically from the class library so that it can "coexist" with the logging configuration from a consuming web application. I did something like this:

public static void RegisterLoggingConfiguration()
{
    // If there is existing configuration then just use that and update it.  Otherwise, create brand new config.
    var config = LogManager.Configuration ?? new LoggingConfiguration();

    var specialTarget = new FileTarget { FileName = @"C:\Logs\SpecialLog.txt" };
    config.AddTarget("specialTarget", specialTarget);

    var specialRule = new LoggingRule("SpecialLoggerName", LogLevel.Info, specialTarget) { Final = true };
    config.LoggingRules.Add(specialRule);

    LogManager.Configuration = config;  
}

The key is that I'm targeting a specific logger by name, so that its output can be directed towards the specific file target. For example, somewhere in my class library:

var logger = LogManager.GetLogger("SpecialLoggerName");

Which is being name-matched by this line from the programmatic configuration above:

var specialRule = new LoggingRule("SpecialLoggerName", LogLevel.Info, specialTarget) { Final = true };

So far so good. The problem, however, is when a consuming web application has its own logging setup and uses, say, a catch-all logger, it will ALSO catch my special logger output. Like this:

<logger name="*" minlevel="Info" writeTo="someLogfile" />

I think this is because the programmatic logging configuration ends up adding the "special target" at the end of the existing list of loggers, so the whole "final=true" doesn't actually help. At initial glance, I didn't find a way to add a target at a specific index. But if anyone has a way to do that, please let me know.

Or if anyone has other ideas about how to isolate the logging from inside a common class library, please let me know.

1

1 Answers

1
votes

Ah, I feel so dumb!!! Turns out there is a simple way to insert a rule at a specific index, which I missed:

//config.LoggingRules.Add(specialRule);       // old way
config.LoggingRules.Insert(0, specialRule);   // new way

I had focused too much on LoggingRules.Add(...) not having a way to specify an index, that I completely missed there is an Insert(int index, LoggingRule item) method.

I hope this helps someone else looking for a similar thing one day.