Я не уверен, но я думаю, что вы, вероятно, застряли с дублированием.Вы хотите, чтобы 4 разных макета были использованы для одного и того же файла, и вы хотите 3 разных файла.Для одной цели требуется один макет.Итак, если вы хотите войти только в 1 файл, вам все равно придется определить 4 цели, каждая из которых указывает на один и тот же файл и у каждого свой макет.Я не думаю, что в NLog есть более удобный способ связать несколько макетов с целью, а затем выбрать один макет на основе содержимого сообщения регистрации.
В зависимости от того, чего именно вы хотите достичь с помощью своих форматов.Вы можете уменьшить дублирование, написав собственный LayoutRenderer.В вашем примере вы показываете, что в макете Debug есть «...», в Info - [i], в Warn - [!], А в Error - исключение Warn +.Вы можете написать LayoutRenderer, который добавляет специальный маркер, в зависимости от уровня сообщения.Таким образом, вы бы свернули Debug, Info и Warn все в один Layout, а Error сохранил бы свой собственный Layout.
Например:
Что-то вроде этого для пользовательского LayoutRenderer (основанного на NLogОбновление 1.0, а не 2.0):
[LayoutRenderer("LevelMarkerLayoutRenderer")]
class LevelMarkerLayoutRenderer : LayoutRenderer
{
int estimatedSize = 3;
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
string marker;
switch (logEvent.Level)
{
case Debug:
marker = "...";
break;
case Info:
marker = "[i]";
break;
case Warn:
marker = "[!]";
break;
case Error:
marker = "[!]";
break;
case Fatal:
marker = "[!]";
break;
default:
marker = "?";
}
builder.Append(marker);
}
protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
{
return estimatedSize;
}
}
Теперь вы можете настроить два макета: «нормальный» и «ошибка».
Что-то вроде:
<variable name="stamp" value="${date} ${username} ${logger}" />
<variable name="normal" value="${stamp} ${LevelMarkerLayoutRenderer} ${message}" />
<variable name="error"
value="${warnLayout}${newline}${pad:padding=10:inner=${exception:format=ToString}}" />
Вы могли бы даже создать собственный LayoutRenderer для обработки исключений.Если не исключение, ничего не выводите.Если исключение, объедините новую строку, отступы и строку исключения.
Если у вас был «условный» рендерер макета исключений, то у вас может быть только один макет, который может выглядеть следующим образом:
<variable name="normal" value="${stamp} ${LevelMarkerLayoutRenderer} ${message} ${ConditionalExceptionLayoutRenderer}" />
В большинстве случаев ConditionalExceptionLayoutRenderer будет выдавать значение NULL, поскольку исключений не будет.
Надеюсь, это поможет.