Как я могу использовать Nlog для создания файлов с другим именем, используя значения во время выполнения? - PullRequest
0 голосов
/ 28 марта 2020

У меня есть случай, когда мне нужно создать отдельный файл для разных типов данных, поступающих в мою систему, я хочу использовать NLog, чтобы убедиться, что каждый тип события хранится в своем собственном файле типа события. например, для событий a, b, c, ai требуется, чтобы все события регистрировались в файле с именем a.txt, а все события b регистрировались в файле b.txt.

C# code

string[] events= { "a", "b", "c", "a" };
            foreach(string et in events)
            {
                NLog.LogManager.Configuration.Variables["filename"] = et ;
                LogManager.ReconfigExistingLoggers();
                logger.Warn(filename);
            }

Вот мой Nlog.config

<?xml version="1.0" encoding="utf-8" ?>

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <variable name ="filename" value="test"></variable>
  <targets>
    <target name="logfile" xsi:type="File" filename="${filename}.txt" />
    <target name="logconsole" xsi:type="Console" />
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="logconsole" />
    <logger name="*" minlevel="Debug" writeTo="logfile" />
  </rules>
</nlog>

Ответы [ 2 ]

2 голосов
/ 29 марта 2020

Вы не должны использовать глобальные переменные NLog Config для передачи локального контекста. Вместо этого вы должны использовать рекомендуемые способы обработки контекста в NLog:

https://github.com/NLog/NLog/wiki/Context

Например, вы можете создать объект Logger для каждого имеющегося у вас типа события:

var loggerA = NLog.LogManager.GetLogger("a");
loggerA.Info("Hello from a");
loggerA.Info("Goodbye from a");
var loggerB = NLog.LogManager.GetLogger("b");
loggerB.Info("Hello from b");
loggerB.Info("Goodbye from b");

И используйте ${logger} в NLog FileTarget FileName:

<target name="logfile" xsi:type="File" filename="${logger}.txt" />

Вы также можете добавить пользовательское свойство в свой Logger с помощью Logger.WithProperty и использовать этот Logger для всех своих события:

var loggerPropA = NLog.LogManager.GetCurrentClassLogger().WithProperty("EventType", "a");
loggerPropA.Info("Hello from a");
loggerPropA.Info("Goodbye from a");
var loggerPropB = NLog.LogManager.GetCurrentClassLogger().WithProperty("EventType", "b");
loggerPropB.Info("Hello from b");
loggerPropB.Info("Goodbye from b");

И используйте ${event-properties:EventType} в NLog FileTarget FileName:

<target name="logfile" xsi:type="File" filename="${event-properties:EventType:whenEmpty=App}.txt" />

В зависимости от того, сколько у вас активных типов событий (2 или 200) и их времени жизни (2 мин. или 2 дня), тогда вы можете изучить следующие параметры NLog FileTarget:

  • openFileCacheTimeout
  • openFileCacheSize

См. также https://github.com/NLog/NLog/wiki/File-target

0 голосов
/ 28 марта 2020

Вы можете определить правило, которое соответствует типу события и записывает в другой файл.

<?xml version="1.0" encoding="utf-8" ?>

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="logfile" xsi:type="File" filename="log.txt" />
    <target name="log_a" xsi:type="File" filename="a.txt" />
    <target name="log_b" xsi:type="File" filename="b.txt" />
    <target name="log_c" xsi:type="File" filename="c.txt" />
    <target name="logconsole" xsi:type="Console" />
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="logconsole" />
    <!-- now add overrides for the log sources you want written to separate files -->
    <!-- order of the rules is important, because we're setting final = True --> 
    <logger name="a" minlevel="Debug" writeTo="log_a" final="True"/>
    <logger name="b" minlevel="Debug" writeTo="log_b" final="True"/>
    <logger name="c" minlevel="Debug" writeTo="log_c" final="True"/>
    <!-- anything not matched above will go to the general log file -->
    <logger name="*" minlevel="Debug" writeTo="logfile" />
  </rules>
</nlog>

Надеюсь, это поможет. Вы также можете сделать то же самое с кодом:

var config = new NLog.Config.LoggingConfiguration();

var logfile = new NLog.Targets.FileTarget()
{
    Name = "logfile",
    FileName = "logfile.txt"
}

var logconsole = new NLog.Targets.ColoredConsoleTarget() {
    Name = "logconsole"
    // other options here..
};
config.AddTarget(logconsole);
config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, logconsole, "*");


foreach (var et in events) {
  var target = new NLog.Targets.FileTarget() {
    Name = "log_" + et,
    FileName = et + ".txt"
  };
  config.AddTarget(target);
  config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, target, et, final: true);
}
config.AddTarget(logfile);
config.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Fatal, logfile, "*");                    

NLog.LogManager.Configuration = config;

Я никогда не пробовал, но, возможно, вы можете обновить конфигурацию несколько раз, во время выполнения, когда вы найдете новые события для добавления. Попробуйте.

...