feat(auditlog): site script-side emitters stamp ExecutionId
Move the per-script-execution Guid on ScriptRuntimeContext from _auditCorrelationId to _executionId, and stamp it into the dedicated AuditEvent.ExecutionId column on every script-side audit row: - Sync ApiCall / DbWrite: ExecutionId set; CorrelationId reverts to null (a sync one-shot call has no operation lifecycle). - Cached-call script-side rows (CachedSubmit, immediate-completion ApiCallCached + CachedResolve) and NotifySend: ExecutionId set; CorrelationId unchanged (per-operation TrackedOperationId / NotificationId). Renames the threaded ctor param/field across ExternalSystemHelper, DatabaseHelper, AuditingDbConnection and AuditingDbCommand, and threads the id through NotifyHelper/NotifyTarget. The S&F retry-loop cached rows (CachedCallLifecycleBridge) are out of scope here.
This commit is contained in:
@@ -106,19 +106,22 @@ public class ScriptRuntimeContext
|
||||
private readonly ICachedCallTelemetryForwarder? _cachedForwarder;
|
||||
|
||||
/// <summary>
|
||||
/// Audit Log #23: the execution-wide audit correlation id. Every sync
|
||||
/// Audit Log #23: the per-execution id for this script run. Every
|
||||
/// trust-boundary audit row emitted by this script execution
|
||||
/// (<c>ApiCall</c>, <c>DbWrite</c>) is stamped with this id so all the
|
||||
/// rows from one script run can be correlated together.
|
||||
/// (sync <c>ApiCall</c>/<c>DbWrite</c>, cached-call lifecycle rows,
|
||||
/// <c>NotifySend</c>) is stamped into <c>AuditEvent.ExecutionId</c> with
|
||||
/// this value so all the rows from one script run can be correlated
|
||||
/// together — independently of the per-operation
|
||||
/// <c>AuditEvent.CorrelationId</c>.
|
||||
/// </summary>
|
||||
private readonly Guid _auditCorrelationId;
|
||||
private readonly Guid _executionId;
|
||||
|
||||
/// <param name="auditCorrelationId">
|
||||
/// Audit Log #23: the execution-wide audit correlation id. When omitted
|
||||
/// <param name="executionId">
|
||||
/// Audit Log #23: the per-execution id for this script run. When omitted
|
||||
/// (tag-change / timer-triggered executions) a fresh id is generated; an
|
||||
/// inbound caller may supply one to tie the execution to an upstream
|
||||
/// request. Stamped on the sync <c>ApiCall</c>/<c>DbWrite</c> audit rows
|
||||
/// this execution emits.
|
||||
/// request. Stamped into <c>AuditEvent.ExecutionId</c> on every
|
||||
/// trust-boundary audit row this execution emits.
|
||||
/// </param>
|
||||
public ScriptRuntimeContext(
|
||||
IActorRef instanceActor,
|
||||
@@ -138,7 +141,7 @@ public class ScriptRuntimeContext
|
||||
IAuditWriter? auditWriter = null,
|
||||
IOperationTrackingStore? operationTrackingStore = null,
|
||||
ICachedCallTelemetryForwarder? cachedForwarder = null,
|
||||
Guid? auditCorrelationId = null)
|
||||
Guid? executionId = null)
|
||||
{
|
||||
_instanceActor = instanceActor;
|
||||
_self = self;
|
||||
@@ -157,7 +160,7 @@ public class ScriptRuntimeContext
|
||||
_auditWriter = auditWriter;
|
||||
_operationTrackingStore = operationTrackingStore;
|
||||
_cachedForwarder = cachedForwarder;
|
||||
_auditCorrelationId = auditCorrelationId ?? Guid.NewGuid();
|
||||
_executionId = executionId ?? Guid.NewGuid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -258,7 +261,7 @@ public class ScriptRuntimeContext
|
||||
/// ExternalSystem.CachedCall("systemName", "methodName", params)
|
||||
/// </summary>
|
||||
public ExternalSystemHelper ExternalSystem => new(
|
||||
_externalSystemClient, _instanceName, _logger, _auditCorrelationId, _auditWriter, _siteId, _sourceScript,
|
||||
_externalSystemClient, _instanceName, _logger, _executionId, _auditWriter, _siteId, _sourceScript,
|
||||
// Audit Log #23 (M3 Bundle E — Task E3): emit CachedSubmit telemetry
|
||||
// on every ExternalSystem.CachedCall enqueue.
|
||||
_cachedForwarder);
|
||||
@@ -272,7 +275,7 @@ public class ScriptRuntimeContext
|
||||
_databaseGateway,
|
||||
_instanceName,
|
||||
_logger,
|
||||
_auditCorrelationId,
|
||||
_executionId,
|
||||
// Audit Log #23 (M4 Bundle A): wire the IAuditWriter so
|
||||
// Database.Connection(name) returns an auditing decorator that
|
||||
// emits one DbOutbound/DbWrite row per script-initiated
|
||||
@@ -299,7 +302,7 @@ public class ScriptRuntimeContext
|
||||
/// </remarks>
|
||||
public NotifyHelper Notify => new(
|
||||
_storeAndForward, _siteCommunicationActor, _siteId, _instanceName, _sourceScript, _askTimeout, _logger,
|
||||
_auditWriter);
|
||||
_executionId, _auditWriter);
|
||||
|
||||
/// <summary>
|
||||
/// Audit Log #23 (M3): site-local tracking-status API for cached operations.
|
||||
@@ -380,7 +383,7 @@ public class ScriptRuntimeContext
|
||||
private readonly IExternalSystemClient? _client;
|
||||
private readonly string _instanceName;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Guid _auditCorrelationId;
|
||||
private readonly Guid _executionId;
|
||||
private readonly IAuditWriter? _auditWriter;
|
||||
private readonly string _siteId;
|
||||
private readonly string? _sourceScript;
|
||||
@@ -390,7 +393,7 @@ public class ScriptRuntimeContext
|
||||
// (via InternalsVisibleTo). Production sites resolve the helper through
|
||||
// ScriptRuntimeContext.ExternalSystem.
|
||||
//
|
||||
// Parameter ordering: auditCorrelationId sits immediately after the
|
||||
// Parameter ordering: executionId sits immediately after the
|
||||
// ILogger across all four audit-threaded ctors (ExternalSystemHelper,
|
||||
// DatabaseHelper, AuditingDbConnection, AuditingDbCommand) — a required
|
||||
// Guid cannot follow the optional provenance params without a
|
||||
@@ -400,7 +403,7 @@ public class ScriptRuntimeContext
|
||||
IExternalSystemClient? client,
|
||||
string instanceName,
|
||||
ILogger logger,
|
||||
Guid auditCorrelationId,
|
||||
Guid executionId,
|
||||
IAuditWriter? auditWriter = null,
|
||||
string siteId = "",
|
||||
string? sourceScript = null,
|
||||
@@ -409,7 +412,7 @@ public class ScriptRuntimeContext
|
||||
_client = client;
|
||||
_instanceName = instanceName;
|
||||
_logger = logger;
|
||||
_auditCorrelationId = auditCorrelationId;
|
||||
_executionId = executionId;
|
||||
_auditWriter = auditWriter;
|
||||
_siteId = siteId;
|
||||
_sourceScript = sourceScript;
|
||||
@@ -567,7 +570,11 @@ public class ScriptRuntimeContext
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.ApiOutbound,
|
||||
Kind = AuditKind.CachedSubmit,
|
||||
// CorrelationId stays the per-operation lifecycle id
|
||||
// (TrackedOperationId); ExecutionId carries the
|
||||
// per-execution id shared across this script run.
|
||||
CorrelationId = trackedId.Value,
|
||||
ExecutionId = _executionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
@@ -677,7 +684,10 @@ public class ScriptRuntimeContext
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.ApiOutbound,
|
||||
Kind = AuditKind.ApiCallCached,
|
||||
// CorrelationId = per-operation lifecycle id;
|
||||
// ExecutionId = per-execution id for this script run.
|
||||
CorrelationId = trackedId.Value,
|
||||
ExecutionId = _executionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
@@ -738,7 +748,10 @@ public class ScriptRuntimeContext
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.ApiOutbound,
|
||||
Kind = AuditKind.CachedResolve,
|
||||
// CorrelationId = per-operation lifecycle id;
|
||||
// ExecutionId = per-execution id for this script run.
|
||||
CorrelationId = trackedId.Value,
|
||||
ExecutionId = _executionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
@@ -910,9 +923,12 @@ public class ScriptRuntimeContext
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.ApiOutbound,
|
||||
Kind = AuditKind.ApiCall,
|
||||
// Audit Log #23: the execution-wide correlation id, so all the
|
||||
// sync ApiCall/DbWrite rows from one script run share an id.
|
||||
CorrelationId = _auditCorrelationId,
|
||||
// Audit Log #23: a sync one-shot call has no operation
|
||||
// lifecycle, so CorrelationId is null. ExecutionId carries the
|
||||
// per-execution id so all the sync ApiCall/DbWrite rows from
|
||||
// one script run can be correlated together.
|
||||
CorrelationId = null,
|
||||
ExecutionId = _executionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
@@ -979,7 +995,7 @@ public class ScriptRuntimeContext
|
||||
private readonly IDatabaseGateway? _gateway;
|
||||
private readonly string _instanceName;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Guid _auditCorrelationId;
|
||||
private readonly Guid _executionId;
|
||||
private readonly string _siteId;
|
||||
private readonly string? _sourceScript;
|
||||
private readonly ICachedCallTelemetryForwarder? _cachedForwarder;
|
||||
@@ -996,7 +1012,7 @@ public class ScriptRuntimeContext
|
||||
/// </summary>
|
||||
private readonly IAuditWriter? _auditWriter;
|
||||
|
||||
// Parameter ordering: auditCorrelationId sits immediately after the
|
||||
// Parameter ordering: executionId sits immediately after the
|
||||
// ILogger — see the note on ExternalSystemHelper's ctor for why the
|
||||
// post-logger slot is the one consistent position across all four
|
||||
// audit-threaded ctors.
|
||||
@@ -1004,7 +1020,7 @@ public class ScriptRuntimeContext
|
||||
IDatabaseGateway? gateway,
|
||||
string instanceName,
|
||||
ILogger logger,
|
||||
Guid auditCorrelationId,
|
||||
Guid executionId,
|
||||
IAuditWriter? auditWriter = null,
|
||||
string siteId = "",
|
||||
string? sourceScript = null,
|
||||
@@ -1013,7 +1029,7 @@ public class ScriptRuntimeContext
|
||||
_gateway = gateway;
|
||||
_instanceName = instanceName;
|
||||
_logger = logger;
|
||||
_auditCorrelationId = auditCorrelationId;
|
||||
_executionId = executionId;
|
||||
_auditWriter = auditWriter;
|
||||
_siteId = siteId;
|
||||
_sourceScript = sourceScript;
|
||||
@@ -1049,7 +1065,7 @@ public class ScriptRuntimeContext
|
||||
instanceName: _instanceName,
|
||||
sourceScript: _sourceScript,
|
||||
logger: _logger,
|
||||
auditCorrelationId: _auditCorrelationId);
|
||||
executionId: _executionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1116,7 +1132,10 @@ public class ScriptRuntimeContext
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.DbOutbound,
|
||||
Kind = AuditKind.CachedSubmit,
|
||||
// CorrelationId = per-operation lifecycle id
|
||||
// (TrackedOperationId); ExecutionId = per-execution id.
|
||||
CorrelationId = trackedId.Value,
|
||||
ExecutionId = _executionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
@@ -1178,6 +1197,12 @@ public class ScriptRuntimeContext
|
||||
private readonly TimeSpan _askTimeout;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Audit Log #23: the per-execution id for this script run, stamped
|
||||
/// into <c>AuditEvent.ExecutionId</c> on the <c>NotifySend</c> row.
|
||||
/// </summary>
|
||||
private readonly Guid _executionId;
|
||||
|
||||
/// <summary>
|
||||
/// Audit Log #23 (M4 Bundle C): best-effort emitter for the
|
||||
/// <c>Notification</c>/<c>NotifySend</c> row produced when the script
|
||||
@@ -1188,6 +1213,8 @@ public class ScriptRuntimeContext
|
||||
/// </summary>
|
||||
private readonly IAuditWriter? _auditWriter;
|
||||
|
||||
// Parameter ordering: executionId sits immediately after the ILogger,
|
||||
// consistent with the other audit-threaded ctors.
|
||||
internal NotifyHelper(
|
||||
StoreAndForwardService? storeAndForward,
|
||||
ICanTell? siteCommunicationActor,
|
||||
@@ -1196,6 +1223,7 @@ public class ScriptRuntimeContext
|
||||
string? sourceScript,
|
||||
TimeSpan askTimeout,
|
||||
ILogger logger,
|
||||
Guid executionId,
|
||||
IAuditWriter? auditWriter = null)
|
||||
{
|
||||
_storeAndForward = storeAndForward;
|
||||
@@ -1205,6 +1233,7 @@ public class ScriptRuntimeContext
|
||||
_sourceScript = sourceScript;
|
||||
_askTimeout = askTimeout;
|
||||
_logger = logger;
|
||||
_executionId = executionId;
|
||||
_auditWriter = auditWriter;
|
||||
}
|
||||
|
||||
@@ -1215,6 +1244,9 @@ public class ScriptRuntimeContext
|
||||
{
|
||||
return new NotifyTarget(
|
||||
listName, _storeAndForward, _siteId, _instanceName, _sourceScript, _logger,
|
||||
// Audit Log #23: the per-execution id stamped into the
|
||||
// NotifySend row's ExecutionId column.
|
||||
_executionId,
|
||||
// Audit Log #23 (M4 Bundle C): forward the writer so Send()
|
||||
// can emit one NotifySend(Submitted) row per accepted submission.
|
||||
_auditWriter);
|
||||
@@ -1292,6 +1324,12 @@ public class ScriptRuntimeContext
|
||||
private readonly string? _sourceScript;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Audit Log #23: the per-execution id for this script run, stamped
|
||||
/// into <c>AuditEvent.ExecutionId</c> on the <c>NotifySend</c> row.
|
||||
/// </summary>
|
||||
private readonly Guid _executionId;
|
||||
|
||||
/// <summary>
|
||||
/// Audit Log #23 (M4 Bundle C): best-effort emitter for the
|
||||
/// <c>Notification</c>/<c>NotifySend</c> row written immediately after
|
||||
@@ -1307,6 +1345,7 @@ public class ScriptRuntimeContext
|
||||
string instanceName,
|
||||
string? sourceScript,
|
||||
ILogger logger,
|
||||
Guid executionId,
|
||||
IAuditWriter? auditWriter = null)
|
||||
{
|
||||
_listName = listName;
|
||||
@@ -1315,6 +1354,7 @@ public class ScriptRuntimeContext
|
||||
_instanceName = instanceName;
|
||||
_sourceScript = sourceScript;
|
||||
_logger = logger;
|
||||
_executionId = executionId;
|
||||
_auditWriter = auditWriter;
|
||||
}
|
||||
|
||||
@@ -1431,7 +1471,10 @@ public class ScriptRuntimeContext
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.Notification,
|
||||
Kind = AuditKind.NotifySend,
|
||||
// CorrelationId is the NotificationId-derived per-operation
|
||||
// lifecycle id; ExecutionId carries the per-execution id.
|
||||
CorrelationId = correlationId,
|
||||
ExecutionId = _executionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
|
||||
Reference in New Issue
Block a user