|
| 1 | +# AG0041: Use message templates in logging |
| 2 | + |
| 3 | +Structured logging should be employed instead of string interpolation or concatenation. |
| 4 | + |
| 5 | +## Why is this an issue? |
| 6 | + |
| 7 | +Logging is a critical aspect of any application, providing insights into its behavior and facilitating debugging. |
| 8 | +However, not all logging approaches are created equal. Using string interpolation or concatenation for log messages is |
| 9 | +a common pitfall that can lead to performance issues and hinder log analysis. |
| 10 | + |
| 11 | +Consider the following problematic code: |
| 12 | + |
| 13 | +```csharp |
| 14 | +logger.Information($"User {userId} logged in at {DateTime.Now}"); // Noncompliant |
| 15 | +logger.Information("Error occurred: " + errorMessage); // Noncompliant |
| 16 | +``` |
| 17 | + |
| 18 | +Instead, you should use message templates: |
| 19 | + |
| 20 | +```csharp |
| 21 | +logger.Information("User {UserId} logged in at {LoginTime}", userId, DateTime.Now); // Compliant |
| 22 | +logger.Information("Error occurred: {ErrorMessage}", errorMessage); // Compliant |
| 23 | +``` |
| 24 | + |
| 25 | +## Benefits of using message templates |
| 26 | + |
| 27 | +The use of message templates in logging offers several significant advantages over traditional string interpolation or |
| 28 | +concatenation methods. Firstly, message templates can provide a notable performance boost, particularly in scenarios where |
| 29 | +log messages aren't actually written due to log level settings. This efficiency is crucial in high-volume logging environments |
| 30 | +where every millisecond counts. |
| 31 | + |
| 32 | +Structured logging, enabled by message templates, is another key benefit. It allows variables to be captured as separate entities |
| 33 | +rather than being merged into a single string. This separation enables powerful log analysis capabilities, making it easier to search, |
| 34 | +filter, and aggregate log data based on specific parameters. The ability to maintain consistent log formats across an application |
| 35 | +is also greatly enhanced with message templates, leading to more uniform and easily interpretable logs. |
| 36 | + |
| 37 | +Message templates also facilitate semantic logging, allowing developers to attach additional metadata to log events. This extra |
| 38 | +context can be invaluable when debugging complex issues or analyzing application behavior. Furthermore, modern logging frameworks such |
| 39 | +as Serilog and Microsoft.Extensions.Logging are optimized for template-style logging. By using message templates, developers can |
| 40 | +take full advantage of these frameworks' features and performance optimizations, ensuring their logging strategy is future-proof |
| 41 | +and aligned with industry best practices. |
| 42 | + |
| 43 | +## More Info |
| 44 | + |
| 45 | +This analyzer checks for the use of string interpolation (`$"..."`) or string concatenation in logging method calls. It specifically targets methods of `ILogger` from both `Microsoft.Extensions.Logging` and `Serilog`. |
| 46 | + |
| 47 | +### Noncompliant Code Examples |
| 48 | + |
| 49 | +```csharp |
| 50 | +_logger.LogInformation($"Processing order {orderId}"); |
| 51 | +_logger.LogError("Error: " + exception.Message); |
| 52 | +``` |
| 53 | + |
| 54 | +### Compliant Solution |
| 55 | + |
| 56 | +```csharp |
| 57 | +_logger.LogInformation("Processing order {OrderId}", orderId); |
| 58 | +_logger.LogError("Error: {ErrorMessage}", exception.Message); |
| 59 | +``` |
| 60 | + |
| 61 | +### Exceptions |
| 62 | + |
| 63 | +This rule doesn't apply to non-logging methods or to logging methods that explicitly expect formatted strings. |
| 64 | + |
| 65 | +## Resources |
| 66 | + |
| 67 | +* [Structured logging with ILogger in .NET](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-5.0#log-message-template) |
| 68 | +* [Serilog message templates](https://github.com/serilog/serilog/wiki/Writing-Log-Events#message-templates) |
0 commit comments