Структурированный каротаж NLog с повторяющимися именами отверстий

Я пытаюсь понять, как правильно фиксировать свойства с повторяющимися именами отверстий в соответствии с синтаксисом шаблонов сообщений, который реализован в NLog.

Посмотрим на примере.

  1. Запишите на консоль повторяющиеся имена отверстий, но количество параметров меньше, чем количество имен.

    // 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}

Никаких замен нет!

  1. Запишите на консоль повторяющиеся имена отверстий с одинаковым количеством параметров.

    // 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}" (не рекомендуется).

Другие вопросы по тегам