代码之家  ›  专栏  ›  技术社区  ›  MonkeyWrench

Serilog不会破坏对象集合的结构

  •  0
  • MonkeyWrench  · 技术社区  · 8 年前

    当调用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"
    

    1 回复  |  直到 8 年前
        1
  •  0
  •   George Kargakis    7 年前

    可以使用分解策略来记录对象集合:

    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();
        }
    }
    

    马币。有成就的asp.net核心解决方案 sample

    推荐文章