为不同的类实例创建具有特定名称的日志文件

时间:2018-11-05 06:42:51

标签: .net .net-core nlog

我正在将NLog与nlog.config一起使用,而没有编程方式,一切都很好,并且在共享静态logger之前,将使用多个实例创建一个类:

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

但是,现在,由于实例稀少,我想为该类分离日志文件,以便更好地阅读,此外,我希望每个日志文件名都可以由内部代码逻辑来命名,例如:

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");
    }
}

做完一些研究后,由于日志只是在DoingReadWork()中停止了,因此我仍然无法达到这个简单的要求,这是我的测试代码:

        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;
        }

此外,只是想知道实际上返回了什么LogManager.GetLogger(string loggerName),即使我传入了一个不存在的名称,为什么它仍然返回Logger?注意,我的*中没有配置nlog.config记录器。

1 个答案:

答案 0 :(得分:1)

NLog中没有称为ILog的东西,所以不确定是什么。

加载NLog配置会产生巨大的开销。仅应在应用程序初始启动时完成,而不是在创建Logger对象时进行。

分配LogManager.Configuration时,所有对NLog配置的先前修改都将丢失(所有先前私有创建的FileTarget都将变为非活动状态)。

当在同一个类(MyClass)中进行两个Debug-logging-operations时,我不知道您期望什么。并期望其中一个被记录,而另一个则不会。 NLog应该如何知道区别?如果您试图告诉您最初的Debug语句有效,但下一个Debug语句被忽略,则可能是因为分配了LogManager.Configuration

您可以执行以下操作,而不是在运行时添加FileTarget:

<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>

然后,您只需要像这样创建Logger:

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

如果要同时运行多个NLog配置,则需要为每个配置使用隔离的LogFactory:

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