Shawn
Shawn

Reputation: 734

Create log files with specific name for different class instance

I'm using NLog with nlog.config with no programatical way, all good, and one of a class will be created with multiple instances, before they shared a static logger:

public class MyClass
{
    static NLog.Logger logger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("nameDefinedInConfigFile");
    ...
    ...
}

But now, with its instances rasies, I want to seperate the log file ONLY for this class for better reading, further, I want each log file name could be named by internal code logic, like:

public class MyClass
{
    private ILog logger = null;
    public MyClass(string color)
    {
        this.logger = createSpecializedLogFileWithNamePrefix(color);
        this.logger.Debug("I can see this line of logging");
    }

    public void DoingRealWork()
    {
        this.logger.Debug("Never can see this line of logging");
    }
}

after doing some research, I still could not reach this simple requirment as the log just stopped in DoingReadWork(), this is my testing code:

        private Logger createSpecializedLogFileWithNamePrefix(string privateLogFileName)
        {
            // Step 1. Get configuration object 
            var config = NLog.LogManager.LoadConfiguration("nlog.config").Configuration;

            // Step 2. Create targets                
            var fileTarget = new FileTarget("target2" + privateLogFileName)
            {
                FileName = "log\\" + privateLogFileName + "_${date:format = yyyyMMdd}.log",
                Layout = "${date:format=HH\\:mm\\:ss.fff} [${threadid}:${level:uppercase=true}]${logger} - ${message} ${exception}"
            };
            config.AddTarget(fileTarget);

            // Step 3. Define rules
            config.AddRuleForOneLevel(LogLevel.Trace, "target2" + privateLogFileName, "private" + privateLogFileName); // only errors to file
            config.AddRuleForOneLevel(LogLevel.Debug, "target2" + privateLogFileName, "private" + privateLogFileName);
            config.AddRuleForOneLevel(LogLevel.Info, "target2" + privateLogFileName, "private" + privateLogFileName);
            //config.AddRuleForAllLevels(consoleTarget); // all to console

            // Step 4. Activate the configuration
            LogManager.Configuration = config;

            // Example usage
            Logger logger = LogManager.GetLogger("private" + privateLogFileName);
            return logger;
        }

besides, just wonder what LogManager.GetLogger(string loggerName) actually returned, even I pass in a non-existed name, why it still return a Logger? NOTE, I don't have a * logger configurated in my nlog.config.

Upvotes: 0

Views: 514

Answers (1)

Rolf Kristensen
Rolf Kristensen

Reputation: 19867

There is nothing in NLog called ILog so not sure what that is.

There is a huge overhead in loading an NLog Configuration. It should only be done at initial application startup, and NOT whenever creating a Logger-object.

When assigning LogManager.Configuration, then all previous modifications to NLog configurations are lost (All previous privately created FileTarget's becomes inactive).

I have no clue what you expect when having two Debug-logging-operations in the same class (MyClass). And expect one to be logged but the other not. How should NLog know the difference? If you are trying to tell that initial Debug-statement works but the next is ignored then it is probably because assigning LogManager.Configuration.

Instead of adding FileTarget at runtime, then you could do this:

<targets>
    <target name="privateFile" xsi:type="File" fileName="log\\${replace:searchFor=Private_:replaceWith=:inner=${logger}}_${date:format=yyyyMMdd}.log" />
    <target name="logconsole" xsi:type="Console" />
</targets>

<rules>
    <logger name="Private_*" minlevel="Trace" writeTo="privateFile" final="true" />
    <logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>

Then you just need to create the Logger like this:

var logger = LogManager.GetLogger("Private_" + privateLogFileName);

If you want to have multiple NLog configurations running at the same time, then you need to have an isolated LogFactory for each config:

https://github.com/NLog/NLog/wiki/Configure-component-logging

Upvotes: 1

Related Questions