MVC核心Web服务项目,使用AspNetCore 2.0.0和Serilogger 2.1.1。
当调用Serilog来记录集合/ IEnumerable /对象列表时,它所做的就是列出对象类型。如果我们遍历集合中的项目并单独记录它们,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。
答案 0 :(得分:0)
您可以使用解构策略来记录对象的集合:
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核心解决方案sample