feat(audit)!: ScadaBridge C3 — swap to canonical ZB.MOM.WW.Audit.AuditEvent across seams/emitters/DTO/redactor wiring; transitional 24-col storage shim (Task 2.5)
This commit is contained in:
@@ -2,9 +2,10 @@ using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
||||
using AuditEvent = ZB.MOM.WW.Audit.AuditEvent;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
|
||||
|
||||
@@ -473,40 +474,36 @@ internal sealed class AuditingDbCommand : DbCommand
|
||||
? $"{{\"op\":\"write\",\"rowsAffected\":{(rowsAffected ?? 0)}}}"
|
||||
: $"{{\"op\":\"read\",\"rowsReturned\":{(rowsReturned ?? 0)}}}";
|
||||
|
||||
return new AuditEvent
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.DbOutbound,
|
||||
Kind = AuditKind.DbWrite,
|
||||
return ScadaBridgeAuditEventFactory.Create(
|
||||
channel: AuditChannel.DbOutbound,
|
||||
kind: AuditKind.DbWrite,
|
||||
status: status,
|
||||
occurredAtUtc: DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
// Outbound channel: per the Audit Log Actor-column spec the actor is
|
||||
// the calling script. Null when no single script owns the call
|
||||
// (e.g. a shared script running inline).
|
||||
actor: _sourceScript,
|
||||
target: target,
|
||||
// Audit Log #23: a sync one-shot DB write has no operation
|
||||
// lifecycle, so CorrelationId is null. ExecutionId carries the
|
||||
// per-execution id so this row shares an id with the other sync
|
||||
// trust-boundary rows from the same script run.
|
||||
CorrelationId = null,
|
||||
ExecutionId = _executionId,
|
||||
correlationId: null,
|
||||
executionId: _executionId,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning execution's id;
|
||||
// null for non-routed runs.
|
||||
ParentExecutionId = _parentExecutionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
// Outbound channel: per the Audit Log Actor-column spec the actor is
|
||||
// the calling script. Null when no single script owns the call
|
||||
// (e.g. a shared script running inline).
|
||||
Actor = _sourceScript,
|
||||
Target = target,
|
||||
Status = status,
|
||||
HttpStatus = null,
|
||||
DurationMs = durationMs,
|
||||
ErrorMessage = thrown?.Message,
|
||||
ErrorDetail = thrown?.ToString(),
|
||||
RequestSummary = requestSummary,
|
||||
ResponseSummary = null,
|
||||
PayloadTruncated = false,
|
||||
Extra = extra,
|
||||
ForwardState = AuditForwardState.Pending,
|
||||
};
|
||||
parentExecutionId: _parentExecutionId,
|
||||
sourceSiteId: string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
sourceInstanceId: _instanceName,
|
||||
sourceScript: _sourceScript,
|
||||
httpStatus: null,
|
||||
durationMs: durationMs,
|
||||
errorMessage: thrown?.Message,
|
||||
errorDetail: thrown?.ToString(),
|
||||
requestSummary: requestSummary,
|
||||
responseSummary: null,
|
||||
payloadTruncated: false,
|
||||
extra: extra);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using Akka.Actor;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Instance;
|
||||
@@ -11,7 +10,9 @@ using ZB.MOM.WW.ScadaBridge.Commons.Messages.Integration;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Notification;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Messages.ScriptExecution;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
||||
using AuditEvent = ZB.MOM.WW.Audit.AuditEvent;
|
||||
using ZB.MOM.WW.ScadaBridge.StoreAndForward;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
|
||||
@@ -735,29 +736,25 @@ public class ScriptRuntimeContext
|
||||
try
|
||||
{
|
||||
telemetry = new CachedCallTelemetry(
|
||||
Audit: new AuditEvent
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.ApiOutbound,
|
||||
Kind = AuditKind.CachedSubmit,
|
||||
Audit: ScadaBridgeAuditEventFactory.Create(
|
||||
channel: AuditChannel.ApiOutbound,
|
||||
kind: AuditKind.CachedSubmit,
|
||||
status: AuditStatus.Submitted,
|
||||
occurredAtUtc: DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
target: target,
|
||||
// CorrelationId stays the per-operation lifecycle id
|
||||
// (TrackedOperationId); ExecutionId carries the
|
||||
// per-execution id shared across this script run.
|
||||
CorrelationId = trackedId.Value,
|
||||
ExecutionId = _executionId,
|
||||
correlationId: trackedId.Value,
|
||||
executionId: _executionId,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning
|
||||
// execution's id; null for non-routed runs.
|
||||
ParentExecutionId = _parentExecutionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
Target = target,
|
||||
Status = AuditStatus.Submitted,
|
||||
parentExecutionId: _parentExecutionId,
|
||||
sourceSiteId: string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
sourceInstanceId: _instanceName,
|
||||
sourceScript: _sourceScript,
|
||||
// Submit precedes the call — request args only, no response yet.
|
||||
RequestSummary = SerializeRequest(parameters),
|
||||
ForwardState = AuditForwardState.Pending,
|
||||
},
|
||||
requestSummary: SerializeRequest(parameters)),
|
||||
Operational: new SiteCallOperational(
|
||||
TrackedOperationId: trackedId,
|
||||
Channel: "ApiOutbound",
|
||||
@@ -857,30 +854,26 @@ public class ScriptRuntimeContext
|
||||
try
|
||||
{
|
||||
attempted = new CachedCallTelemetry(
|
||||
Audit: new AuditEvent
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.ApiOutbound,
|
||||
Kind = AuditKind.ApiCallCached,
|
||||
Audit: ScadaBridgeAuditEventFactory.Create(
|
||||
channel: AuditChannel.ApiOutbound,
|
||||
kind: AuditKind.ApiCallCached,
|
||||
status: AuditStatus.Attempted,
|
||||
occurredAtUtc: DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
target: target,
|
||||
// CorrelationId = per-operation lifecycle id;
|
||||
// ExecutionId = per-execution id for this script run.
|
||||
CorrelationId = trackedId.Value,
|
||||
ExecutionId = _executionId,
|
||||
correlationId: trackedId.Value,
|
||||
executionId: _executionId,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning
|
||||
// execution's id; null for non-routed runs.
|
||||
ParentExecutionId = _parentExecutionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
Target = target,
|
||||
Status = AuditStatus.Attempted,
|
||||
HttpStatus = httpStatus,
|
||||
ErrorMessage = result.Success ? null : result.ErrorMessage,
|
||||
RequestSummary = SerializeRequest(parameters),
|
||||
ResponseSummary = result.ResponseJson,
|
||||
ForwardState = AuditForwardState.Pending,
|
||||
},
|
||||
parentExecutionId: _parentExecutionId,
|
||||
sourceSiteId: string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
sourceInstanceId: _instanceName,
|
||||
sourceScript: _sourceScript,
|
||||
httpStatus: httpStatus,
|
||||
errorMessage: result.Success ? null : result.ErrorMessage,
|
||||
requestSummary: SerializeRequest(parameters),
|
||||
responseSummary: result.ResponseJson),
|
||||
Operational: new SiteCallOperational(
|
||||
TrackedOperationId: trackedId,
|
||||
Channel: "ApiOutbound",
|
||||
@@ -929,30 +922,26 @@ public class ScriptRuntimeContext
|
||||
try
|
||||
{
|
||||
resolve = new CachedCallTelemetry(
|
||||
Audit: new AuditEvent
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.ApiOutbound,
|
||||
Kind = AuditKind.CachedResolve,
|
||||
Audit: ScadaBridgeAuditEventFactory.Create(
|
||||
channel: AuditChannel.ApiOutbound,
|
||||
kind: AuditKind.CachedResolve,
|
||||
status: auditTerminalStatus,
|
||||
occurredAtUtc: DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
target: target,
|
||||
// CorrelationId = per-operation lifecycle id;
|
||||
// ExecutionId = per-execution id for this script run.
|
||||
CorrelationId = trackedId.Value,
|
||||
ExecutionId = _executionId,
|
||||
correlationId: trackedId.Value,
|
||||
executionId: _executionId,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning
|
||||
// execution's id; null for non-routed runs.
|
||||
ParentExecutionId = _parentExecutionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
Target = target,
|
||||
Status = auditTerminalStatus,
|
||||
HttpStatus = httpStatus,
|
||||
ErrorMessage = result.Success ? null : result.ErrorMessage,
|
||||
RequestSummary = SerializeRequest(parameters),
|
||||
ResponseSummary = result.ResponseJson,
|
||||
ForwardState = AuditForwardState.Pending,
|
||||
},
|
||||
parentExecutionId: _parentExecutionId,
|
||||
sourceSiteId: string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
sourceInstanceId: _instanceName,
|
||||
sourceScript: _sourceScript,
|
||||
httpStatus: httpStatus,
|
||||
errorMessage: result.Success ? null : result.ErrorMessage,
|
||||
requestSummary: SerializeRequest(parameters),
|
||||
responseSummary: result.ResponseJson),
|
||||
Operational: new SiteCallOperational(
|
||||
TrackedOperationId: trackedId,
|
||||
Channel: "ApiOutbound",
|
||||
@@ -1112,44 +1101,40 @@ public class ScriptRuntimeContext
|
||||
}
|
||||
}
|
||||
|
||||
return new AuditEvent
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.ApiOutbound,
|
||||
Kind = AuditKind.ApiCall,
|
||||
return ScadaBridgeAuditEventFactory.Create(
|
||||
channel: AuditChannel.ApiOutbound,
|
||||
kind: AuditKind.ApiCall,
|
||||
status: status,
|
||||
occurredAtUtc: DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
// Outbound channel: per the Audit Log Actor-column spec the actor
|
||||
// is the calling script. Null when no single script owns the call
|
||||
// (e.g. a shared script running inline).
|
||||
actor: _sourceScript,
|
||||
target: $"{systemName}.{methodName}",
|
||||
// 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,
|
||||
correlationId: null,
|
||||
executionId: _executionId,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning execution's
|
||||
// id; null for non-routed runs.
|
||||
ParentExecutionId = _parentExecutionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
// Outbound channel: per the Audit Log Actor-column spec the actor
|
||||
// is the calling script. Null when no single script owns the call
|
||||
// (e.g. a shared script running inline).
|
||||
Actor = _sourceScript,
|
||||
Target = $"{systemName}.{methodName}",
|
||||
Status = status,
|
||||
HttpStatus = httpStatus,
|
||||
DurationMs = durationMs,
|
||||
ErrorMessage = errorMessage,
|
||||
ErrorDetail = errorDetail,
|
||||
parentExecutionId: _parentExecutionId,
|
||||
sourceSiteId: string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
sourceInstanceId: _instanceName,
|
||||
sourceScript: _sourceScript,
|
||||
httpStatus: httpStatus,
|
||||
durationMs: durationMs,
|
||||
errorMessage: errorMessage,
|
||||
errorDetail: errorDetail,
|
||||
// Payload capture: the request arguments and the response body.
|
||||
// The audit writer's payload filter applies the configured size
|
||||
// cap and header/secret redaction downstream — the emitter just
|
||||
// hands over the raw values.
|
||||
RequestSummary = SerializeRequest(parameters),
|
||||
ResponseSummary = result?.ResponseJson,
|
||||
PayloadTruncated = false,
|
||||
Extra = null,
|
||||
ForwardState = AuditForwardState.Pending,
|
||||
};
|
||||
// The audit writer's redactor applies the configured size cap and
|
||||
// header/secret redaction downstream — the emitter just hands
|
||||
// over the raw values.
|
||||
requestSummary: SerializeRequest(parameters),
|
||||
responseSummary: result?.ResponseJson,
|
||||
payloadTruncated: false,
|
||||
extra: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1383,26 +1368,22 @@ public class ScriptRuntimeContext
|
||||
try
|
||||
{
|
||||
telemetry = new CachedCallTelemetry(
|
||||
Audit: new AuditEvent
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
OccurredAtUtc = DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
Channel = AuditChannel.DbOutbound,
|
||||
Kind = AuditKind.CachedSubmit,
|
||||
Audit: ScadaBridgeAuditEventFactory.Create(
|
||||
channel: AuditChannel.DbOutbound,
|
||||
kind: AuditKind.CachedSubmit,
|
||||
status: AuditStatus.Submitted,
|
||||
occurredAtUtc: DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
target: target,
|
||||
// CorrelationId = per-operation lifecycle id
|
||||
// (TrackedOperationId); ExecutionId = per-execution id.
|
||||
CorrelationId = trackedId.Value,
|
||||
ExecutionId = _executionId,
|
||||
correlationId: trackedId.Value,
|
||||
executionId: _executionId,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning
|
||||
// execution's id; null for non-routed runs.
|
||||
ParentExecutionId = _parentExecutionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
Target = target,
|
||||
Status = AuditStatus.Submitted,
|
||||
ForwardState = AuditForwardState.Pending,
|
||||
},
|
||||
parentExecutionId: _parentExecutionId,
|
||||
sourceSiteId: string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
sourceInstanceId: _instanceName,
|
||||
sourceScript: _sourceScript),
|
||||
Operational: new SiteCallOperational(
|
||||
TrackedOperationId: trackedId,
|
||||
Channel: "DbOutbound",
|
||||
@@ -1830,42 +1811,38 @@ public class ScriptRuntimeContext
|
||||
body = body,
|
||||
});
|
||||
|
||||
evt = new AuditEvent
|
||||
{
|
||||
EventId = Guid.NewGuid(),
|
||||
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,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning
|
||||
// execution's id; null for non-routed runs.
|
||||
ParentExecutionId = _parentExecutionId,
|
||||
SourceSiteId = string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
SourceInstanceId = _instanceName,
|
||||
SourceScript = _sourceScript,
|
||||
evt = ScadaBridgeAuditEventFactory.Create(
|
||||
channel: AuditChannel.Notification,
|
||||
kind: AuditKind.NotifySend,
|
||||
status: AuditStatus.Submitted,
|
||||
occurredAtUtc: DateTime.SpecifyKind(occurredAtUtc, DateTimeKind.Utc),
|
||||
// Outbound channel: per the Audit Log Actor-column spec the
|
||||
// actor is the calling script. Null when no single script
|
||||
// owns the call (e.g. a shared script running inline).
|
||||
Actor = _sourceScript,
|
||||
Target = _listName,
|
||||
Status = AuditStatus.Submitted,
|
||||
HttpStatus = null,
|
||||
actor: _sourceScript,
|
||||
target: _listName,
|
||||
// CorrelationId is the NotificationId-derived per-operation
|
||||
// lifecycle id; ExecutionId carries the per-execution id.
|
||||
correlationId: correlationId,
|
||||
executionId: _executionId,
|
||||
// Audit Log #23 (ParentExecutionId): the spawning
|
||||
// execution's id; null for non-routed runs.
|
||||
parentExecutionId: _parentExecutionId,
|
||||
sourceSiteId: string.IsNullOrEmpty(_siteId) ? null : _siteId,
|
||||
sourceInstanceId: _instanceName,
|
||||
sourceScript: _sourceScript,
|
||||
httpStatus: null,
|
||||
// Send is fire-and-forget from the script's perspective —
|
||||
// the dispatcher (NotificationOutboxActor) times each
|
||||
// delivery attempt and stamps DurationMs on its
|
||||
// NotifyDeliver(Attempted) rows.
|
||||
DurationMs = null,
|
||||
ErrorMessage = null,
|
||||
ErrorDetail = null,
|
||||
RequestSummary = requestSummary,
|
||||
ResponseSummary = null,
|
||||
PayloadTruncated = false,
|
||||
Extra = null,
|
||||
ForwardState = AuditForwardState.Pending,
|
||||
};
|
||||
durationMs: null,
|
||||
errorMessage: null,
|
||||
errorDetail: null,
|
||||
requestSummary: requestSummary,
|
||||
responseSummary: null,
|
||||
payloadTruncated: false,
|
||||
extra: null);
|
||||
}
|
||||
catch (Exception buildEx)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user