Partager via


CA1873 : Éviter la journalisation potentiellement coûteuse

Propriété Valeur
Identificateur de la règle CA1873
Titre Éviter la journalisation potentiellement coûteuse
Catégorie Niveau de performance
Le correctif est cassant ou non cassant Non-breaking
Activé par défaut dans .NET 10 À titre de suggestion

La cause

Dans de nombreuses situations, la journalisation est désactivée ou définie sur un niveau de journalisation qui entraîne une évaluation inutile pour les arguments de journalisation.

Description de la règle

Lorsque les méthodes de journalisation sont appelées, leurs arguments sont évalués, que le niveau de journalisation soit activé. Cela peut entraîner l’exécution d’opérations coûteuses même lorsque le message de journal n’est pas écrit. Pour de meilleures performances, protégez les appels de journalisation coûteux avec une vérification ou IsEnabled utilisez la journalisation générée par la source avec l’attribut LoggerMessageAttribute .

Comment corriger les violations

Pour corriger une violation de cette règle, utilisez l’une des approches suivantes :

  • Gardez l’appel de journalisation avec une vérification à IsEnabled.
  • Utilisez la journalisation générée par la source avec l’attribut LoggerMessageAttribute .
  • Vérifiez que les opérations coûteuses ne sont pas effectuées dans les arguments de journalisation, sauf si nécessaire.

Example

L’extrait de code suivant montre les violations 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

L’extrait de code suivant corrige les violations à l’aide de la journalisation générée par la source :

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

Quand supprimer les avertissements

Il est sûr de supprimer un avertissement de cette règle si les performances ne sont pas un problème ou si les arguments de journalisation n’impliquent pas d’opérations coûteuses.

Supprimer un avertissement

Si vous voulez supprimer une seule violation, ajoutez des directives de préprocesseur à votre fichier source pour désactiver et réactiver la règle.

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

Pour désactiver la règle sur un fichier, un dossier ou un projet, définissez sa gravité sur none dans le fichier de configuration.

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

Pour plus d’informations, consultez Comment supprimer les avertissements d’analyse du code.

Voir aussi