Compartir a través de


CA1873: Evitar el registro potencialmente costoso

Propiedad Importancia
Identificador de la regla CA1873
Título Evitar el registro potencialmente costoso
Categoría Rendimiento
La corrección es disruptiva o no disruptiva Non-breaking
Habilitado de forma predeterminada en .NET 10 Como sugerencia

Causa

En muchas situaciones, el registro está deshabilitado o establecido en un nivel de registro que da como resultado una evaluación innecesaria para los argumentos de registro.

Descripción de la regla

Cuando se llama a los métodos de registro, sus argumentos se evalúan independientemente de si el nivel de registro está habilitado. Esto puede dar lugar a que se ejecuten operaciones costosas incluso cuando no se escriba el mensaje de registro. Para mejorar el rendimiento, proteja las llamadas de registro costosas con una comprobación o IsEnabled use el registro generado por el origen con LoggerMessageAttribute.

Cómo corregir infracciones

Para corregir una infracción de esta regla, use uno de los métodos siguientes:

  • Proteja la llamada de registro con una comprobación en IsEnabled.
  • Use el registro generado por el origen con LoggerMessageAttribute.
  • Asegúrese de que las operaciones costosas no se realizan en argumentos de registro a menos que sea necesario.

Example

En el fragmento de código siguiente se muestran infracciones de 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

El siguiente fragmento de código corrige las infracciones mediante el registro generado por el origen:

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

Cuándo suprimir las advertencias

Es seguro suprimir una advertencia de esta regla si el rendimiento no es un problema o si los argumentos de registro no implican operaciones costosas.

Supresión de una advertencia

Si solo quiere suprimir una única infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y volver a habilitar la regla.

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

Para deshabilitar la regla de un archivo, una carpeta o un proyecto, establezca su gravedad a none en el archivo de configuración.

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

Para obtener más información, consulte Cómo suprimir advertencias de análisis de código.

Consulte también