【发布时间】:2018-01-30 07:57:02
【问题描述】:
我正在为使用实体框架的 SaaS 应用程序测试 Serilog。 我注意到如果加载对象的上下文尚未处理,Serilog 无法处理解构 EF 对象。
Supplier supplier = context.Supplier.Find(6100);
Log.Information("This works and the cost for ToString() is negligible {supp}", supplier);
Log.Fatal("This will cause an Out of Memory error {@supp}", supplier);
Serilog 会尝试延迟加载整个数据库,应用会挂起一分钟然后崩溃。 Serilog 日志文件会报告 OutOfMemoryException
如何防止其他开发人员不小心执行以下操作并导致意外挂起/崩溃?
if(veryRarelyOccuringEvent)
Log.Information("Supplier {@supplier} just did something, supplier)
我所做的是使用解构策略来防止所有的解构, 我宁愿让开发人员明确声明 ToString 方法而不是使用 @。当然我们可以决定不使用@-operator,但是如果有人忘记了并且应用程序因此而崩溃怎么办? @ 在代码审查中很容易被忽略。我不想为 Serilog 操作构建一个包装器,只是为了防止使用 @。
以下内容将阻止使用@-operator:
Log.Logger = new LoggerConfiguration()
.Destructure.With<PreventDestructure>()
...
只会返回 {}。但是有没有比下面的代码更简单的方法呢?
public class PreventDestructure : IDestructuringPolicy {
public bool TryDestructure(
object value,
ILogEventPropertyValueFactory propertyValueFactory,
out LogEventPropertyValue result) {
List<LogEventProperty> fieldsWithValues;
fieldsWithValues = new List<LogEventProperty>();
result = new StructureValue(fieldsWithValues);
return true;
}
}
第二个问题:有没有办法指示 Serilog 在日志事件中花费最多 XXXms?如果我使用数据库接收器并且数据库处于脱机状态怎么办?如果我使用 AI sink 并且无法访问 ApplicationInsights 等?
【问题讨论】:
-
关于问题 2,大部分 sink 都是异步执行外部服务的日志记录,所以应用应该可以正常运行。
-
也许你应该默认关闭延迟加载。你真的需要它吗?
标签: c# asp.net-mvc entity-framework serilog