| 资产 | 价值 |
|---|---|
| 规则 ID | CA1873 |
| 标题 | 避免可能成本高昂的日志记录 |
| 类别 | 性能 |
| 修复是中断修复还是非中断修复 | Non-breaking |
| 在 .NET 10 中默认启用 | 作为建议 |
原因
在许多情况下,日志记录被禁用或设置为日志级别,这会导致对日志记录参数进行不必要的评估。
规则说明
调用日志记录方法时,无论是否启用日志记录级别,都会评估其参数。 这可能会导致执行成本高昂的作,即使不会写入日志消息也是如此。 为了获得更好的性能,请使用检查 IsEnabled 或使用 LoggerMessage 模式保护昂贵的日志记录调用。
如何修复违规行为
若要修复此规则的冲突,请使用以下方法之一:
- 使用检查来 IsEnabled保护日志记录调用。
- 将
LoggerMessage模式与 LoggerMessageAttribute. - 确保除非必要,否则不会在日志记录参数中执行昂贵的作。
Example
以下代码片段显示了 CA1873 的冲突:
using Microsoft.Extensions.Logging;
class Example
{
private readonly ILogger _logger;
public Example(ILogger<Example> logger)
{
_logger = logger;
}
public void ProcessData(int[] data)
{
// Violation: expensive operation in logging argument.
_logger.LogDebug($"Processing {string.Join(", ", data)} items");
// Violation: object creation in logging argument.
_logger.LogTrace("Data: {Data}", new { Count = data.Length, Items = data });
}
}
Imports Microsoft.Extensions.Logging
Class Example
Private ReadOnly _logger As ILogger
Public Sub New(logger As ILogger(Of Example))
_logger = logger
End Sub
Public Sub ProcessData(data As Integer())
' Violation: expensive operation in logging argument.
_logger.LogDebug($"Processing {String.Join(", ", data)} items")
' Violation: object creation in logging argument.
_logger.LogTrace("Data: {Data}", New With {.Count = data.Length, .Items = data})
End Sub
End Class
以下代码片段修复了冲突:
using Microsoft.Extensions.Logging;
class Example
{
private readonly ILogger _logger;
public Example(ILogger<Example> logger)
{
_logger = logger;
}
public void ProcessData(int[] data)
{
// Fixed: guard with IsEnabled check.
if (_logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug($"Processing {string.Join(", ", data)} items");
}
// Fixed: guard with IsEnabled check.
if (_logger.IsEnabled(LogLevel.Trace))
{
_logger.LogTrace("Data: {Data}", new { Count = data.Length, Items = data });
}
}
}
Imports Microsoft.Extensions.Logging
Class Example
Private ReadOnly _logger As ILogger
Public Sub New(logger As ILogger(Of Example))
_logger = logger
End Sub
Public Sub ProcessData(data As Integer())
' Fixed: guard with IsEnabled check.
If _logger.IsEnabled(LogLevel.Debug) Then
_logger.LogDebug($"Processing {String.Join(", ", data)} items")
End If
' Fixed: guard with IsEnabled check.
If _logger.IsEnabled(LogLevel.Trace) Then
_logger.LogTrace("Data: {Data}", New With {.Count = data.Length, .Items = data})
End If
End Sub
End Class
何时禁止显示警告
如果性能不关心或日志记录参数不涉及昂贵的作,则禁止显示此规则的警告是安全的。
禁止显示警告
如果只想抑制单个冲突,请将预处理器指令添加到源文件以禁用该规则,然后重新启用该规则。
#pragma warning disable CA1873
// The code that's violating the rule is on this line.
#pragma warning restore CA1873
若要禁用文件、文件夹或项目的规则,请在none中将其严重性设置为。
[*.{cs,vb}]
dotnet_diagnostic.CA1873.severity = none
有关详细信息,请参阅 如何禁止显示代码分析警告。