|
| 1 | +--- |
| 2 | +title: "CA1873: Avoid potentially expensive logging (code analysis)" |
| 3 | +description: "Learn about code analysis rule CA1873: Avoid potentially expensive logging" |
| 4 | +ms.date: 10/27/2025 |
| 5 | +ms.topic: reference |
| 6 | +f1_keywords: |
| 7 | + - CA1873 |
| 8 | + - AvoidPotentiallyExpensiveCallWhenLoggingAnalyzer |
| 9 | +helpviewer_keywords: |
| 10 | + - CA1873 |
| 11 | +dev_langs: |
| 12 | + - CSharp |
| 13 | + - VB |
| 14 | +ai-usage: ai-generated |
| 15 | +--- |
| 16 | + |
| 17 | +# CA1873: Avoid potentially expensive logging |
| 18 | + |
| 19 | +| Property | Value | |
| 20 | +|-------------------------------------|----------------------------------------| |
| 21 | +| **Rule ID** | CA1873 | |
| 22 | +| **Title** | Avoid potentially expensive logging | |
| 23 | +| **Category** | [Performance](performance-warnings.md) | |
| 24 | +| **Fix is breaking or non-breaking** | Non-breaking | |
| 25 | +| **Enabled by default in .NET 10** | As suggestion | |
| 26 | + |
| 27 | +## Cause |
| 28 | + |
| 29 | +In many situations, logging is disabled or set to a log level that results in an unnecessary evaluation for logging arguments. |
| 30 | + |
| 31 | +## Rule description |
| 32 | + |
| 33 | +When logging methods are called, their arguments are evaluated regardless of whether the logging level is enabled. This can result in expensive operations being executed even when the log message won't be written. For better performance, guard expensive logging calls with a check to <xref:Microsoft.Extensions.Logging.ILogger.IsEnabled%2A> or use the `LoggerMessage` pattern. |
| 34 | + |
| 35 | +## How to fix violations |
| 36 | + |
| 37 | +To fix a violation of this rule, use one of the following approaches: |
| 38 | + |
| 39 | +- Guard the logging call with a check to <xref:Microsoft.Extensions.Logging.ILogger.IsEnabled%2A>. |
| 40 | +- Use the `LoggerMessage` pattern with <xref:Microsoft.Extensions.Logging.LoggerMessageAttribute>. |
| 41 | +- Ensure expensive operations aren't performed in logging arguments unless necessary. |
| 42 | + |
| 43 | +## Example |
| 44 | + |
| 45 | +The following code snippet shows violations of CA1873: |
| 46 | + |
| 47 | +```csharp |
| 48 | +using Microsoft.Extensions.Logging; |
| 49 | + |
| 50 | +class Example |
| 51 | +{ |
| 52 | + private readonly ILogger _logger; |
| 53 | + |
| 54 | + public Example(ILogger<Example> logger) |
| 55 | + { |
| 56 | + _logger = logger; |
| 57 | + } |
| 58 | + |
| 59 | + public void ProcessData(int[] data) |
| 60 | + { |
| 61 | + // Violation: expensive operation in logging argument. |
| 62 | + _logger.LogDebug($"Processing {string.Join(", ", data)} items"); |
| 63 | + |
| 64 | + // Violation: object creation in logging argument. |
| 65 | + _logger.LogTrace("Data: {Data}", new { Count = data.Length, Items = data }); |
| 66 | + } |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +```vb |
| 71 | +Imports Microsoft.Extensions.Logging |
| 72 | + |
| 73 | +Class Example |
| 74 | + Private ReadOnly _logger As ILogger |
| 75 | + |
| 76 | + Public Sub New(logger As ILogger(Of Example)) |
| 77 | + _logger = logger |
| 78 | + End Sub |
| 79 | + |
| 80 | + Public Sub ProcessData(data As Integer()) |
| 81 | + ' Violation: expensive operation in logging argument. |
| 82 | + _logger.LogDebug($"Processing {String.Join(", ", data)} items") |
| 83 | + |
| 84 | + ' Violation: object creation in logging argument. |
| 85 | + _logger.LogTrace("Data: {Data}", New With {.Count = data.Length, .Items = data}) |
| 86 | + End Sub |
| 87 | +End Class |
| 88 | +``` |
| 89 | + |
| 90 | +The following code snippet fixes the violations: |
| 91 | + |
| 92 | +```csharp |
| 93 | +using Microsoft.Extensions.Logging; |
| 94 | + |
| 95 | +class Example |
| 96 | +{ |
| 97 | + private readonly ILogger _logger; |
| 98 | + |
| 99 | + public Example(ILogger<Example> logger) |
| 100 | + { |
| 101 | + _logger = logger; |
| 102 | + } |
| 103 | + |
| 104 | + public void ProcessData(int[] data) |
| 105 | + { |
| 106 | + // Fixed: guard with IsEnabled check. |
| 107 | + if (_logger.IsEnabled(LogLevel.Debug)) |
| 108 | + { |
| 109 | + _logger.LogDebug($"Processing {string.Join(", ", data)} items"); |
| 110 | + } |
| 111 | + |
| 112 | + // Fixed: guard with IsEnabled check. |
| 113 | + if (_logger.IsEnabled(LogLevel.Trace)) |
| 114 | + { |
| 115 | + _logger.LogTrace("Data: {Data}", new { Count = data.Length, Items = data }); |
| 116 | + } |
| 117 | + } |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +```vb |
| 122 | +Imports Microsoft.Extensions.Logging |
| 123 | + |
| 124 | +Class Example |
| 125 | + Private ReadOnly _logger As ILogger |
| 126 | + |
| 127 | + Public Sub New(logger As ILogger(Of Example)) |
| 128 | + _logger = logger |
| 129 | + End Sub |
| 130 | + |
| 131 | + Public Sub ProcessData(data As Integer()) |
| 132 | + ' Fixed: guard with IsEnabled check. |
| 133 | + If _logger.IsEnabled(LogLevel.Debug) Then |
| 134 | + _logger.LogDebug($"Processing {String.Join(", ", data)} items") |
| 135 | + End If |
| 136 | + |
| 137 | + ' Fixed: guard with IsEnabled check. |
| 138 | + If _logger.IsEnabled(LogLevel.Trace) Then |
| 139 | + _logger.LogTrace("Data: {Data}", New With {.Count = data.Length, .Items = data}) |
| 140 | + End If |
| 141 | + End Sub |
| 142 | +End Class |
| 143 | +``` |
| 144 | + |
| 145 | +## When to suppress warnings |
| 146 | + |
| 147 | +It's safe to suppress a warning from this rule if performance isn't a concern or if the logging arguments don't involve expensive operations. |
| 148 | + |
| 149 | +## Suppress a warning |
| 150 | + |
| 151 | +If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule. |
| 152 | + |
| 153 | +```csharp |
| 154 | +#pragma warning disable CA1873 |
| 155 | +// The code that's violating the rule is on this line. |
| 156 | +#pragma warning restore CA1873 |
| 157 | +``` |
| 158 | + |
| 159 | +To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md). |
| 160 | + |
| 161 | +```ini |
| 162 | +[*.{cs,vb}] |
| 163 | +dotnet_diagnostic.CA1873.severity = none |
| 164 | +``` |
| 165 | + |
| 166 | +For more information, see [How to suppress code analysis warnings](../suppress-warnings.md). |
| 167 | + |
| 168 | +## See also |
| 169 | + |
| 170 | +- [Performance rules](performance-warnings.md) |
| 171 | +- [High-performance logging in .NET](../../../core/extensions/high-performance-logging.md) |
| 172 | +- [Compile-time logging source generation](../../../core/extensions/logger-message-generator.md) |
0 commit comments