From d84a5e37ac1e9b1139bbfe68fe9741703bfd65a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:46:20 +0000 Subject: [PATCH] docs: reduce README bloat (~52 lines, -11.8%) - Convert IWitness 3-bullet list to inline prose - Condense WitnessedAction outcome bullets to one-line prose - Shorten WitnessedAction IWitness facet intro sentence - Remove duplicate JSON from 'Add custom resource attributes' recipe (already shown in the appsettings.json config reference section) - Condense Analyzer section: remove duplicate 'before' code example (same pattern shown in Logging via extension methods above) and remove the full LoggerMessage pattern (documented in docs/rules/WS0001.md); add link to rule docs instead Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 63 ++++++------------------------------------------------- 1 file changed, 6 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 98dac90..83f817f 100644 --- a/README.md +++ b/README.md @@ -37,29 +37,19 @@ public sealed class OrderService(IWitness witness) ### `IWitness` -`IWitness` is the main thing you inject. It bundles: +`IWitness` is the main injectable — it bundles `ILogger`, `Meter`, and `ActivitySource`. No new abstractions; the underlying .NET types stay visible and accessible. -- `ILogger` for logs -- `Meter` for metrics -- `ActivitySource` for traces - -That shape keeps constructors short and keeps related observability tools together. It also avoids inventing new logging or metrics abstractions. If you already know the built-in .NET types, you already know most of WitnessSharp. - -Most classes only need `IWitness`. If you need a typed witness for a type discovered at runtime, inject `IWitnessFactory` and call `Create()`. +Most classes only need `IWitness`. For witnesses created at runtime, inject `IWitnessFactory` and call `Create()`. ### `WitnessedAction` `WitnessedAction` is a small wrapper around an `Activity`. Start one with `witness.StartAction("Name")`, attach tags or events, and dispose it when the operation ends. -Outcomes are explicit: - -- success is the default -- `Failed(Exception)` or `Failed(string)` marks the action as a failure -- `Cancelled()` marks it as cancelled +Outcomes are explicit: success is the default; `Failed(Exception)` or `Failed(string)` marks failure; `Cancelled()` marks cancellation. `Dispose()` sets the final activity status and closes the activity. `Finish()` is also available when you need to stop early without disposing the wrapper yet. -When started from a typed `IWitness`, the action is itself an `IWitness`. That means the same `IWitness` extension methods you call on a witness (such as logging helpers) can be called directly on the action, keeping a single operation's call site consistent: +When started from a typed `IWitness`, the action is itself an `IWitness`, so extension methods work directly on it: ```csharp public async Task RetrieveSummaryAsync() @@ -307,22 +297,7 @@ See the [Azure Monitor OpenTelemetry exporter docs](https://learn.microsoft.com/
Add custom resource attributes -You can add shared metadata once and have it show up on logs, metrics, and traces. - -```json -{ - "Witness": { - "ServiceName": "orders-api", - "AdditionalResourceAttributes": { - "service.owner": "checkout", - "cloud.region": "westeurope", - "deployment.ring": "blue" - } - } -} -``` - -You can do the same in code if you prefer: +`AdditionalResourceAttributes` adds shared metadata to logs, metrics, and traces. To set it in code: ```csharp builder.Services.AddWitness(options => @@ -370,14 +345,7 @@ public class OrderServiceTests ## Analyzer (`WS0001`) -`WitnessSharp.Analyzers` is an optional Roslyn analyzer package. Its first rule, `WS0001`, flags `witness.Logger.LogInformation(...)`, `witness.Logger.LogWarning(...)`, and `witness.Logger.Log(LogLevel, ...)` calls inside `IWitness` or `IWitness` extension methods such as: - -```csharp -public static void LogOrderPlaced(this IWitness witness, int orderId) => - witness.Logger.LogInformation("Order {OrderId} placed", orderId); -``` - -That pattern is convenient, but hot paths often benefit from the `LoggerMessage` source generator. `WS0001` nudges you toward moving the template into a dedicated generated method, and the package includes a code fix to help with the rewrite. +`WitnessSharp.Analyzers` is an optional Roslyn analyzer package. `WS0001` flags `witness.Logger.Log*(...)` calls inside `IWitness` extension methods and provides a code fix that rewrites them to `[LoggerMessage]` for allocation-free structured logging. See the [WS0001 rule documentation](docs/rules/WS0001.md) for the full fix pattern. ### Install the analyzer @@ -391,25 +359,6 @@ dotnet add package WitnessSharp.Analyzers dotnet_diagnostic.WS0001.severity = warning ``` -### The `LoggerMessage` pattern it promotes - -```csharp -public static partial class OrderLogs -{ - [LoggerMessage( - EventId = 1001, - Level = LogLevel.Information, - Message = "Order {OrderId} placed")] - public static partial void OrderPlaced(this ILogger logger, int orderId); -} - -public static class OrderServiceWitnessExtensions -{ - public static void LogOrderPlaced(this IWitness witness, int orderId) => - witness.Logger.OrderPlaced(orderId); -} -``` - For background on source-generated logging, see the official [`LoggerMessage` docs](https://learn.microsoft.com/en-us/dotnet/core/extensions/logger-message-generator). ## AOT support