다음을 통해 공유


CA1873: 비용이 많이 드는 로깅 방지

재산 가치
규칙 아이디 CA1873
Title 잠재적으로 비용이 많이 드는 로깅 방지
범주 성능
수정 사항이 문제를 해결하고 있는지 혹은 새로운 문제를 일으키지 않는지 여부 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

자세한 내용은 코드 분석 경고를 표시하지 않는 방법을 참조하세요.

참고하십시오