| プロパティ | 価値 |
|---|---|
| ルール識別子 | CA1873 |
| タイトル | コストの高いログ記録を回避する |
| カテゴリ | パフォーマンス |
| 修正が破壊的であるか非破壊的であるか | Non-breaking |
| .NET 10 で既定で有効 | 提案として |
原因
多くの場合、ログ記録が無効になっているか、ログ レベルに設定されているため、引数のログ記録に不要な評価が行われます。
ルールの説明
ログ 記録メソッドが呼び出されると、ログ レベルが有効かどうかに関係なく、その引数が評価されます。 これにより、ログ メッセージが書き込まれない場合でも、負荷の高い操作が実行される可能性があります。 パフォーマンスを向上させるには、 IsEnabled するチェックを使用するか、 LoggerMessageAttributeでソース生成ログを使用して、コストのかかるログ記録呼び出しを保護します。
違反を修正する方法
この規則違反を修正するには、次のいずれかの方法を使用します。
- IsEnabledのチェックを使用して、ログ記録呼び出しを保護します。
- LoggerMessageAttributeでソース生成ログを使用します。
- 必要な場合を除き、ログの引数でコストのかかる操作が実行されないようにします。
Example
次のコード スニペットは、CA1873 の違反を示しています。
class ViolationExample
{
private readonly ILogger _logger;
public ViolationExample(ILogger<ViolationExample> 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 });
}
}
Class ViolationExample
Private ReadOnly _logger As ILogger
Public Sub New(logger As ILogger(Of ViolationExample))
_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
次のコード スニペットは、ソース生成ログを使用して違反を修正します。
partial class FixExample
{
private readonly ILogger _logger;
public FixExample(ILogger<FixExample> logger)
{
_logger = logger;
}
public void ProcessData(int[] data)
{
// Fixed: use source-generated logging.
// The data array is passed directly; no expensive operation executed unless log level is enabled.
LogProcessingData(data);
// Fixed: use source-generated logging.
LogTraceData(data.Length, data);
}
[LoggerMessage(Level = LogLevel.Debug, Message = "Processing {Data} items")]
private partial void LogProcessingData(int[] data);
[LoggerMessage(Level = LogLevel.Trace, Message = "Data: Count={Count}, Items={Items}")]
private partial void LogTraceData(int count, int[] items);
}
Partial Class FixExample
Private ReadOnly _logger As ILogger
Public Sub New(logger As ILogger(Of FixExample))
_logger = logger
End Sub
Public Sub ProcessData(data As Integer())
' Fixed: use source-generated logging.
' The data array is passed directly; no expensive operation executed unless log level is enabled.
LogProcessingData(data)
' Fixed: use source-generated logging.
LogTraceData(data.Length, data)
End Sub
<LoggerMessage(Level:=LogLevel.Debug, Message:="Processing {Data} items")>
Private Partial Sub LogProcessingData(data As Integer())
End Sub
<LoggerMessage(Level:=LogLevel.Trace, Message:="Data: Count={Count}, Items={Items}")>
Private Partial Sub LogTraceData(count As Integer, items As Integer())
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
詳細については、「 コード分析の警告を抑制する方法」を参照してください。
こちらも参照ください
GitHub で Microsoft と共同作業する
このコンテンツのソースは GitHub にあります。そこで、issue や pull request を作成および確認することもできます。 詳細については、共同作成者ガイドを参照してください。
.NET