SAIF.Framework.Logging architecture¶
SAIF.Framework.Logging is a cross-cutting, application-agnostic logging utility library that provides audit, error, and (deprecated) trace logging concerns, each dispatching to either a local CSV file or a remote SOAP web service (wsLogging) depending on the hosting application type.
Responsibilities¶
- Provide audit logging (
clsLogAudit) for application/business-event messages, opt-in viaIsEnabled(defaultsFalse). - Provide error logging (
clsLogError), including exception detail capture, ViewState-noise suppression, and optional email notification of errors. - Provide trace logging (
clsLogTrace) for method-level tracing — functionally disabled (see Design constraints). - Provide a legacy login-event logger (
clsLoginLog.LogItem) that writes monthly CSV files. - Provide an MSMQ queue path-name helper (
clsLoggingQueues) that formats a queue path string from configuration. - Retain a deprecated, independently designed rolling-file logger (
LogList/LogList.LogItem) for backward compatibility only.
Component boundaries¶
clsLogAudit,clsLogError,clsLogTrace: primary logging entry points, each following the same internal shape — aGetBasic*Info()context-gathering method, a value-type info struct (AuditInfoStruct/ErrorInfoStruct/TraceInfoStruct), and aWriteMessagedispatcher.clsLogCommon:Publicshared helper class. Its web/non-web context detection (IsWeb), environment/application-name derivation, calling-method reflection, and related helper methods/properties areFriend-scoped (assembly-internal) and not part of the external public surface; its format-string constants (e.g.STATEFMTSIMPLE,TOFILEFORMAT) arePublic Constand are part of the external public surface.wsLogging.clsWSLogging(generated SOAP client proxy,Web References/wsLogging/Reference.vb): remote sink boundary — marshalsAuditInfoStruct/ErrorInfoStruct/TraceInfoStructdata to a legacy ASMX web service viaWriteAudit/WriteError/WriteTraceoperations.clsLoginLog: independent boundary — writes directly to a monthly CSV file; does not use thewsLoggingsink or theclsLogCommoninfo-struct pattern.clsLoggingQueues: independent boundary — resolves an MSMQ path-name string fromConfigurationManager.AppSettings; does not open or write to a queue itself*.LogList/LogList.LogItem: independent, obsolete boundary — a separate rolling-file logger unrelated to theclsLogXxxdual-sink pattern.
Interaction model¶
- Callers (hosting applications) invoke one of the public logging entry points (
clsLogAudit.AuditMessage/AuditCustomMessage,clsLogError.CreateError/CreateErrorWithEmail,clsLogTrace.MethodBegin/MethodEnd/MethodMessage). - Each entry point gathers ambient context (machine name, application name, page name, environment, username) via a
GetBasic*Info()method, which constructs aclsSecurityPrincipalinstance (fromSAIF.Framework.Security) purely to read the current user's identity for inclusion in the log record. clsLogCommon.IsWebdetermines whether context is sourced fromHttpContext.Server/Request(web) orProcess/Environment(non-web), governing which sink is permitted (see Design constraints).- The populated info struct is passed to
WriteMessage, which dispatches to either: - a local file sink (
m_OutFile.WriteLine, CSV format), ifToFile()was previously called; or - the remote SOAP sink (
wsLogging.clsWSLogging.WriteAudit/WriteError/WriteTrace), by default — with the endpoint URL resolved viaAppGlobal.EnvironmentService.GetConfigSetting(EnvironmentConfigKeys.LoggingServiceUrl). clsLogError.CreateErrorWithEmailadditionally constructs aclsSAIFMessage(fromSAIF.Framework.Mail) and callsSendMail(...)to notify a recipient by email, in parallel with the file/SOAP write.- All logging entry-point bodies (or their private write helpers) wrap execution in
Try...Catchwith empty/'gobble gobblecatch blocks, so logging failures are silently swallowed and never propagate to the caller.
The following diagram shows high-level component interactions.
flowchart TD
Caller[Hosting application] --> LogAudit[clsLogAudit]
Caller --> LogError[clsLogError]
Caller --> LogTrace["clsLogTrace<br>(obsolete, no-op sink)"]
Caller --> LoginLog[clsLoginLog]
Caller --> LoggingQueues[clsLoggingQueues]
Caller --> LogListLegacy["LogList<br>(obsolete)"]
LogAudit --> LogCommon[clsLogCommon]
LogError --> LogCommon
LogTrace --> LogCommon
LogAudit --> SecurityPrincipal["clsSecurityPrincipal<br>(SAIF.Framework.Security)"]
LogError --> SecurityPrincipal
LogTrace --> SecurityPrincipal
LogAudit --> EnvService["AppGlobal.EnvironmentService<br>(SAIF.Framework.Security.EnvironmentApi)"]
LogError --> EnvService
LogTrace --> EnvService
LogAudit -->|IsWeb=False, ToFile called| FileSinkA["Local CSV file"]
LogAudit -->|default| WsLogging["wsLogging.clsWSLogging<br>(SOAP/ASMX web service)"]
LogError -->|IsWeb=False, ToFile called| FileSinkE["Local CSV file"]
LogError -->|default| WsLogging
LogTrace -.->|no-op, never writes| WsLogging
LogError --> SaifMail["clsSAIFMessage<br>(SAIF.Framework.Mail)"]
LoginLog --> FileSinkL["Monthly login CSV file"]
LoggingQueues --> QueuePath["MSMQ path string<br>(no queue I/O in this library)"]
Sequence diagram¶
The following diagram shows the primary error-logging request/response sequence, including the file/web-service sink branch.
sequenceDiagram
participant Caller
participant clsLogError
participant clsSecurityPrincipal
participant wsLogging as wsLogging.clsWSLogging
Caller->>clsLogError: CreateError(exception, stateInfo)
clsLogError->>clsSecurityPrincipal: read current user identity
clsSecurityPrincipal-->>clsLogError: UserName / IsAuthenticated
clsLogError->>clsLogError: SuppressLogging() check (ViewState noise)
alt not suppressed and ToFile() previously called
clsLogError->>clsLogError: WriteMessageToFile (local CSV)
else default (web-service sink)
clsLogError->>wsLogging: WriteError(ErrorInfoStruct)
wsLogging-->>clsLogError: (fire-and-forget / swallowed failure)
end
clsLogError-->>Caller: (no exception propagated on failure)
Design constraints¶
- Dual-sink design: every main logging class writes to exactly one of two sinks — a local CSV file (opened via
ToFile()) or the remotewsLoggingSOAP web service (default) — selected per-instance, not concurrently. - File logging is prohibited for web applications:
clsLogCommon.IsWeb(Not System.Web.HttpContext.Current Is Nothing) gatesToFile(); ifIsWebisTrue,ToFile()throwsApplicationException("Logging to files not valid for web applications."). Web applications must use thewsLoggingweb-service sink. See BR-003. clsLogTraceis fully disabled and obsolete: all public trace methods (MethodBegin,MethodEnd,MethodMessage) are decorated<Obsolete("Log Trace No Longer Supported, Please remove")>, and the privateWriteMessagesink is a no-op ('Removed Logic as tracing should not be used.). The class still exposesIsEnabled/UserTraceEnabledgating logic and a privateWSWriteMessagepath, but no trace data ever reaches the file or web-service sinks regardless of flag state. See BR-002.- Best-effort logging: all logging entry points swallow failures silently via empty/
'gobble gobbleTry...Catchblocks, so a failure to log (e.g., web service unreachable) never causes the calling application to fail. See BR-005. - Tight coupling to sibling framework libraries: logging classes directly construct
clsSecurityPrincipaland referenceAppGlobal.EnvironmentServicerather than depending on abstractions, coupling this library toSAIF.Framework.SecurityandSAIF.Framework.Security.EnvironmentApi— architectural observation, inferred*. - Environment/application-name detection is convention-based:
GetAppEnvironment/GetWebAppNameparse the physical file/module path (splitting on:and\) rather than reading explicit configuration, an inferred convention rather than a documented contract*. LogListandclsLoginLogbypass the dual-sink pattern:LogListis an independently designed rolling-file logger, andclsLoginLogwrites directly to a monthly CSV file; neither uses theclsLogCommon/wsLoggingpattern used byclsLogAudit/clsLogError/clsLogTrace.
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with**could not be confirmed; treat as unknown until verified.
Related documentation¶
Sources¶
SAIF.Framework.Logging/clsLogAudit.vbSAIF.Framework.Logging/clsLogCommon.vbSAIF.Framework.Logging/clsLogError.vbSAIF.Framework.Logging/clsLoggingQueues.vbSAIF.Framework.Logging/clsLoginLog.vbSAIF.Framework.Logging/clsLogTrace.vbSAIF.Framework.Logging/LogList.vbSAIF.Framework.Logging/Web References/wsLogging/Reference.vbSAIF.Framework.Logging/SAIF.BOF.Framework.Logging.vbprojSAIF.Framework.Logging/app.config