2
votes

I have a multi thread application and want each thread have separate NLog Config(dest, format).
I need log each thread data to different file so need config in code (separated dest/filename/message format).

I found that each time I defined LoggingConfiguration differently and assigned it LogManager.Configuration and then get GetLogger() it overwrite the last config and return single instance of Logger so only one output is created.

It seems that I can't have multi instance of Logger in NLog !!!
To test I wrote bellow test code.

        List<Logger> Loggers = new List<Logger>();
        for (int i = 0; i < 10; i++)
        {
            var config = new LoggingConfiguration();

            var fileTarget = new FileTarget();
            config.AddTarget("file", fileTarget);
            fileTarget.Layout = "${message}";
            fileTarget.CreateDirs = true;
            fileTarget.FileName = Convert.ToString(i)+".txt";
            fileTarget.FileAttributes = Win32FileAttributes.ReadOnly | Win32FileAttributes.WriteThrough;
            fileTarget.LineEnding = LineEndingMode.CRLF;
            var rule2 = new LoggingRule("*", LogLevel.Trace, fileTarget);
            config.LoggingRules.Add(rule2);

            LogManager.Configuration = config;   // overwrite last config

            Loggers.Add(LogManager.GetLogger(Convert.ToString(i)));   

        }

        for (int i = 0; i < 10; i++)
        {
            Loggers[i].Info("text "+ Convert.ToString(i));  // all written in single output
        }

All outputs is written in '9.txt'!
How have multi instance of NLog Class.
Thanks

1

1 Answers

1
votes

One simple option is to use the threadid in the filename, e.g.

fileTarget.FileName = "thread-${threadid}.txt";

You could also create multiple targets, but don't create a new configuration, e.g. This is a bit uncommon and not preferred.

    List<Logger> Loggers = new List<Logger>();
    for (int i = 0; i < 10; i++)
    {
        //no new here, but change the current
        var config = LogManager.Configuration;

        var fileTarget = new FileTarget();
        config.AddTarget("file"+i, fileTarget); //unique name here
        fileTarget.Layout = "${message}";
        fileTarget.CreateDirs = true;
        fileTarget.FileName = Convert.ToString(i)+".txt";
        fileTarget.FileAttributes = Win32FileAttributes.ReadOnly | Win32FileAttributes.WriteThrough;
        fileTarget.LineEnding = LineEndingMode.CRLF;
        var rule2 = new LoggingRule("*", LogLevel.Trace, fileTarget);
        config.LoggingRules.Add(rule2);

        LogManager.Configuration = config;   //update config

        Loggers.Add(LogManager.GetLogger(Convert.ToString(i)));   

    }

    for (int i = 0; i < 10; i++)
    {
        Loggers[i].Info("text "+ Convert.ToString(i));  // all written in single output
    }