Skip to content

Commit 95f724e

Browse files
authored
Merge pull request #235 from Vulthil/feature/outbox-telemetry-rename
Outbox telemetry: rename ActivitySource + auto-register when tracing is enabled
2 parents 34f2ed2 + ccbee42 commit 95f724e

8 files changed

Lines changed: 51 additions & 4 deletions

docs/articles/outbox-pattern.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
6666
| `MaxDelaySeconds` | 60 | Maximum back-off delay when no messages are found |
6767
| `EnableTracing` | `true` | Carry the originating trace identifier when publishing |
6868

69+
## Observability
70+
71+
The relay emits an `ActivitySource` named `"Vulthil.SharedKernel.Outbox"` (exposed as `Telemetry.ActivitySourceName`). When `EnableTracing` is on (the default), each relayed message starts an `OutboxPublishing` span parented on the trace that captured the row — the originating trace is carried forward through the `OutboxMessage.TraceParent`/`TraceState` columns stamped at capture — so the relay, which runs later on its own background service, still correlates back to the request that produced the message.
72+
73+
`AddOutboxEngine` (called by `EnableOutboxProcessing`) registers the source with OpenTelemetry automatically when `EnableTracing` is on (the default), so the spans reach whatever tracer the application has configured without extra wiring. If you build a `TracerProviderBuilder` yourself, the same registration is available as `tracing.AddVulthilOutboxInstrumentation()` — sugar for `AddSource(Telemetry.ActivitySourceName)`.
74+
6975
## Custom Outbox Store
7076

7177
The relay engine talks to the database through an EF-free `IOutboxStore` (in `Vulthil.SharedKernel.Outbox`). The EF

docs/articles/packages/vulthil-sharedkernel-outbox.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ seam. It has **no EF Core dependency**; the EF implementation lives in
2020
- The engine relies on `IOutboxStore` for both capture (`AddOutboxMessage`/`SaveChangesAsync`/`IsInTransaction`) and
2121
the relay batch unit (`ProcessBatchAsync`); the EF implementation and provider stores supply the transaction and
2222
row-locking. `AddOutboxEngine` registers the engine's own internals.
23+
- Relay spans are emitted on the `ActivitySource` `"Vulthil.SharedKernel.Outbox"` (`Telemetry.ActivitySourceName`),
24+
auto-registered with OpenTelemetry by `AddOutboxEngine` (manual: `tracing.AddVulthilOutboxInstrumentation()`).
2325

2426
See the [Outbox Pattern](https://github.com/Vulthil/Vulthil.SharedKernel/tree/main/docs/articles/outbox-pattern.md)
2527
article for the design, the pluggable-sink model, and the commit-time trigger.

src/Vulthil.SharedKernel.Outbox/OutboxEngineServiceCollectionExtensions.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ public static IServiceCollection AddOutboxEngine(
3636
.ValidateDataAnnotations()
3737
.ValidateOnStart();
3838

39+
if (IsTracingEnabled(configureOptions))
40+
{
41+
services
42+
.AddOpenTelemetry()
43+
.WithTracing(tracing => tracing.AddVulthilOutboxInstrumentation());
44+
}
45+
3946
services.TryAddSingleton(TimeProvider.System);
4047
services.TryAddSingleton<IOutboxSignal, OutboxSignal>();
4148

@@ -46,4 +53,11 @@ public static IServiceCollection AddOutboxEngine(
4653

4754
return services;
4855
}
56+
57+
private static bool IsTracingEnabled(Action<OutboxProcessingOptions>? configureOptions)
58+
{
59+
var options = new OutboxProcessingOptions();
60+
configureOptions?.Invoke(options);
61+
return options.EnableTracing;
62+
}
4963
}

src/Vulthil.SharedKernel.Outbox/OutboxProcessingOptions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ public sealed class OutboxProcessingOptions
4141
public int MaxDegreeOfParallelism { get; init; } = 4;
4242

4343
/// <summary>
44-
/// Gets a value indicating whether Trace Identifiers should be included when publishing outbox messages.
44+
/// Gets or sets a value indicating whether Trace Identifiers should be included when publishing outbox messages.
4545
/// <br />
4646
/// This allows the originating action that persisted the outbox message to act as an owner for the resulting scope,
4747
/// even after the outbox delay
4848
/// <br/>
4949
/// Default: <see langword="true"/>
5050
/// </summary>
51-
public bool EnableTracing { get; init; } = true;
51+
public bool EnableTracing { get; set; } = true;
5252
}

