https://github.com/blokyk/ca2254-codefix
A codefix for CA2254, to replace interpolated strings with a proper structred-logging friendly message
https://github.com/blokyk/ca2254-codefix
csharp dotnet roslyn roslyn-codefix structured-logging
Last synced: 3 months ago
JSON representation
A codefix for CA2254, to replace interpolated strings with a proper structred-logging friendly message
- Host: GitHub
- URL: https://github.com/blokyk/ca2254-codefix
- Owner: Blokyk
- License: mit
- Created: 2025-04-13T21:24:30.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-04-13T23:25:36.000Z (over 1 year ago)
- Last Synced: 2025-04-15T15:16:24.927Z (over 1 year ago)
- Topics: csharp, dotnet, roslyn, roslyn-codefix, structured-logging
- Language: C#
- Homepage:
- Size: 38.1 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# `Blokyk.CA2254CodeFix`
The CA2254 diagnostic (`Template should be a static expression`) helps you
detect logger messages that could be problematic for structured logging, by
flagging non-constant message templates, i.e. messages that contain expressions
themselves.
Most notably, this includes interpolated strings (`$"hello {user.name}!"`),
which can be pretty annoying to "un-interpolate." This small roslyn codefix aims
to address that! Here's an example:
```cs
// Before codefix, marked with CA2254
logger.LogDebug($"User {user.Username} uploaded {documents.Count} documents!");
// After codefix
logger.LogDebug("User {Username} uploaded {Count} documents!", user.Username, documents.Count);
```
## Installation
This codefix can be installed just like any package using the dotnet CLI:
```sh
dotnet add package Blokyk.CA2254CodeFix
```
You can also reference it in your project:
```xml
```
## Details about the expression names
The expressions in the interpolated string need to be replaced with *something*,
so obviously this codefix is quite opinionated. Here are some examples of
transformations used to derive the names:
| expression | resulting name |
|-----------------------|--------------------|
| `foo.bar` | `Bar` |
| `foo.bar()` | `Bar` |
| `foo.bar(alice, bob)` | `BarOfALiceAndBob` |
| `foo is not null` | `FooIsNotNull` |
| `DateTime.UtcNow` | `DateTime` |
The actual derivation is mostly done in [`ExpressionNamer.cs`](./ExpressionNamer.cs),
with a little bit more in [`CSharpLoggerMessageFixer.cs`](./CSharpLoggerMessageFixer.cs)
right now.
If you'd like to suggest a tweak or a new naming rule, don't hesitate to open a
new issue or PR, I'm completely open to ideas on this!