Serilog序列化字段

时间:2017-09-11 09:15:36

标签: c# .net seq 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 {}

如果我将名称字段更改为属性,但是我不想在此阶段执行此操作。有什么方法吗?

2 个答案:

答案 0 :(得分:4)

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

.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>()

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

答案 1 :(得分:3)

感谢Nicholas Blumhardt提供了一个很好的起点。我只是做了一个小调整。

我的课:

php artisan make:controller API/PhotoController --api

日志通话:

public class Dummy
{
    public string Field = "the field";
    public string Property { get; set; } = "the property";
}

IDestructuringPolicy实现包括字段和属性:

Log.Information("Dummy = {@Dummy}", new Dummy());