2015-12-17 2 views
3

Возможно ли, если NLog выдаст многострочное сообщение, чтобы каждая строка была отформатирована в соответствии с текущим макетом? Например.Печать многострочного сообщения с NLog

2015-12-17 11:37:38.0845 | 64 | INFO | ----------------------------------- 
2015-12-17 11:37:38.0845 | 64 | INFO | Statistics: 
2015-12-17 11:37:38.0845 | 64 | INFO | Crawling Requests 46887 /min 
2015-12-17 11:37:38.0845 | 64 | INFO | Stored Documents 9910 /min 
2015-12-17 11:37:38.0845 | 64 | INFO | ----------------------------------- 

В качестве альтернативы, можно с NLog излучать несколько сообщений в виде одного, не-прерванного блока в многопоточной среде?

ответ

1

Вы можете сделать все это из своей конфигурации.

<variable name="statData" value="${longdate} | 64 | ${level} | "/> 
<variable name="line" value="-----------------------------------"/> 
<targets> 
    <target xsi:type="Console" 
     name="Console" 
     layout=" 
     ${statData}${line}${newline} 
     ${statData}Statistics:${newline} 
     ${statData} Crawling Requests 46887 /min ${newline} 
     ${statData} Stored Documents 9910 /min ${newline} 
     ${statData}${line}${newline}"/> 

Не был уверен, что ваш 64 был или где вы получали данные за минуту. Вероятно, переменная или что-то вставляемое. Это также должно работать, если вы входите в файл, а не в консоль.

Что касается вашего второго вопроса, если вы хотите получить одно сообщение журнала из нескольких потоков, я думаю, вам нужно будет сделать это на стороне кода. Вам нужно будет собирать свои потоки, получать данные своего журнала и отправлять его 1 раз в nLog. Возможно, я ошибаюсь

+0

Спасибо за ваш вклад. Сообщение статистики генерируется процедурно, поэтому я не могу отформатировать сообщение в файле конфигурации. Что касается моего второго вопроса, то я ищу способ написать N сообщений в NLog таким образом, чтобы гарантировать, что эти сообщения будут записаны сразу, без добавления других сообщений из других потоков. –

+1

Вы говорите, что количество строк в вашей статистике может варьироваться в зависимости от того, что вы генерируете? Я попытался использовать рендеринг макета замены, но у меня странная проблема. Похоже, что замена не примет другой макет, просто текст. У вас могут быть лучшие результаты. Существует также регулярное выражение для замены макета.В основном я собирался заменить каждую строку с вашего сообщения данными статистики layout = "$ {replace-newlines: replacement = $ {statData}: $ {message}}" /> –

+0

Да, блок статистики полностью построен по коду, и, в частности, количество строк может меняться. Мой вопрос действительно общий: как выводить N строк журнала одновременно, атомарно. Я не знал рендеринга макета 'replace-newlines'. Похоже, это может быть решение, если оно будет работать. –

1

Похоже, что функционально этого не существует (с NLog 4.2.3). Потенциальным решением является создание собственного средства рендеринга макета оболочки для улучшения функциональности рендеринга replace-newlines.

Так заменить-новой строки и заменить обертки не будут принимать макет рендеры в их замены строк. Рассматривая источник NLog для других оболочек, рендерингов и целей, свойство типа Layout можно использовать для принятия строки с (или без) средствами рендеринга макетов. Встроенные заменяющие обертки терпят неудачу при предоставлении средства визуализации макета, потому что их тип свойства Replacement - string. Парсер xml ищет только обычный текст, но} предоставленного рендеринга макета преждевременно завершает обертку replace-newline.

Следующая пользовательская обертка изменяет тип замены от string до Layout. Затем макет замены должен быть обработан, вызвав его метод Render с некоторым контекстом (LogEventInfo). Это можно сделать в переопределенном методе Append, где доступно LogEventInfo. Выделенный вывод можно сохранить для последующего использования в методе Transform.

using System; 
using System.Text; 
using NLog.Config; 
using NLog.LayoutRenderers; 
using NLog.LayoutRenderers.Wrappers; 
using NLog.Layouts; 

namespace My.Namespace 
{ 
    [LayoutRenderer("replace-newlines-withlayout")] 
    [ThreadAgnostic] 
    public class ReplaceNewLinesFormatLayoutRendererWrapper : WrapperLayoutRendererBase 
    { 
     private string m_replacementString = " "; 

     public ReplaceNewLinesFormatLayoutRendererWrapper() 
     { 
      // Changed from 
      // Replacement = " "; 
      Replacement = Layout.FromString(" "); 
     } 

     // Changed from 
     // public string Replacement { get; set; } 
     public Layout Replacement { get; set; } 

     // Override Append in order to render the replacement. 
     protected override void Append(StringBuilder builder, NLog.LogEventInfo logEvent) 
     { 
      // Render... 
      m_replacementString = Replacement.Render(logEvent); 

      // The base functionality of append is fine. 
      base.Append(builder, logEvent); 
     } 

     // Called from base.Append() 
     protected override string Transform(string text) 
     { 
      // Changed from 
      // return text.Replace(Environment.NewLine, Replacement); 

      // Now just put in the rendered replacement string. 
      return text.Replace(Environment.NewLine, m_replacementString); 
     } 
    } 
} 

А потом, к примеру, использовать его в качестве

<target 
    ... 
    layout=${replace-newlines-withlayout:replacement=${newline}${time}:${message}} 
    ... 
    /> 

В этом упрощенном случае, предполагая, что $ {сообщение} имеет разрывы строк, каждая новая строка будет начинаться с отметки времени. Просто замените $ {time} на желаемый макет префикса.

 Смежные вопросы

  • Нет связанных вопросов^_^