Похоже, что функционально этого не существует (с 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} на желаемый макет префикса.
Спасибо за ваш вклад. Сообщение статистики генерируется процедурно, поэтому я не могу отформатировать сообщение в файле конфигурации. Что касается моего второго вопроса, то я ищу способ написать N сообщений в NLog таким образом, чтобы гарантировать, что эти сообщения будут записаны сразу, без добавления других сообщений из других потоков. –
Вы говорите, что количество строк в вашей статистике может варьироваться в зависимости от того, что вы генерируете? Я попытался использовать рендеринг макета замены, но у меня странная проблема. Похоже, что замена не примет другой макет, просто текст. У вас могут быть лучшие результаты. Существует также регулярное выражение для замены макета.В основном я собирался заменить каждую строку с вашего сообщения данными статистики layout = "$ {replace-newlines: replacement = $ {statData}: $ {message}}" /> –
Да, блок статистики полностью построен по коду, и, в частности, количество строк может меняться. Мой вопрос действительно общий: как выводить N строк журнала одновременно, атомарно. Я не знал рендеринга макета 'replace-newlines'. Похоже, это может быть решение, если оно будет работать. –