Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 5 additions & 18 deletions docs/rules/WS0001.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@

## Cause

An extension method on `IWitness<T>` logs through `witness.Logger` using one of the
templated `ILogger` extension methods (`LogTrace`, `LogDebug`, `LogInformation`,
`LogWarning`, `LogError`, `LogCritical`, or `Log`) with a constant message template.
An extension method on `IWitness<T>` calls a templated `ILogger` extension method (`LogTrace`, `LogDebug`, `LogInformation`, `LogWarning`, `LogError`, `LogCritical`, or `Log`) with a constant message template.

```csharp
public static void LogOrderPlaced(this IWitness<OrderService> witness, int orderId)
Expand All @@ -22,22 +20,13 @@ public static void LogOrderPlaced(this IWitness<OrderService> witness, int order

## Rule description

The templated `ILogger` extension methods box value-type arguments and parse the
message template on every call. The source-generated `[LoggerMessage]` pattern avoids
both costs, producing allocation-free, strongly-typed logging.
The templated `ILogger` extension methods box value-type arguments and parse the message template on every call. `[LoggerMessage]` avoids both costs, producing allocation-free, strongly-typed logging.

On **net9.0** and later, WitnessSharp ships a source-generator interceptor that rewrites
these call sites to `[LoggerMessage]`-equivalent code automatically — you do not need to
change anything, and this diagnostic is informational only.

On **net8.0**, no interception occurs. This analyzer surfaces the optimization
opportunity and the accompanying code fix converts the call site to an explicit
`[LoggerMessage]` partial method.
On **net9.0+**, WitnessSharp's source-generator interceptor rewrites these call sites automatically — this diagnostic is informational only. On **net8.0**, no interception occurs; the analyzer surfaces the optimization and the code fix applies it.

## How to fix violations

Apply the **"Convert to [LoggerMessage] pattern"** code fix, or manually extract the log
call into a `[LoggerMessage]` partial method:
Apply the **"Convert to [LoggerMessage] pattern"** code fix, or manually rewrite as a `[LoggerMessage]` partial method:

```csharp
public static partial class OrderServiceLog
Expand All @@ -52,9 +41,7 @@ public static partial class OrderServiceLog

## When to suppress

This rule is informational and safe to suppress when the performance of a particular log
statement is irrelevant (for example, rarely executed startup diagnostics). Suppress it
with:
Suppress when a log statement's performance is irrelevant (e.g., rare startup diagnostics):

```csharp
#pragma warning disable WS0001
Expand Down