gpt4 book ai didi

c# - 解构 EF 对象会导致 Serilog 内存不足

转载 作者:行者123 更新时间:2023-12-03 23:55:44 24 4
gpt4 key购买 nike

我正在为使用 Entity Framework 的 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 接收器并且无法访问 ApplicationInsights 等?

最佳答案

我猜测 Serilog 由于实体中的导航属性而挂起,这很容易导致整个数据库被加载。我找到了 an issue on a Serilog似乎描述了相同问题的项目。

在那个问题上,他们说:

Serilog does already have a maximum depth limit; it's set to 10 by default but you can use Destructure.ToMaximumDepth(n) to reduce it.



您可以尝试将其设置为 1,以防止加载相关实体。但是,我个人认为这不是一个理想的解决方案。

还有 this NuGet package允许您使用 NotLogged您不想记录的属性或字段的属性。哪个可行,但如果您在某处的导航属性上忘记了它,仍然很容易错过。

由于 Serilog 为您提供了自定义解构处理方式的选项。您可以编写自己的处理程序来满足您的所有要求,例如最大时间花费日志记录,或者只是让它记录堆栈跟踪,说明它试图将对象解构为故障安全。但这取决于你。

关于c# - 解构 EF 对象会导致 Serilog 内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48516514/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com