【问题标题】:NLog C# config at runtime with different log filesNLog C# 在运行时配置不同的日志文件
【发布时间】:2018-02-02 11:05:37
【问题描述】:

我的主类正在运行 10 个并发线程,我希望将每个线程的输出放在一个单独的文件中。我想将一些线程分组在同一个文件中。为此,我编写了以下类,它会即时生成LoggingConfiguration。我想生成不同的Logger 对象,每个对象都有自己特定的LoggingConfiguration

下面是我的配置生成方法:

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

我正试图达到我的语法看起来像这样的地步:

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

我所拥有的是:在每个线程中我调用LogManager.Configuration = GetLoggerConfig(@"C:\Target1");,然后来自先前启动线程的所有日志都出现在那里。

我不知道在运行前我有多少不同的目标。

【问题讨论】:

    标签: c# logging nlog


    【解决方案1】:

    NLog 只支持 ONE LoggingConfiguration,所以你必须在运行时修改现有的。

    可以在此处找到一种可能的解决方案:

    C# lock issues when writing to log

    如果使用 NLog 4.5,那么您可以使用在 FileTarget 文件名中包含 ${logger} 的技巧。然后你不需要在运行时修改配置,只需使用想要的名称创建新的记录器。

    【讨论】:

    • 您所建议的问题是,每次我想编写日志消息时都需要更改配置,因为它会更改同时运行的所有其他类实例的全局配置。我认为性能不是很好?似乎 ${logger} 会一直输出相同的名称,因为我的每个实例都有相同的类名。另一种选择可能是实例化不同的 Logger 实例,每个实例都是非静态的,并且每个实例都有自己的配置?
    • 如果同一个线程使用多个Logger,而所有的logger使用不同的名字,那么${logger}的使用就不行了。另一种解决方案是设置一个 ThreadContext 变量并将其用作文件名。 FileName="${mdlc:item=ThreadName}"。另请参阅github.com/NLog/NLog/wiki/MDLC-Layout-Renderer(再次仅适用于 NLog 4.5)
    • 关于运行时修改配置的性能,那么如果每秒注册新的线程配置可能会影响性能。但是,如果它每分钟只发生一次,那么您将不会看到性能受到影响。可以考虑缓存线程配置,并在它们被旧线程释放后将它们重用于其他线程。您同时运行多少个线程,也许只是预先分配?
    猜你喜欢
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 2014-06-12
    • 2017-04-20
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    相关资源
    最近更新 更多