Compartilhar via


CA1873: Evitar registro em log potencialmente caro

Propriedade Value
ID da regra CA1873
Title Evitar registro em log potencialmente caro
Categoria Desempenho
Correção é disruptiva ou não disruptiva Non-breaking
Habilitado por padrão no .NET 10 Como sugestão

Motivo

Em muitas situações, o registro em log é desabilitado ou definido como um nível de log que resulta em uma avaliação desnecessária para argumentos de log.

Descrição da regra

Quando os métodos de registro em log são chamados, seus argumentos são avaliados independentemente de o nível de log estar habilitado. Isso pode resultar em operações caras sendo executadas mesmo quando a mensagem de log não será gravada. Para obter um melhor desempenho, proteja chamadas de log caras com uma verificação IsEnabled ou use o log gerado pela origem com o LoggerMessageAttribute atributo.

Como corrigir violações

Para corrigir uma violação dessa regra, use uma das seguintes abordagens:

  • Proteja a chamada de registro em log com uma verificação para IsEnabled.
  • Use o log gerado pela origem com o LoggerMessageAttribute atributo.
  • Verifique se as operações caras não são executadas em argumentos de registro em log, a menos que seja necessário.

Example

O snippet de código a seguir mostra violações da 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

O snippet de código a seguir corrige as violações usando o log gerado pela origem:

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

Quando suprimir avisos

É seguro suprimir um aviso dessa regra se o desempenho não for uma preocupação ou se os argumentos de registro em log não envolverem operações caras.

Suprimir um aviso

Se você quiser suprimir apenas uma única violação, adicione diretivas de pré-processamento ao arquivo de origem para desabilitar e, em seguida, habilitar novamente a regra.

#pragma warning disable CA1873
// The code that's violating the rule is on this line.
#pragma warning restore CA1873

Para desabilitar a regra para um arquivo, pasta ou projeto, defina sua severidade none no arquivo de configuração.

[*.{cs,vb}]
dotnet_diagnostic.CA1873.severity = none

Para obter mais informações, consulte Como suprimir avisos de análise de código.

Consulte também