Serilog序列化字段

Cra*_*aig 3 .net c# seq serilog

如果我有以下课程

public class Customer
{
    public string Name;
}
Run Code Online (Sandbox Code Playgroud)

然后在Serilog中有以下log命令

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);
Run Code Online (Sandbox Code Playgroud)

日志仅在Seq中显示为

Customer {}
Run Code Online (Sandbox Code Playgroud)

如果我将“名称”字段更改为一个属性,则可以使用,但我目前不希望这样做。有什么办法解决吗?

Nic*_*rdt 5

要仅针对一种类型(推荐)执行此操作,可以使用:

.Destructure.ByTransforming<Customer>(c => new { c.Name })
Run Code Online (Sandbox Code Playgroud)

如果要包括所有类型的公共字段,或包含符合某种条件的公共字段,可以插入一个策略来做到这一点:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

该示例将范围缩小到SomeBaseType仅查看派生自对象的对象。

您可以将其插入:

.Destructure.With<IncludePublicFieldsPolicy>()
Run Code Online (Sandbox Code Playgroud)

(我认为可能需要进行一些调整,但这应该是一个很好的起点。)