До сегодняшнего дня мы использовали NLog версии 4.4.12 (без структурированного ведения журнала). Однако мы использовали https://www.nuget.org/packages/NLog.StructuredLogging.Json/ для структурированной регистрации.
Хорошая особенность использования этого расширения в том, что вам НЕ нужно иметь шаблонные сообщения (содержащие индексы или заполнители для ваших дополнительных параметров / объектов для регистрации). Сообщение не содержит индексов или заполнителей для ваших дополнительных объектов (например, анонимного типа) для регистрации.
Переходя на NLog 4.6.5, который поддерживает структурированное ведение журнала из коробки, мы хотели бы избавиться от этого дополнительного пакета NuGet. Однако наши дополнительные параметры регистрируются только при использовании шаблонных сообщений с фактическими индексированными / именованными заполнителями.
Отсутствие индекса или заполнителей в нашем сообщении не приводит к выводу наших дополнительных параметров / объектов через JSON.
Возможно ли иметь сообщения без шаблонов, все еще используя структурированное ведение журнала NLog для наших дополнительных параметров, которые были переданы им для добавления в JSON?
Ниже приведен пример (обратите внимание, что мы используем дополнительную оболочку вокруг nlog)
NLog версия : 4.6.5
Платформа : .Net 4.5
Текущая конфигурация NLog
// Arrange
var typeUsingLogger = typeof(NLogWrapperTest);
var nLogWrapper = new NLogWrapper(typeof(NLogWrapper));
var level = (LogLevel)Enum.Parse(typeof(LogLevel), nLevel.Name);
var message = $"{Guid.NewGuid()}"; // {{extendedLogProperties}} {{@extendedLogProperties}} {{@purchase}} {{badplaceholder}}
var innerException = new DivideByZeroException("bla inner exception");
var exception = new ArgumentNullException("bla out exception", innerException);
var extendedLogProperties = new
{
ClientID = 8,
MyOtherProp = "abc",
MySubObject = new
{
//nested object although not recommended
A = 123,
B = "yep"
}
};
//log configuration
var logConfig = new LoggingConfiguration();
var memoryTarget = new MemoryTarget("MemoryTarget");
var jsonLayout = new JsonLayout
{
IncludeAllProperties = true,
Attributes =
{
new JsonAttribute("dateTime", "${date:universalTime=true:format=o}" ),
new JsonAttribute("level", "${level:uppercase=true}" ),
new JsonAttribute("logger", "${logger}" ),
new JsonAttribute("message", "${message}" ),
new JsonAttribute("callsite", "${callsite:className=true:methodName=true:skipFrame=0}" ),
new JsonAttribute("exception", "${exception:format=ToString:innerFormat=ToString}" ),
new JsonAttribute("machinename", "${machinename}" ),
new JsonAttribute("processid", "${processid}" ),
new JsonAttribute("threadid", "${threadid}" ),
new JsonAttribute("threadname", "${threadname}" ),
new JsonAttribute("application", "${application}" ),
new JsonAttribute("aspnetSessionId", "${aspnet-sessionid}" ),
new JsonAttribute("iisSiteName", "${iis-site-name}" ),
new JsonAttribute("stage", "${stage}" ),
}
};
memoryTarget.Layout = jsonLayout;
logConfig.AddTarget("memoryTarget", memoryTarget);
var memoryTargetLoggingRule = new LoggingRule("*", nLevel, memoryTarget);
logConfig.LoggingRules.Add(memoryTargetLoggingRule);
LogManager.Configuration = logConfig;
// Act
nLogWrapper.Log(level, message, typeUsingLogger, exception, extendedLogProperties);
var jsonLogMsg = memoryTarget.Logs[0];
Assert.Matches("ClientID", jsonLogMsg);
Зачем нам это нужно?
Было бы очень хорошо, чтобы сообщение не изменялось без каких-либо замененных индексов или заполнителей, чтобы мы могли искать точно такое же сообщение в наших журналах. (использование new JsonAttribute("message", "${message:raw=true}"
не вариант)
Также таким образом мы не заканчиваем тем, что сериализованные объекты JSON один раз в сообщении журнала (заменяющие заполнители / индексы шаблонного сообщения) И дополнительные поля JSON для этих дополнительных параметров.
Пожалуйста, ознакомьтесь с лучшими практиками: https://github.com/justeat/NLog.StructuredLogging.Json/blob/master/README.md#best-practices
Если вы спросите: «Почему вы не продолжаете использовать расширение NuGet NLog?»
Ответ заключается в том, что структурированное ведение журнала в NLog делает более приятными дополнительные параметры при использовании {@placeholder} в шаблонных сообщениях для вложенных объектов.
Редактировать 1:
Я хотел бы, чтобы все свойства моего анонимного объекта отображались в корне json. Такие как:
{
...
"ClientID": 8,
"MyOtherProp": "abc",
"MySubObject": {
"A": 123,
"B": "yep"
},
...
}