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

Create log files with specific name for different class instance

我将 NLog 与 nlog.config 一起使用,没有任何编程方式,一切都很好,class 中的一个将在多个实例共享静态 logger 之前创建:

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

但是现在,由于它的实例 rasies,我想为这个 class 单独 ONLY 日志文件以便更好地阅读,此外,我想要每个日志文件名可以通过内部代码逻辑命名,例如:

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) 实际上 return 是什么,即使我传入了一个不存在的名称,为什么它仍然是 return 一个 Logger?注意,我的 nlog.config.

中没有配置 * 记录器

NLog 中没有名为 ILog 的内容,所以不确定那是什么。

加载 NLog 配置的开销很大。它应该只在初始应用程序启动时完成,而不是在创建 Logger 对象时完成。

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

我不知道在同一个 class (MyClass) 中有两个调试日志记录操作时您期望什么。并期望一个被记录但另一个不被记录。 NLog 应该如何知道差异?如果您试图告诉初始调试语句有效但下一个被忽略,那么可能是因为分配了 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>

然后你只需要像这样创建记录器:

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

如果你想同时有多个NLog配置运行,那么你需要为每个配置有一个独立的LogFactory:

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