pab
pab

Reputation: 332

NLog C# config at runtime with different log files

My main class is running 10 concurrent threads and I'd like to have the output of each of them in a separate file. Some threads I want to be grouped in the same file. To do this, I've written the following class which generate a LoggingConfiguration on the fly. I'd like to generate different Logger objects, each with its own specific LoggingConfiguration.

Below is my configuration generating method:

private LoggingConfiguration GetLoggerConfig(string target)
    {
        if (!Directory.Exists(target)){
            Directory.CreateDirectory(target);
        }
        // Step 1. Create configuration object 
        var config = new LoggingConfiguration();

        // Step 2. Create targets and add them to the configuration 
        var consoleTarget = new ColoredConsoleTarget();
        config.AddTarget("console", consoleTarget);

        var fileTarget = new FileTarget();
        config.AddTarget("file", fileTarget);

        var asyncWrapper = new AsyncTargetWrapper();
        asyncWrapper.QueueLimit = 5000;
        asyncWrapper.OverflowAction = AsyncTargetWrapperOverflowAction.Grow;
        asyncWrapper.WrappedTarget = fileTarget;

        // Step 3. Set target properties 
        consoleTarget.Layout = @"${longdate} | ${logger} |  ${level} | ${message}";//@"${date:format=HH\:mm\:ss} ${logger} ${message}";
        fileTarget.FileName = Path.Combine(target, "logs-${shortdate}.txt");
        fileTarget.Layout = "${longdate} | ${machinename} | ${processid} | ${processname} | ${logger} | ${level} | ${message}";

        // Step 4. Define rules
        config.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, consoleTarget));
        config.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, asyncWrapper));


        return config;
    }

And I'm trying to get to a point where my syntax would look like this:

Logger logger1 = GetLoggerConfig(@"C:\Target1");
Logger logger2 = GetLoggerConfig(@"C:\Target2");

logger1.Info("hello -- should be printed in a file");
logger2.Info("World -- should be printed in a different file");

Instead what I have is: in each threads I call LogManager.Configuration = GetLoggerConfig(@"C:\Target1"); and then all the logs from previously initiated threads appear there.

I don't know how many different targets I have before run-time.

Upvotes: 0

Views: 2197

Answers (1)

Rolf Kristensen
Rolf Kristensen

Reputation: 19847

NLog only supports ONE LoggingConfiguration, so you have to modify the existing at runtime.

One possible solution can be found here:

C# lock issues when writing to log

If using NLog 4.5, then you could use the trick with having ${logger} in the FileTarget-filename. Then you don't need to modify the configuration as runtime, but just create new loggers with the wanted name.

Upvotes: 1

Related Questions