次の方法で共有


CA1873: コストの高いログ記録を回避する

プロパティ 価値
ルール識別子 CA1873
タイトル コストの高いログ記録を回避する
カテゴリ パフォーマンス
修正が破壊的であるか非破壊的であるか Non-breaking
.NET 10 で既定で有効 提案として

原因

多くの場合、ログ記録が無効になっているか、ログ レベルに設定されているため、引数のログ記録に不要な評価が行われます。

ルールの説明

ログ 記録メソッドが呼び出されると、ログ レベルが有効かどうかに関係なく、その引数が評価されます。 これにより、ログ メッセージが書き込まれない場合でも、負荷の高い操作が実行される可能性があります。 パフォーマンスを向上させるには、 IsEnabled または LoggerMessage パターンを使用するチェックを使用して、コストの高いログ記録呼び出しを保護します。

違反を修正する方法

この規則違反を修正するには、次のいずれかの方法を使用します。

  • IsEnabledのチェックを使用して、ログ記録呼び出しを保護します。
  • LoggerMessageAttributeLoggerMessage パターンを使用します。
  • 必要な場合を除き、ログの引数でコストのかかる操作が実行されないようにします。

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

詳細については、「 コード分析の警告を抑制する方法」を参照してください。

こちらも参照ください