NLog - правильный способ буферизации - PullRequest
0 голосов
/ 09 июля 2019

Вопрос

Как мы читаем содержимое буфера регистрации в NLog?

Подробно

Я настроил нормальный FileTarget и BufferingTargetWrapper в моемприложение.Каждые несколько минут мое приложение выполняет ряд шагов и регистрирует некоторые сообщения в процессе.Я хочу продолжать буферизировать эти сообщения и сбрасывать их в конце процесса.Во время сброса я также хочу отправить все сообщения из текущей партии по электронной почте.Затем буфер сбрасывается в основной файл журнала и готов к следующему пакету.

Я настроил свой регистратор программно:

/// <summary>
/// Initializes global logging service
/// </summary>
private void InitLogger()
{
  var config = new LoggingConfiguration();

  var fileTarget = new FileTarget("MyService")
  {
    FileName = "${basedir}/myservice.log",
    Layout = "${longdate} ${level} ${message}  ${exception}"
  };
  config.AddTarget(fileTarget);

  var bufferTarget = new BufferingTargetWrapper("BufferLog", fileTarget);

  config.AddRuleForAllLevels(bufferTarget);

  LogManager.Configuration = config;
}

Вот пример метода тестирования, который показывает, что именноЯ пытаюсь достичь:

public static Logger Log => LogManager.GetLogger("BufferLog");

[TestMethod]
public void BufferedLogTest()
{
  InitLogger();

  Log.Info("Message 1");
  Log.Info("Message 2");
  Log.Info("Message 3");
  LogManager.Configuration.FindTargetByName<BufferingTargetWrapper>("BufferLog").Flush(new NLog.Common.AsyncContinuation((s) =>
  {
    //I want to send these 3 buffered messages through email and
    //flush them to the main log file, but s is null unfortunately
  }));
  Log.Info("Message 4");
  Log.Info("Message 5");
  Log.Info("Message 6");
  LogManager.Configuration.FindTargetByName<BufferingTargetWrapper>("BufferLog").Flush((s) =>
  {
    //I want to send next 3 buffered messages through email and
    //flush them to the main log file, but s is null again
  });
}

Я ожидал, что BufferingTargetWrapper передаст содержимое своего буфера целевой функции, но это не так.Также нет никакого другого прямого / косвенного способа доступа к буферу.

1 Ответ

1 голос
/ 11 июля 2019

После комментария @ RolfKristensen (спасибо, парень) все оказалось проще, чем я думал. Сейчас я создаю два Target в моей конфигурации NLog. Один продолжает буферизировать сообщения журнала, пока я не сбрасываю их вручную в конце каждого пакета, а другой продолжает записывать их в основной файл журнала.

Если это кому-нибудь поможет, вот мой программный способ сделать это (вы также можете сделать это через файлы конфигурации):

/// <summary>
/// Initializes global logging service
/// </summary>
private void InitLogger()
{
  // Create configuration object 
  var Config = new LoggingConfiguration();

  // Create main target that continuously writes to the log file
  var FileTarget = new FileTarget("FileTarget")
  {
    FileName = "${basedir}/myservice.log",
    Layout = "${longdate} ${level} ${message}  ${exception}"
  };
  Config.AddTarget(FileTarget);

  //Create memory target that buffers log messages
  var MemTarget = new MemoryTarget("MemTarget");

  // Define rules
  Config.AddRuleForAllLevels(MemTarget);
  Config.AddRuleForAllLevels(FileTarget);

  // Activate the configuration
  LogManager.Configuration = Config;    
}

Теперь я могу вызывать извлеченные буферизованные сообщения в конце каждого пакета следующим образом:

var MemTarget = LogManager.Configuration.FindTargetByName<MemoryTarget>("MemTarget");
//Do whatever you want with buffered messages in MemTarget.Logs
MemTarget.Logs.Clear();
...