feat(auditlog): inbound audit rows carry ExecutionId
This commit is contained in:
@@ -145,17 +145,21 @@ public sealed class AuditWriteMiddleware
|
|||||||
OccurredAtUtc = DateTime.UtcNow,
|
OccurredAtUtc = DateTime.UtcNow,
|
||||||
Channel = AuditChannel.ApiInbound,
|
Channel = AuditChannel.ApiInbound,
|
||||||
Kind = kind,
|
Kind = kind,
|
||||||
// Audit Log #23: a fresh per-request correlation id so the
|
// Audit Log #23: a fresh per-request execution id so the
|
||||||
// inbound row carries a request identifier (closes the design
|
// inbound row carries a request identifier (closes the design
|
||||||
// gap that inbound rows should be correlatable).
|
// gap that inbound rows should be correlatable).
|
||||||
//
|
//
|
||||||
// This id is intentionally request-local: it is NOT bridged to
|
// This id is intentionally request-local: it is NOT bridged to
|
||||||
// RouteHelper's routed-call correlation id or to
|
// RouteHelper's routed-call correlation id or to
|
||||||
// HttpContext.TraceIdentifier. Threading an inbound request's
|
// HttpContext.TraceIdentifier. Threading an inbound request's
|
||||||
// correlation id through to the routed script execution (so an
|
// execution id through to the routed script execution (so an
|
||||||
// inbound call and the outbound API/DB rows it triggers share
|
// inbound call and the outbound API/DB rows it triggers share
|
||||||
// one id) is a deliberate future follow-up, out of scope here.
|
// one id) is a deliberate future follow-up, out of scope here.
|
||||||
CorrelationId = Guid.NewGuid(),
|
ExecutionId = Guid.NewGuid(),
|
||||||
|
// CorrelationId is purely the per-operation-lifecycle id; an
|
||||||
|
// inbound request is a one-shot from the audit row's
|
||||||
|
// perspective with no multi-row operation to correlate.
|
||||||
|
CorrelationId = null,
|
||||||
Actor = actor,
|
Actor = actor,
|
||||||
Target = methodName,
|
Target = methodName,
|
||||||
Status = status,
|
Status = status,
|
||||||
|
|||||||
@@ -351,12 +351,14 @@ public class AuditWriteMiddlewareTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Correlation id — Audit Log #23: each inbound row carries a fresh
|
// Execution id — Audit Log #23: each inbound row carries a fresh
|
||||||
// per-request correlation id so inbound rows are correlatable.
|
// per-request execution id so inbound rows are correlatable. The inbound
|
||||||
|
// row's CorrelationId stays null — CorrelationId is purely the
|
||||||
|
// per-operation-lifecycle id and an inbound request is a one-shot.
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task InboundRow_CarriesNonNull_CorrelationId()
|
public async Task InboundRow_CarriesNonNull_ExecutionId_And_NullCorrelationId()
|
||||||
{
|
{
|
||||||
var writer = new RecordingAuditWriter();
|
var writer = new RecordingAuditWriter();
|
||||||
var ctx = BuildContext();
|
var ctx = BuildContext();
|
||||||
@@ -369,12 +371,15 @@ public class AuditWriteMiddlewareTests
|
|||||||
await mw.InvokeAsync(ctx);
|
await mw.InvokeAsync(ctx);
|
||||||
|
|
||||||
var evt = Assert.Single(writer.Events);
|
var evt = Assert.Single(writer.Events);
|
||||||
Assert.NotNull(evt.CorrelationId);
|
Assert.NotNull(evt.ExecutionId);
|
||||||
Assert.NotEqual(Guid.Empty, evt.CorrelationId!.Value);
|
Assert.NotEqual(Guid.Empty, evt.ExecutionId!.Value);
|
||||||
|
// CorrelationId is the per-operation-lifecycle id; an inbound request
|
||||||
|
// is a one-shot with no multi-row operation to correlate.
|
||||||
|
Assert.Null(evt.CorrelationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task SeparateRequests_GetDistinct_CorrelationIds()
|
public async Task SeparateRequests_GetDistinct_ExecutionIds()
|
||||||
{
|
{
|
||||||
var writer = new RecordingAuditWriter();
|
var writer = new RecordingAuditWriter();
|
||||||
var mw = CreateMiddleware(hc =>
|
var mw = CreateMiddleware(hc =>
|
||||||
@@ -387,7 +392,7 @@ public class AuditWriteMiddlewareTests
|
|||||||
await mw.InvokeAsync(BuildContext());
|
await mw.InvokeAsync(BuildContext());
|
||||||
|
|
||||||
Assert.Equal(2, writer.Events.Count);
|
Assert.Equal(2, writer.Events.Count);
|
||||||
Assert.NotEqual(writer.Events[0].CorrelationId, writer.Events[1].CorrelationId);
|
Assert.NotEqual(writer.Events[0].ExecutionId, writer.Events[1].ExecutionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
Reference in New Issue
Block a user