NLog JsonLayout имеет две опции, которые важны для сериализации свойств LogEvent:
- IncludeAllProperties
- MaxRecursionLimit
Параметры по умолчанию примерно такие:
<layout type="JsonLayout" includeAllProperties="false" maxRecursionLimit="0">
<attribute name="time" layout="${longdate}" />
<attribute name="level" layout="${level}"/>
<attribute name="message" layout="${message}" />
</layout>
Но вы также можете активировать включение свойств LogEvent следующим образом:
<layout type="JsonLayout" includeAllProperties="true" maxRecursionLimit="10">
<attribute name="time" layout="${longdate}" />
<attribute name="level" layout="${level}"/>
<attribute name="message" layout="${message}" />
</layout>
Если у вас есть такой объект:
public class Planet
{
public string Name { get; set; }
public string PlanetType { get; set; }
public override string ToString()
{
return Name; // Will be called in normal message-formatting
}
}
Тогда вы можно зарегистрировать объект следующим образом:
logger.Info("Hello {World}", new Planet() { Name = "Earth", PlanetType = "Water Planet" });
JsonLayout по умолчанию будет просто включать атрибуты по умолчанию, где message
-attribute говорит Hello Earth
.
Но JsonLayout с includeAllProperties="true"
будет включать любые дополнительные свойства LogEvent. И будет включать в себя World
-property, который был полностью сериализован.
Идея состоит в том, что не нужно заботиться о том, как настраиваются цели NLog при ведении журнала. Именно Logging-Rules + Target-Configuration + Layout-Configuration решает, как все должно быть наконец написано.
Если вы действительно хотите, чтобы объект был сериализован в ${message}
, то вы также можете сделать это:
logger.Info("Hello {@World}", new Planet() { Name = "Earth", PlanetType = "Water Planet" });
Если вы не хотите, чтобы свойства LogEvent смешивались со свойствами по умолчанию, вы можете сделать это:
<layout type="JsonLayout" maxRecursionLimit="10">
<attribute name="time" layout="${longdate}" />
<attribute name="level" layout="${level}"/>
<attribute name="message" layout="${message}" />
<attribute name="properties" encode="false">
<layout type="JsonLayout" includeAllProperties="true" maxRecursionLimit="10" />
</attribute>
</layout>
Если у вас есть объект, который смешивает поля с свойств, то вы можете указать NLog выполнить пользовательское отражение для этого типа:
LogManager.Setup().SetupSerialization(s =>
s.RegisterObjectTransformation<GetEntityViewRequest>(obj =>
return Newtonsoft.Json.Linq.JToken.FromObject(obj) // Lazy and slow
)
);