将 Azure 诊断日志写入 blob 存储的性能影响
Performance impact of writing Azure diagnostic logs to blob storage
我们的 C# Web 应用程序 运行 在 Azure 上使用 System.Diagnostics.Trace 为 debugging/troubleshooting 编写跟踪语句。一旦我们为这些日志启用 blob 存储(使用 Azure 门户中的 "Application Logging (blob)" 选项),我们应用程序的响应时间就会大大减慢。如果我关闭此选项,Web 应用程序会再次加速(尽管显然我们不再在 blob 存储中获取日志)。
有人知道这是否符合预期吗?我们当然会在每个请求上写很多跟踪语句(每个请求 100 条左右),但我认为这对于 Web 应用程序来说并不罕见。有什么方法可以诊断为什么为日志启用 blob 存储会显着减慢这些跟踪语句的执行速度?例如,写入跟踪语句是否与 blob 存储中正在更新的日志同步?
我无法找到有关如何将日志记录到 Azure 中的 blob 存储的任何信息。然而,这是我能够推断出的:
我确认禁用 global lock 没有效果。因此,性能问题与锁争用没有直接关系。
我也确认如果我关闭AutoFlush,性能问题不会出现。
通过进一步的交叉引用 the source code for the .NET trace API,我的结论是,当您为日志启用 blob 存储时,它会在您的应用程序中注入某种跟踪侦听器(与您在中添加侦听器的方式相同) web.config) 并将它收到的每个跟踪语句同步写入 blob 存储。
因此,似乎有几种方法可以解决此问题:
- 不要打开自动冲洗,而是定期手动冲洗。这将防止同步 blob 写入中断每个日志语句。
- 编写你自己的守护进程,定期将本地日志文件复制到 blob 存储或类似的东西
- 根本不要使用此 blob 存储功能,而是利用 the tracing functionality in Application Insights。
我最后做了 #3,因为事实证明,我们已经配置了 Application Insights,只是没有意识到它可以处理跟踪日志记录和查询。在跟踪事件 disabling sampling 之后,我们现在有一种方法可以轻松地远程查询任何日志语句并获取符合任何条件的完整跟踪集(关键字匹配、特定请求的所有跟踪、特定中的所有跟踪时间段等)此外,使用 Application Insights 跟踪侦听器编写日志语句没有明显的同步开销,因此我们的应用程序中无需更改任何内容(我们可以继续使用 .NET 跟踪 class)。作为奖励,由于 Application Insights 跟踪对于跟踪源非常灵活,如果需要,我们甚至可以切换到另一个更高性能的日志记录 API(例如 ETW 或 log4net)并且 Application Insights 仍然有效。
最终,您应该考虑使用 Application Insights 来存储和查询您的跟踪。根据您最初希望将日志存储在 blob 存储中的原因,它可能满足也可能不满足您的需求,但它对我们有用。
我们的 C# Web 应用程序 运行 在 Azure 上使用 System.Diagnostics.Trace 为 debugging/troubleshooting 编写跟踪语句。一旦我们为这些日志启用 blob 存储(使用 Azure 门户中的 "Application Logging (blob)" 选项),我们应用程序的响应时间就会大大减慢。如果我关闭此选项,Web 应用程序会再次加速(尽管显然我们不再在 blob 存储中获取日志)。
有人知道这是否符合预期吗?我们当然会在每个请求上写很多跟踪语句(每个请求 100 条左右),但我认为这对于 Web 应用程序来说并不罕见。有什么方法可以诊断为什么为日志启用 blob 存储会显着减慢这些跟踪语句的执行速度?例如,写入跟踪语句是否与 blob 存储中正在更新的日志同步?
我无法找到有关如何将日志记录到 Azure 中的 blob 存储的任何信息。然而,这是我能够推断出的:
我确认禁用 global lock 没有效果。因此,性能问题与锁争用没有直接关系。
我也确认如果我关闭AutoFlush,性能问题不会出现。
通过进一步的交叉引用 the source code for the .NET trace API,我的结论是,当您为日志启用 blob 存储时,它会在您的应用程序中注入某种跟踪侦听器(与您在中添加侦听器的方式相同) web.config) 并将它收到的每个跟踪语句同步写入 blob 存储。
因此,似乎有几种方法可以解决此问题:
- 不要打开自动冲洗,而是定期手动冲洗。这将防止同步 blob 写入中断每个日志语句。
- 编写你自己的守护进程,定期将本地日志文件复制到 blob 存储或类似的东西
- 根本不要使用此 blob 存储功能,而是利用 the tracing functionality in Application Insights。
我最后做了 #3,因为事实证明,我们已经配置了 Application Insights,只是没有意识到它可以处理跟踪日志记录和查询。在跟踪事件 disabling sampling 之后,我们现在有一种方法可以轻松地远程查询任何日志语句并获取符合任何条件的完整跟踪集(关键字匹配、特定请求的所有跟踪、特定中的所有跟踪时间段等)此外,使用 Application Insights 跟踪侦听器编写日志语句没有明显的同步开销,因此我们的应用程序中无需更改任何内容(我们可以继续使用 .NET 跟踪 class)。作为奖励,由于 Application Insights 跟踪对于跟踪源非常灵活,如果需要,我们甚至可以切换到另一个更高性能的日志记录 API(例如 ETW 或 log4net)并且 Application Insights 仍然有效。
最终,您应该考虑使用 Application Insights 来存储和查询您的跟踪。根据您最初希望将日志存储在 blob 存储中的原因,它可能满足也可能不满足您的需求,但它对我们有用。