Serilog сериализует поля
Если у меня есть следующий класс
public class Customer
{
public string Name;
}
а затем иметь следующую команду журнала в Serilog
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.Seq("http://localhost:5341")
.CreateLogger();
var item = new Customer();
item.Name = "John";
Serilog.Log.Information("Customer {@item}", item);
Журнал просто отображается в Seq как
Customer {}
Если я изменю поле "Имя" на свойство, оно будет работать, но я бы предпочел не делать этого на этом этапе. Есть ли способ обойти это?
1 ответ
Чтобы сделать это только для одного типа (рекомендуется), вы можете использовать:
.Destructure.ByTransforming<Customer>(c => new { c.Name })
Если вы хотите включить открытые поля для всех типов или те, которые соответствуют каким-либо условиям, вы можете подключить политику, чтобы сделать это:
class IncludePublicFieldsPolicy : IDestructuringPolicy
{
public bool TryDestructure(
object value,
ILogEventPropertyValueFactory propertyValueFactory,
out LogEventPropertyValue result)
{
if (!(value is SomeBaseType))
{
result = null;
return false;
}
var fieldsWithValues = value.GetType().GetTypeInfo().DeclaredFields
.Where(f => f.IsPublic)
.Select(f => new LogEventProperty(f.Name,
propertyValueFactory.CreatePropertyValue(f.GetValue(value))));
result = new StructureValue(fieldsWithValues);
return true;
}
}
Пример ограничивает это, чтобы посмотреть на объекты, полученные из SomeBaseType
только.
Вы можете подключить его с помощью:
.Destructure.With<IncludePublicFieldsPolicy>()
(Я думаю, что это, вероятно, потребует некоторой настройки, но должно быть хорошей отправной точкой.)
Спасибо Николасу Блюмхардту за хорошую отправную точку. Просто у меня небольшая поправка.
мои занятия:
public class Dummy
{
public string Field = "the field";
public string Property { get; set; } = "the property";
}
журнал вызовов:
Log.Information("Dummy = {@Dummy}", new Dummy());
Реализация IDestructuringPolicy включает как поля, так и свойства:
internal class IncludePublicFieldsPolicy : IDestructuringPolicy
{
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
{
var typeInfo = value.GetType().GetTypeInfo();
var fieldsWithValues = typeInfo
.DeclaredFields
.Where(f => f.IsPublic)
.Select(f =>
{
var val = f.GetValue(value);
var propval = propertyValueFactory.CreatePropertyValue(val);
var ret = new LogEventProperty(f.Name, propval);
return ret;
})
;
var propertiesWithValues = typeInfo
.DeclaredProperties
.Where(f => f.CanRead)
.Select(f =>
{
var val = f.GetValue(value);
var propval = propertyValueFactory.CreatePropertyValue(val);
var ret = new LogEventProperty(f.Name, propval);
return ret;
})
;
result = new StructureValue(fieldsWithValues.Union(propertiesWithValues));
return true;
}
}