.net-core - 启用调试日志级别时,Serilog 性能受到巨大影响
问题描述
我在 .NET Core Service Fabric 应用程序上使用 Serilog。
我们注意到性能问题,经过调查发现 Serilog 是罪魁祸首。
我们记录了大约 2,000 条调试消息,这需要 10 多秒。
即使仅配置了控制台接收器并将其设置为仅在信息日志级别上进行过滤(因此不显示任何调试消息),也是如此。
将 MinimumLevel 设置为 Information 会使相同的代码运行不到 1 秒(即使配置了接收器)。
我们的项目使用:
- netcoreapp2.0
- Serilog NuGet 包 2.8.0(最新)
这是 Serilog 所期望的那种性能吗?
编辑:我注意到另一个(很多)较小的项目有同样的行为。这使我能够隔离问题:我有一个正在检索 ProcessId 的自定义浓缩器。打电话Process.GetCurrentProcess()
是非常昂贵的。对每个日志调用都这样做是导致性能下降的原因。我将进程 ID 存储在实例字段中,性能飙升。
解决方案
过滤掉调试级别的事件与设置最低级别不同;Serilog 可用于结构化日志数据的序列化,因此Debug
事件的构建可能会占用时间。
这可能表明您的调试日志记录存在问题 - Serilog 本身速度很快,但如果您的调试事件正在序列化任意大的东西,例如请求/响应有效负载或 DTO,您的应用程序最终会进行大量反射,属性访问器调用您的对象(可能会阻塞、执行 I/O 和其他疯狂的事情)、分配和垃圾收集。
如果调试事件使用无效的消息模板(即通过使用$"..."
字符串插值或非常量字符串进行记录),那么您的应用程序也将浪费大量精力将这些解析为格式字符串。
也就是说,并不是 Serilog 在这里很慢,而是您的应用程序无意中让它做了很多浪费的工作。
使用Debug
然后Information
在控制台接收器上使用稍后的过滤器将导致所有这些工作完成,然后被丢弃。将最低级别设置为Information
将首先阻止这项工作。
从长远来看,审核您的调试级别日志记录以使用非常量消息模板,@
应该destructureObjects: true
有助于让事情恢复到正常水平。
推荐阅读
- ios - Swift将字符串从一个到所有字母放入数组
- android - java.lang.RuntimeException:WakeLock 未锁定唤醒:com.google.firebase.messaging
- r - 方法分派时 UseMethod 出错
- ansible - Ansible:在 Ansible 清单中使用主机范围时如何获取当前的“主机索引”?
- python - 检查用户是否属于 Odoo 中的组
- karate - 空手道测试:如何匹配仅包含一个模式的每个嵌套数组响应
- java - 在java中使用Builder更新对象的特定字段
- latex - Latex 使用不同的背景颜色突出显示参考部分中的引文
- ubuntu - 控制台通过 ssh 冻结到远程服务器
- json - 创建动态可编码对象