Skip to content

OP-03: Configure the console logger (ConsoleLogService)

Field Value
Operation ID OP-03
Trigger ConsoleLogService is constructed; Configure() runs inline in the constructor.
Inputs IConfiguration, IEnvironmentClient (identity only).
Outputs A configured Serilog pipeline (Event Log sink at LogEventLevel.Fatal, plus a Console sink) set as the static Log.Logger, and up to five separately-configured auxiliary LogWriter file sinks reachable via GetLog/WriteToAppLog.
Primary components ConsoleLogService, LogWriter
Entry point ConsoleLogService constructor → Configure()

Steps

  1. Read SaifLogging:BaseLevel from IConfiguration; if absent or whitespace, default to "Info" (BR-LOG-12).
  2. Parse the resolved level string into the BaseLevelSwitch; an invalid value throws ArgumentException directly out of the constructor, failing DI resolution of IConsoleLogService.
  3. Register the five auxiliary file paths (file0–file4) from the root of IConfiguration via RegisterLogFiles(); each LogWriter is constructed with whatever value is read, or an empty string when the corresponding key is unset (GetArg's own defString: "" default) — RegisterLogFiles applies no Windows-style default path of its own. The C:/temp/logs/file{n}.txt default is applied later, only inside LogWriter.Configure(), when FilePath is whitespace at the time that method runs (BR-LOG-18); each LogWriter is a separate channel that lazily builds its own Serilog logger with an independent LoggingLevelSwitch(LogEventLevel.Verbose) threshold — it is not part of the main pipeline built in step 5.
  4. Build the standard EventLogConfig sink configuration (BuildStandardLoggerConfigs returns only this one config for the console logger).
  5. Call Log.CloseAndFlush() then set Log.Logger to a newly built Serilog logger with the resolved BaseLevelSwitch, an Event Log sink restricted to LogEventLevel.Fatal (hardcoded in CreateLogger(), not read from configuration), and a Console sink. No Logging API sink is attached, and no Debug sink exists anywhere in this logger.
  6. The console logger never reads the Environment API base threshold or the SaifLogging:Loggers override array; both are ignored for this host style.

Process flow

flowchart TD
    A[ConsoleLogService constructed] --> B[Configure called inline]
    B --> C["Read SaifLogging:BaseLevel,<br>default Info if whitespace/missing"]
    C --> D{Level valid?}
    D -->|No| D1["ArgumentException thrown from constructor -<br>DI resolution fails"]
    D -->|Yes| E["RegisterLogFiles: file0..file4,<br>each its own LogWriter with independent Verbose switch"]
    E --> F["Build Serilog Log.Logger: Event Log sink<br>(Fatal, hardcoded) + Console sink"]

Failure and edge-case behavior

  • An invalid SaifLogging:BaseLevel value throws ArgumentException directly out of the constructor, failing DI resolution of IConsoleLogService; it is the only level-parsing failure mode, but it is not the only way this constructor can throw — EventLog construction in CreateLogger() can itself fail at runtime (for example, on a non-Windows host or without the necessary OS permissions to create/open the named Event Log source), and _loggers/the registered LogWriter list is mutable instance state assembled during the same constructor call, so any exception during RegisterLogFiles() or CreateLogger() likewise aborts construction and DI resolution.
  • File sinks are lazy: a configured path is only created on disk via an explicit call to the writer's own public Configure() method or on first access of its Logger property (not specifically on first write) — a channel that is never explicitly Configure()-d and whose Logger property is never accessed never creates a file — and each file sink's own LoggingLevelSwitch (fixed at Verbose) is independent of BaseLevelSwitch and of the main Event Log/Console sinks.
  • Environment API thresholds and SaifLogging:Loggers overrides set by operators have no effect on this logger (BR-LOG-12).

Sources

  • src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/ConsoleLogService.cs
  • src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Console/LogWriter.cs