Skip to content

Commit

Permalink
Update AG0041LogTemplateAnalyzer.cs (#193)
Browse files Browse the repository at this point in the history
* Update AG0041LogTemplateAnalyzer.cs

* Create AG0041.md
  • Loading branch information
joeldickson authored Oct 17, 2024
1 parent 5fe7cb1 commit 44c34b4
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 2 deletions.
68 changes: 68 additions & 0 deletions doc/AG0041.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# AG0041: Use message templates in logging

Structured logging should be employed instead of string interpolation or concatenation.

## Why is this an issue?

Logging is a critical aspect of any application, providing insights into its behavior and facilitating debugging.
However, not all logging approaches are created equal. Using string interpolation or concatenation for log messages is
a common pitfall that can lead to performance issues and hinder log analysis.

Consider the following problematic code:

```csharp
logger.Information($"User {userId} logged in at {DateTime.Now}"); // Noncompliant
logger.Information("Error occurred: " + errorMessage); // Noncompliant
```

Instead, you should use message templates:

```csharp
logger.Information("User {UserId} logged in at {LoginTime}", userId, DateTime.Now); // Compliant
logger.Information("Error occurred: {ErrorMessage}", errorMessage); // Compliant
```

## Benefits of using message templates

The use of message templates in logging offers several significant advantages over traditional string interpolation or
concatenation methods. Firstly, message templates can provide a notable performance boost, particularly in scenarios where
log messages aren't actually written due to log level settings. This efficiency is crucial in high-volume logging environments
where every millisecond counts.

Structured logging, enabled by message templates, is another key benefit. It allows variables to be captured as separate entities
rather than being merged into a single string. This separation enables powerful log analysis capabilities, making it easier to search,
filter, and aggregate log data based on specific parameters. The ability to maintain consistent log formats across an application
is also greatly enhanced with message templates, leading to more uniform and easily interpretable logs.

Message templates also facilitate semantic logging, allowing developers to attach additional metadata to log events. This extra
context can be invaluable when debugging complex issues or analyzing application behavior. Furthermore, modern logging frameworks such
as Serilog and Microsoft.Extensions.Logging are optimized for template-style logging. By using message templates, developers can
take full advantage of these frameworks' features and performance optimizations, ensuring their logging strategy is future-proof
and aligned with industry best practices.

## More Info

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`.

### Noncompliant Code Examples

```csharp
_logger.LogInformation($"Processing order {orderId}");
_logger.LogError("Error: " + exception.Message);
```

### Compliant Solution

```csharp
_logger.LogInformation("Processing order {OrderId}", orderId);
_logger.LogError("Error: {ErrorMessage}", exception.Message);
```

### Exceptions

This rule doesn't apply to non-logging methods or to logging methods that explicitly expect formatted strings.

## Resources

* [Structured logging with ILogger in .NET](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-5.0#log-message-template)
* [Serilog message templates](https://github.com/serilog/serilog/wiki/Writing-Log-Events#message-templates)
4 changes: 2 additions & 2 deletions src/Agoda.Analyzers/AgodaCustom/AG0041LogTemplateAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class AG0041LogTemplateAnalyzer : DiagnosticAnalyzer
Category,
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
helpLinkUri: "https://github.com/agoda-com/AgodaAnalyzers/issues/183");
helpLinkUri: "https://github.com/agoda-com/AgodaAnalyzers/blob/master/doc/AG0041.md");

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);

Expand Down Expand Up @@ -87,4 +87,4 @@ private static bool ContainsStringConcatenation(ExpressionSyntax expression)
bes.Right.IsKind(SyntaxKind.StringLiteralExpression)));
}
}
}
}

0 comments on commit 44c34b4

Please sign in to comment.