PsCraft
PsCraft

Reputation: 642

Nlog rule for particular loggername do not work

I am quite new in Nlog so my problem could be pretty simple. However I cannot make it to work. Problem: My application do something for several customers. I would like to have separate log file for each customer. All configuration must be done programatically. Currently I have:

private static Logger InitialiseLog(Target target, string customerName)
{
    var loggerName = customerName == null? "globalLog" : customerName;
    var config = LogManager.Configuration ?? new LoggingConfiguration();
    config.AddTarget("eventlog", target);
    var rule = new LoggingRule("*", LogLevel.Debug, target);
    config.LoggingRules.Add(rule);
    LogManager.Configuration = config;
    Logger _logger;
    _logger = LogManager.GetLogger(loggerName);

    return _logger;
}

It is called by:

var target =
    new FileTarget
    {
        FileName = customerName + ".log",
        Layout = "${longdate}|${level:uppercase=true}|${logger}|${message}${exception}"
    };

    return InitialiseLog(target, customerName);

It works but write the same for each customer log file. I would like to write single information to particular file, so I change the rule to:

var rule = new LoggingRule(loggerName, ...

But it didn't work, nothing is written nowhere. My purpose is to achieve something like this: LogManager.GetLogger("Customer1"); -> It writes only to Customer1.log file LogManager.GetLogger("globalLog"); -> It writes only to globalLog.log file

What I do wrong?

Upvotes: 0

Views: 310

Answers (1)

Rolf Kristensen
Rolf Kristensen

Reputation: 19867

I'm guessing that you want the same application instance to handle multiple customer log-files.

Maybe you can do this:

private static Logger InitialiseLog(Target target, string customerName)
{
    var loggerName = string.IsNullOrEmpty(customerName) ? "globalLog" : customerName;

    var config = LogManager.Configuration ?? new LoggingConfiguration();
    if (config.FindTargetByName("eventlog")==null)
    {
        config.AddTarget("eventlog", target);
        var rule = new LoggingRule("*", LogLevel.Debug, target);
        config.LoggingRules.Add(rule);
        LogManager.Configuration = config;
    }

    return LogManager.GetLogger(loggerName);
}

I have no clue how you configure (or allocate) the NLog Target, but since you are hiding that information then I guess that the NLog Target only depends on the ${logger}-name and you can use the same NLog Target for all loggers.

Alternative solution where new target is registered for each logger:

private static Logger InitialiseLog(Target target, string customerName)
{
    var loggerName = string.IsNullOrEmpty(customerName) ? "globalLog" : customerName;
    var targetAlias = "eventlog_" + loggerName;

    var config = LogManager.Configuration ?? new LoggingConfiguration();
    if (config.FindTargetByName(targetAlias)==null)
    {
        config.AddTarget(targetAlias, target);
        config.AddRule(LogLevel.Debug, LogLevel.Fatal, target, loggerName, true):
        if (LogManager.Configuration != null)
           LogManager.ReconfigExistingLoggers();
        else
           LogManager.Configuration = config;
    }

    return LogManager.GetLogger(loggerName);
}

Upvotes: 1

Related Questions