Skip to content

Dispatch audit message

This operation records a single audit event, but only once a hosting application has explicitly turned audit logging on. It gathers ambient context (who, where, and in what environment), merges in the caller's message or custom payload, and writes the resulting record to whichever sink is currently active — a local CSV file if one was opened, or the remote wsLogging SOAP service otherwise.

Field Value
Operation ID LOG-OP-001
Trigger Caller invokes clsLogAudit.AuditMessage(...) or clsLogAudit.AuditCustomMessage(...).
Inputs Message text, optional state objects, and for the custom overload performedTo, optional performedBy, optional performedAt, optional overrideApplicationName.
Outputs CSV append or wsLogging.WriteAudit(...) side effect; no return value.
Primary components clsLogAudit.AuditMessage, clsLogAudit.AuditCustomMessage, clsLogAudit.GetBasicAuditInfo, clsLogAudit.WriteMessage
Entry point SAIF.Framework.Logging/clsLogAudit.vb

Steps

  1. Check clsLogAudit.IsEnabled first; while it is False, the operation returns immediately and performs no context capture or sink work (BR-001).
  2. Assemble a baseline AuditInfoStruct in GetBasicAuditInfo().
  3. Stamp AuditDate = Now and clear DataText.
  4. For web hosts (clsLogCommon.IsWeb is True), read machine, application, page, and environment values from HttpContext.Server and HttpContext.Request, then construct New clsSecurityPrincipal(clsSecurityPrincipal.Platform.Web).
  5. For non-web hosts, read the executable and environment data from Process.MainModule, set PageName = "WINFORMS", use Environment.MachineName, and construct New clsSecurityPrincipal(clsSecurityPrincipal.Platform.Windows).
  6. Copy Secprinc.UserName into UserName when the principal resolves one; otherwise leave it empty.
  7. On failure: the helper swallows the exception and returns whatever fields it managed to populate (BR-005).

Origin: The identity-capture in step 2 delegates to clsSecurityPrincipal and follows the same pattern documented in Principal identity initialization (SAIF.Framework.Security). 3. Merge the caller's payload into the struct. - AuditMessage(...) copies inMsg into MessageText and serializes inStateInfo through clsLogCommon.GetStateInfo(...), which writes primitive values directly and reflects object properties into name/type/value lines. - AuditCustomMessage(...) copies performedTo into DataText, then overrides the audit date, user name, or application name only where the caller supplied an explicit, non-default value. - AuditCustomMessage(...) then replaces the environment text with AppGlobal.EnvironmentService.ToDevelopmentEnvironment(AppGlobal.EnvironmentService.GetApplicationEnvironment()).ToString().

Origin: The environment lookup in step 3.3 depends on IEnvironmentService.GetApplicationEnvironment() from SAIF.Framework.Security.EnvironmentApi, summarized in Retrieve a configuration setting (SAIF.Framework.Security.EnvironmentApi). 4. Select the output sink in WriteMessage(...). - If m_OutFile Is Nothing, continue to the SOAP branch below. - Otherwise append AuditInfoStruct.ToCSVString() to the open file writer and flush it. 5. In the SOAP branch, resolve loggingServiceUrl, construct wsLogging.clsWSLogging, copy the local struct into a wsLogging.AuditInfoStruct, call WriteAudit(...), and dispose the proxy. - On failure: the SOAP branch catches and discards the exception, so the caller always regains control (BR-005).

Origin: The loggingServiceUrl lookup in step 5 delegates to Environment API configuration retrieval, summarized in Retrieve a configuration setting (SAIF.Framework.Security.EnvironmentApi).

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([Audit request]) --> Enabled{IsEnabled?}
    Enabled -->|No| EndSkip([Return without logging])
    Enabled -->|Yes| Context[Build AuditInfoStruct]
    Context --> Payload[Apply message and state/custom overrides]
    Payload --> Sink{File sink active?}
    Sink -->|Yes| FileWrite[Append CSV row and flush]
    Sink -->|No| Resolve[Resolve loggingServiceUrl]
    Resolve --> SoapWrite[Call wsLogging.WriteAudit]
    FileWrite --> EndOk([Return to caller])
    SoapWrite --> EndOk

Failure and edge-case behavior

  • While IsEnabled is False, the operation exits before touching context or any sink, so disabled audit logging carries no performance cost beyond the flag check (BR-001).
  • Context capture and the SOAP dispatch both suppress exceptions, so a partially populated or entirely unsent audit record can be dropped silently rather than surfacing a failure to the caller (BR-005).
  • Once a file sink has been opened through ToFile(...), this operation never falls back to the SOAP path for that call.

Sources

  • SAIF.Framework.Logging/clsLogAudit.vb
  • SAIF.Framework.Logging/clsLogCommon.vb
  • SAIF.Framework.Logging/AuditInfoStruct.vb
  • SAIF.Framework.Security/clsSecurityPrincipal.vb
  • SAIF.Framework.Security/EnvironmentServices/EnvironmentExtensions.vb
  • SAIF.Framework.Security.EnvironmentApi/Services.Common/EnvironmentServiceBase.cs
  • SAIF.Framework.Security.EnvironmentApi/Services.Common/EnvironmentConfigKeys.cs