Serilog не будет разрушать коллекции объектов - PullRequest
0 голосов
/ 11 июня 2018

Проект веб-службы MVC Core, использующий AspNetCore 2.0.0 и Serilogger 2.1.1.

При вызове Serilog для регистрации коллекции / IEnumerable / List объектов все, что он делает, это перечисляет типы объектов.Если мы перебираем элементы коллекции и регистрируем их независимо, Serilog хорошо их разрушает, и они правильно отображаются в наших журналах.

Базовый пример кода:

List<MyResponse> results = ValidateResourceCollection(events);
_logger.LogInformation("EventController.Post response {@results}", results);

И мы получимсообщение в журнале, подобное этому:

2018-06-11 10:53:35.952 -04:00 [Information] EventController.Post response "Blah.Models.Response.MyResponse, Blah.Models.Response.MyResponse"

Есть ли способ заставить Serilog правильно деструктурировать этот список?Я попытался исправить это, реализовав IDestructuringPolicy, но он вызывается только в том случае, если существует один объект для деструктуры.Если в качестве параметра используется коллекция объектов, IDestructuringPolicy никогда не вызывается.

1 Ответ

0 голосов
/ 14 сентября 2018

Вы можете использовать политику деструктурирования для регистрации коллекции объектов:

public class CollectionDestructuringPolicy<T> : IDestructuringPolicy
{
    public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory,
        out LogEventPropertyValue result)
    {

        switch (value)
        {
            case City city:
                result = Destruct(city,propertyValueFactory);
                return true;
            case ICollection<T> collection:
                result = Destruct(collection,propertyValueFactory);
                return true;
        }
        result = null;
        return false;
    }

    private static LogEventPropertyValue Destruct(object collectionItem, ILogEventPropertyValueFactory propertyValueFactory)
    {
        var collectionItemPropertiesNamePerValue = new List<(string propertyName, object propertyValue)>();
        var collectionItemProperties = collectionItem.GetType().GetProperties().ToList();
        collectionItemProperties.ForEach(p => collectionItemPropertiesNamePerValue.Add((propertyName:p.Name, propertyValue:p.GetValue(collectionItem))));
        var properties = new List<LogEventProperty>(collectionItemPropertiesNamePerValue.Count);
        collectionItemPropertiesNamePerValue.ForEach(namePerValue =>
            properties.Add(new LogEventProperty(namePerValue.propertyName,
                propertyValueFactory.CreatePropertyValue(namePerValue.propertyValue))));
        LogEventPropertyValue result = new StructureValue(properties);
        return result;
    }

    private static LogEventPropertyValue Destruct(IEnumerable<T> collection,
        ILogEventPropertyValueFactory propertyValueFactory)
    {
        var elements = collection.Select(e => propertyValueFactory.CreatePropertyValue(e, true));
        LogEventPropertyValue result = new SequenceValue(elements);
        return result;
    }
}
//In Logger Factory:
public static class LoggerFactory
{
    public static Logger Create()
    {
        return new LoggerConfiguration()
            .WriteTo.Console()
            .Destructure.With<CollectionDestructuringPolicy<City>>()
            .CreateLogger();
    }
}

RMK.завершенное базовое решение asp.net образец

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...