Структурированный каротаж NLog с повторяющимися именами отверстий
Я пытаюсь понять, как правильно фиксировать свойства с повторяющимися именами отверстий в соответствии с синтаксисом шаблонов сообщений, который реализован в NLog.
Посмотрим на примере.
Запишите на консоль повторяющиеся имена отверстий, но количество параметров меньше, чем количество имен.
// Targets where to log to: File and Console var logconsole = new NLog.Targets.ConsoleTarget("logconsole"); config.AddRule(global::NLog.LogLevel.Debug, global::NLog.LogLevel.Fatal, logconsole); // Apply config NLog.LogManager.Configuration = config; NLog.LogManager.GetLogger("A").Info("hello from {a} {b} {a}", 1, 2);
На выходе
2020-05-26 09:47:37.5013| ИНФОРМАЦИЯ |A| привет от {a} {b} {a}
Никаких замен нет!
Запишите на консоль повторяющиеся имена отверстий с одинаковым количеством параметров.
// Targets where to log to: File and Console var logconsole = new NLog.Targets.ConsoleTarget("logconsole"); config.AddRule(global::NLog.LogLevel.Debug, global::NLog.LogLevel.Fatal, logconsole); // Apply config NLog.LogManager.Configuration = config; NLog.LogManager.GetLogger("A").Info("hello from {a} {b} {a}", 1, 2, 3);
На выходе
2020-05-26 09:49:53.1436| ИНФОРМАЦИЯ |A| привет от 1 2 3
Произошли замены.
Итак, в первом случае я ожидаю увидеть замены, но их нет. Это правильное поведение в NLog относительно синтаксиса шаблонов сообщений?
Я проверил поведение в первом случае для Serilog. Он делает замены.
1 ответ
Это правильное поведение в соответствии с NLog документации - Как использовать структурированные протоколирования состояния
Имена параметров должны быть уникальными.
Хотя правила захвата на https://messagetemplates.org/ не накладывают таких ограничений на параметры:
Если какое-либо из имен свойств не является числовым, тогда все аргументы захватываются путем сопоставления слева направо с отверстиями в том порядке, в котором они появляются.
NLog имеет собственную интерпретацию сопоставления слева направо - если количество свойств не соответствует количеству аргументов, то формат не считается допустимым шаблоном структурированного сообщения (проверьте метод ParseMessageTemplate). Что дает два ожидаемых результата
Logger.Info("{User} {Value}", "Bob", 42); // "Bob" 42
Logger.Info("{User} {Value} {User}", "Bob", 42); // invalid template
И один неожиданный (но NLog предупредил вас об использовании уникальных свойств):
Logger.Info("{User} {Value} {User}", "Bob", 42, "Joe"); // "Bob" 42 "Joe"
Если вы ожидаете получить "Joe" 42 "Joe"
в последнем примере вы можете использовать Serilog или использовать числовые имена свойств в шаблоне сообщения"{0} {1} {0}"
(не рекомендуется).