OP-01: Configure the web logger (SaifLog)¶
| Field | Value |
|---|---|
| Operation ID | OP-01 |
| Trigger | Host application calls SaifLog.Configure(IEnvironmentClient, IHttpJsonClient, IHttpContextAccessor) during application startup. |
| Inputs | IEnvironmentClient (Environment API access), IHttpJsonClient (Logging API transport), IHttpContextAccessor (used to build the web-specific exception formatter). |
| Outputs | A configured Serilog pipeline with Event Log and Console sinks plus the Logging API sink; IsConfigured set to true. |
| Primary components | SaifLog, SaifLogBase, ApiLoggerConfig, EventLogConfig |
| Entry point | SaifLog.Configure |
Steps¶
- Call
ConfigureLoggers(environmentClient), which resolves the base log threshold by checking the application-named Environment API section first, falling back toGetSettingValue("logthreshold", "tracingdefaults")(BR-LOG-01, BR-LOG-02). - Parse the resolved threshold string into a
LogEventLevel; an unparseable or empty value throwsArgumentExceptionand aborts configuration (BR-LOG-08). - Still inside
ConfigureLoggers: build the standardApiLoggerConfigandEventLogConfigsink configurations from the Environment API pattern keys and the resolved threshold, then apply theSaifLogging:BaseLevelandSaifLogging:Loggersappsettings.jsonoverrides: - 3.1. Check whether the
SaifLoggingsection exists and contains aBaseLevelchild; only then replaceBaseLevelwith that configured value (normalized viaToLogLevelString()) — an absent section or key leaves the Environment-API-derivedBaseLevelfrom steps 1–2 untouched (BR-LOG-02). - 3.2. Check whether
SaifLogging:Loggersexists; for each child entry, parseType/Level/LogPatternand replace the matching standardApiLog/EventLogconfig wholesale, throwingSaifLogConfigurationExceptionfor an invalidTypeorArgumentExceptionfor a missingLevel(BR-LOG-03, BR-LOG-04, BR-LOG-05).
Origin: Steps 3.1–3.2 are implemented in Apply appsettings.json logger overrides (
SaifLogBase.ApplyLoggingSettingOverrides) and executed on behalf of this operation. 4. Back inConfigure: setExFormatServiceto a newExceptionFormatServiceForWeb(environmentClient, httpContext)and callLog.CloseAndFlush(). 5. Readtracingdefaults:loggingapiurl,tracingdefaults:logroute, andtracingdefaults:logerrorroutefrom the Environment API, and push the base URL/credentials into the injectedIHttpJsonClient. 6. Construct the Serilog logger with the resolvedBaseLevelSwitch, an Event Log sink at the configuredEventLogConfiglevel, aLoggingApiSink, and a Console sink. 7. SetIsConfigured = trueso that subsequent log calls are accepted.
Process flow¶
flowchart TD
A[Configure called] --> B["ConfigureLoggers: resolve base threshold"]
B --> C{Threshold valid?}
C -->|No| C1["ArgumentException - Configure aborts,<br>IsConfigured stays false if this is the first<br>attempt, or keeps its prior true value<br>if a previously-successful Configure is retried"]
C -->|Yes| D["Build standard ApiLoggerConfig + EventLogConfig,<br>apply BaseLevel/Loggers overrides"]
D --> E["Set ExFormatService = ExceptionFormatServiceForWeb"]
E --> F[Read loggingapiurl / logroute / logerrorroute]
F --> G[Push base URL into IHttpJsonClient]
G --> H["Build Serilog logger: Event Log sink +<br>LoggingApiSink + Console sink"]
H --> I["IsConfigured = true"]
Failure and edge-case behavior¶
- A missing or invalid base threshold aborts this
Configurecall entirely;IsConfiguredstaysfalseif this is the firstConfigureattempt on the instance, or keeps its priortruevalue if a previously-successfulConfigureis being retried and this one fails (BR-LOG-08). WhileIsConfiguredisfalse, every subsequent non-exception log call still returns a generated correlation ID but writes only a Debug-level diagnostic trace instead of reachingILogger/Serilog; an exception-bearing call returns an ID only once its own pre-ID exception-formatting steps complete without throwing. - An invalid
SaifLogging:LoggersentryTypethrowsSaifLogConfigurationException; a missingLevelthrowsArgumentException— both abort thisConfigurecall the same way. - Whether a missing
loggingapiurl/logroute/logerrorrouteaborts configuration is not confirmed one way or the other in this library's source for every case.**LoggingApiSink's constructor calls_httpJsonClient.SetClientInfo(baseUrl, "SaifLog", Environment.MachineName, applicationId)— only the base URL and client identity, not either route — and separately storesroutePart/errorRoutePartfor later use as thePostAsyncURI argument; this call happens without a surrounding try/catch. Whether the specificIHttpJsonClientimplementation in use throws for an empty/invalidbaseUrlargument is implementation-dependent and not something this library's own source confirms either way. IfSetClientInfo(or the sink constructor itself) does not throw, final endpoint validity for the subsequentPostAsync(routePart, ...)call depends entirely on how the injectedIHttpJsonClientresolves a base URL and route together — an empty route does not by itself make a valid base URL resolve to an invalid or empty endpoint. An unsuccessful HTTP result from that POST is reported only to Console/Debug (BR-LOG-15); separately,LoggingApiSink.Emitisasync voidwith no try/catch, so an exception thrown by the POST call itself (as opposed to an unsuccessful result) is not caught or reported anywhere in this library.
Related documentation¶
Note: Statements marked with
**could not be confirmed; treat as unknown until verified.
Sources¶
src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLog.cssrc/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLogBase.cssrc/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLoggerConfig.cs