src/Vulthil.SharedKernel.Outbox/OutboxProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public static class Telemetry
6868
/// <summary>
6969
/// ActivitySourceName for all outbox processing operations, allowing correlation of events across the capture, processing, and publishing stages.
7070
/// </summary>
71-
public static readonly string ActivitySourceName = "Vulthil.SharedKernel.Infrastructure";
71+
public static readonly string ActivitySourceName = "Vulthil.SharedKernel.Outbox";
7272
/// <summary>
7373
/// ActivitySource for all outbox processing operations, allowing correlation of events across the capture, processing, and publishing stages.
7474
/// </summary>

src/Vulthil.SharedKernel.Outbox/PublicAPI.Unshipped.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ static Vulthil.SharedKernel.Outbox.OutboxMessageData.operator !=(Vulthil.SharedK
77
static Vulthil.SharedKernel.Outbox.OutboxMessageData.operator ==(Vulthil.SharedKernel.Outbox.OutboxMessageData left, Vulthil.SharedKernel.Outbox.OutboxMessageData right) -> bool
88
static Vulthil.SharedKernel.Outbox.OutboxMessageFailure.operator !=(Vulthil.SharedKernel.Outbox.OutboxMessageFailure left, Vulthil.SharedKernel.Outbox.OutboxMessageFailure right) -> bool
99
static Vulthil.SharedKernel.Outbox.OutboxMessageFailure.operator ==(Vulthil.SharedKernel.Outbox.OutboxMessageFailure left, Vulthil.SharedKernel.Outbox.OutboxMessageFailure right) -> bool
10+
static Vulthil.SharedKernel.Outbox.TracerProviderBuilderExtensions.AddVulthilOutboxInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder!
1011
Vulthil.SharedKernel.Outbox.IOutboxDispatcher
1112
Vulthil.SharedKernel.Outbox.IOutboxDispatcher.DispatchAsync(Vulthil.SharedKernel.Outbox.OutboxMessageData message, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task!
1213
Vulthil.SharedKernel.Outbox.IOutboxDispatcher.Handles(Vulthil.SharedKernel.Outbox.OutboxDestination destination) -> bool
@@ -87,7 +88,7 @@ Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.BatchSize.init -> void
8788
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.EnableParallelPublishing.get -> bool
8889
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.EnableParallelPublishing.init -> void
8990
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.EnableTracing.get -> bool
90-
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.EnableTracing.init -> void
91+
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.EnableTracing.set -> void
9192
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.MaxDegreeOfParallelism.get -> int
9293
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.MaxDegreeOfParallelism.init -> void
9394
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.MaxDelaySeconds.get -> int
@@ -98,6 +99,7 @@ Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.OutboxProcessingDelayInSecon
9899
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.OutboxProcessingDelayInSeconds.init -> void
99100
Vulthil.SharedKernel.Outbox.OutboxProcessingOptions.OutboxProcessingOptions() -> void
100101
Vulthil.SharedKernel.Outbox.Telemetry
102+
Vulthil.SharedKernel.Outbox.TracerProviderBuilderExtensions
101103
~override Vulthil.SharedKernel.Outbox.OutboxMessageData.Equals(object obj) -> bool
102104
~override Vulthil.SharedKernel.Outbox.OutboxMessageData.ToString() -> string
103105
~override Vulthil.SharedKernel.Outbox.OutboxMessageFailure.Equals(object obj) -> bool
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using OpenTelemetry.Trace;
2+
3+
namespace Vulthil.SharedKernel.Outbox;
4+
5+
/// <summary>
6+
/// OpenTelemetry registration helpers for the Vulthil outbox processing telemetry.
7+
/// </summary>
8+
public static class TracerProviderBuilderExtensions
9+
{
10+
/// <summary>
11+
/// Subscribes the tracer provider to the <see cref="System.Diagnostics.ActivitySource"/> emitted by the outbox
12+
/// relay (the <c>OutboxPublishing</c> spans), so outbox processing is collected without hard-coding the source name.
13+
/// </summary>
14+
/// <param name="builder">The tracer provider builder.</param>
15+
/// <returns>The same builder, for chaining.</returns>
16+
public static TracerProviderBuilder AddVulthilOutboxInstrumentation(this TracerProviderBuilder builder)
17+
{
18+
ArgumentNullException.ThrowIfNull(builder);
19+
return builder.AddSource(Telemetry.ActivitySourceName);
20+
}
21+
}

src/Vulthil.SharedKernel.Outbox/Vulthil.SharedKernel.Outbox.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
<ItemGroup>
88
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
99
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" />
10+
<PackageReference Include="OpenTelemetry.Api" />
11+
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
1012
</ItemGroup>
1113

1214
<ItemGroup>

0 commit comments

Comments
 (0)