---
title: Configuration settings
summary: Configuration keys consumed by this library, retrieval methods, and runtime dependencies.
status: draft
owner: SAIF Platform Team
last_reviewed: 2026-10-02
library: SAIF.NetCore.Logging
reference_type: package
---

# Configuration settings

This library reads 16 unique configuration keys across two retrieval mechanisms: 7 keys through `IEnvironmentClient` (the SAIF Environment API) and 9 keys through `IConfiguration` (`appsettings.json` and any other configured provider). `SaifLog` (web) reads 7 Environment API keys and 4 `IConfiguration` keys; `SaifWindowsServiceLog` reads 6 Environment API keys and 4 `IConfiguration` keys (it never reads `logerrorroute`); `ConsoleLogService` reads 0 Environment API keys and 6 `IConfiguration` keys.

## Configuration retrieval methods

| Method | Class / Interface | Namespace | Usage pattern |
| --- | --- | --- | --- |
| `IEnvironmentClient.GetSettingValue(string configKey, string section)` | `IEnvironmentClient` (package `SAIF.NetCore.ServiceContracts`) | `SAIF.NetCore.Services.Contracts` | Plain-text Environment API read with an explicit section; the client is passed into `SaifLog.Configure(IEnvironmentClient, IHttpJsonClient, IHttpContextAccessor)` / `SaifWindowsServiceLog.Configure(IEnvironmentClient, IHttpJsonClient)` or injected into `ConsoleLogService`'s constructor — this library never resolves it from DI itself. |
| `IEnvironmentClient.HasSetting(string configKey, string section)` | `IEnvironmentClient` | `SAIF.NetCore.Services.Contracts` | Existence check that selects the application-named section over the `tracingdefaults` fallback section. |
| `IConfiguration.GetSection(key)` + `.Exists()` / `.Value` / `.GetChildren()` | `IConfiguration` | `Microsoft.Extensions.Configuration` | Imperative read of the optional `SaifLogging` section for local overrides; no binding to an options class. |
| `IConfiguration.GetValue<string>(key)` (via a private `GetArg` helper) | `IConfiguration` | `Microsoft.Extensions.Configuration` | Optional value with a caller-supplied default; a whitespace or missing value returns the default. |

## Environment API settings

Settings retrieved via `IEnvironmentClient`. `{ApplicationName}` is the runtime value of `IEnvironmentClient.ApplicationName` — a dynamic section resolved at run time. The `IEnvironmentClient` contract itself (`SAIF.NetCore.ServiceContracts`) does not specify what `GetSettingValue` returns for a missing key; the "`""` on missing" behavior described in the table below is specific to the in-repo `BaseEnvironmentClient` implementation (`GetSettingValue` returns `GetConfigSetting(configKey, section).ConfigValue?.Value ?? ""`) — see [Get setting value](../saif-netcore-environmentclient/operations/get-setting-value.md) and the EnvironmentClient library's own [configuration settings](../saif-netcore-environmentclient/configuration.md) catalog. A different `IEnvironmentClient` implementation could throw, return `null`, or behave otherwise for the same missing key.

| Setting key | Method | Data type | Purpose | Consuming class | Source |
| --- | --- | --- | --- | --- | --- |
| `{ApplicationName}:logthreshold` | `HasSetting` then `GetSettingValue` | string (`Debug`\|`Info`\|`Warn`\|`Error`\|`Fatal`) | Application-specific base log threshold; optional, falls back to `tracingdefaults:logthreshold`. | `SaifLogBase.GetBaseLevel`; `ApiLoggerConfig` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLogBase.cs` |
| `tracingdefaults:logthreshold` | `GetSettingValue` | string | Organization-wide default base log threshold; required whenever the application-named key is absent — for the observed `BaseEnvironmentClient` implementation, a missing value yields `""`, which throws `ArgumentException` when parsed; a different `IEnvironmentClient` implementation is not required to behave the same way.** | `SaifLogBase.GetBaseLevel`; `ApiLoggerConfig` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLogBase.cs` |
| `{ApplicationName}:netcorelogpattern` | `HasSetting` then `GetSettingValue` | string (Serilog output template) | Application-specific output template for the Logging API sink message body; optional, falls back to `tracingdefaults:netcorelogpattern`. | `ApiLoggerConfig` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLoggerConfig.cs` |
| `tracingdefaults:netcorelogpattern` | `GetSettingValue` | string | Default output template for the Logging API sink; passed as `logPattern` into `LoggingApiSink`'s constructor, which builds `_messageFormatter = new MessageTemplateTextFormatter(logPattern, null)` from it before any event is dispatched. Whether a missing value (an empty or `null` pattern) causes that constructor to throw, produce an empty-bodied formatter, or something else is not confirmed in this library's source** — if the constructor throws, the sink itself fails construction rather than producing an empty message body ([BR-LOG-14](business-rules.md#br-log-14-message-formatter-built-once-at-construction)). | `ApiLoggerConfig` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLoggerConfig.cs` |
| `tracingdefaults:loggingapiurl` | `GetSettingValue` | string (URL) | Base URL of the central SAIF Logging API; required for `SaifLog` and `SaifWindowsServiceLog` — for the observed `BaseEnvironmentClient` implementation, a missing value yields `""`, which is passed into `LoggingApiSink`'s constructor via `SetClientInfo` before any event is dispatched; whether an empty `baseUrl` causes that call (or the specific `IHttpJsonClient` implementation it targets) to throw, or instead results in POSTs to an invalid/empty endpoint, is not confirmed in this library's source.** A different `IEnvironmentClient` implementation is not required to behave the same way. When construction succeeds and a POST is attempted, an unsuccessful HTTP result from that POST is reported only to Console/Debug ([BR-LOG-15](business-rules.md#br-log-15-emit-is-async-void-with-no-exception-containment)); separately, because `LoggingApiSink.Emit` is `async void` rather than `async Task`, a thrown exception from the POST call itself is not captured on a `Task` for later observation — it propagates directly to the SynchronizationContext captured when `Emit` starts, or the thread pool if none was captured, and is not reported by this library at all.* | `SaifLog.Configure`; `SaifWindowsServiceLog.Configure` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLog.cs` |
| `tracingdefaults:logroute` | `GetSettingValue` | string (relative route) | Route for non-exception log entries; required for `SaifLog` and `SaifWindowsServiceLog`. | `SaifLog.Configure`; `SaifWindowsServiceLog.Configure` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLog.cs` |
| `tracingdefaults:logerrorroute` | `GetSettingValue` | string (relative route) | Route for exception entries, suffixed `?errorId={LogId}`; required for `SaifLog` only — `SaifWindowsServiceLog` never reads this key and posts errors with a `null` route. | `SaifLog.Configure` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLog.cs` |

## appsettings.json and IConfiguration

Settings read through `IConfiguration` (`appsettings.json`, `appsettings.<Environment>.json`, environment variables, and any other configured provider). None of these keys are required to bootstrap the library — every key is optional.

| Setting key | Required | Default value | Retrieval | Purpose | Consuming class | Source |
| --- | --- | --- | --- | --- | --- | --- |
| `SaifLogging:BaseLevel` | No | Web/WinSvc: none (Environment API threshold is kept); Console: `"Info"` | `GetSection("SaifLogging")` → `.Exists("BaseLevel")` → `.Value` (Web/WinSvc); `GetValue<string>` (Console) | Web/WinSvc: overrides the Environment-API-derived base threshold. Console: the **only** threshold source. | `SaifLogBase.ApplyLoggingSettingOverrides`; `ConsoleLogService.Configure` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLogBase.cs` |
| `SaifLogging:Loggers:{n}:Type` | Required per entry (if the array is present) | — | `GetSection("Loggers").GetChildren()` → `ToLoggerConfig()` | Selects which standard sink config (`ApiLog`/`EventLog`) the entry replaces; an invalid or missing value throws `SaifLogConfigurationException`. `ErrorLog` parses but no logger includes it in its standard list, so it is silently ignored. | `IConfigurationSectionExtensions.ToLoggerConfig` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Extensions/IConfigurationSectionExtensions.cs` |
| `SaifLogging:Loggers:{n}:Level` | Required per entry | None — a missing value throws `ArgumentException` | `GetSection("Level").Value` → `ToLogLevel()` | For `EventLog`: sets the Event Log sink's minimum level. For `ApiLog`: populates a level value that is never applied to the API sink at runtime. | `IConfigurationSectionExtensions.ToLoggerConfig` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Extensions/IConfigurationSectionExtensions.cs` |
| `SaifLogging:Loggers:{n}:LogPattern` | No | `null` — the override replaces the standard config wholesale, so the standard pattern is not retained | `GetSection("LogPattern").Value` | `EventLog`: output template. `ApiLog`: Logging API sink message template. | `IConfigurationSectionExtensions.ToLoggerConfig` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Extensions/IConfigurationSectionExtensions.cs` |
| `file0` | No | `C:/temp/logs/file0.txt` | `GetValue<string>("file0")` | Path of auxiliary Serilog file log `LogType.File0` ([BR-LOG-18](business-rules.md#br-log-18-console-file-sinks-default-to-local-temp-path)); root-level key, not under `SaifLogging`. | `ConsoleLogService.RegisterLogFiles`; `LogWriter.Configure` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/ConsoleLogService.cs` |
| `file1` | No | `C:/temp/logs/file1.txt` | same | Path for `LogType.File1`. | `ConsoleLogService.RegisterLogFiles`; `LogWriter.Configure` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/ConsoleLogService.cs` |
| `file2` | No | `C:/temp/logs/file2.txt` | same | Path for `LogType.File2`. | `ConsoleLogService.RegisterLogFiles`; `LogWriter.Configure` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/ConsoleLogService.cs` |
| `file3` | No | `C:/temp/logs/file3.txt` | same | Path for `LogType.File3`. | `ConsoleLogService.RegisterLogFiles`; `LogWriter.Configure` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/ConsoleLogService.cs` |
| `file4` | No | `C:/temp/logs/file4.txt` | same | Path for `LogType.File4`. | `ConsoleLogService.RegisterLogFiles`; `LogWriter.Configure` | `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/ConsoleLogService.cs` |

`file0`–`file4` apply to `ConsoleLogService` only. Because `GetValue<string>` reads the root of the host's `IConfiguration`, these keys can be set by any provider, including environment variables or command-line arguments.*

**Regarding [BR-LOG-04](business-rules.md#br-log-04-missing-override-level-throws-configuration-error):** `SaifLogging:Loggers[n]:Level` has no default-to-`Info` fallback for override entries. Source shows `ToLoggerConfig` calls `level.ToLogLevel()` unconditionally, and `ToLogLevel(null)` throws `ArgumentException` rather than defaulting — the `Level ?? Info` fallback used elsewhere is unreachable for override entries and for every standard config, since each standard config sets `Level` explicitly.

## Developer overrides

The library itself defines no developer-only settings file or override flag. If the host's `IEnvironmentClient` implementation is `SAIF.NetCore.EnvironmentClient`'s `BaseEnvironmentClient` (a runtime choice made by the host, not a dependency of this library), that implementation applies a developer-override mechanism transitively; a different `IEnvironmentClient` implementation may behave differently or not at all.

| File or flag | When applied | Effect | Source |
| --- | --- | --- | --- |
| `AppSettings:EnvApiDeveloperSettingsOverride` (conventionally `developersettings.json`) | Implementation-specific to `BaseEnvironmentClient`: when the configured file exists and the host reports a developer machine | Overrides any of this library's Environment API keys looked up through `GetSettingValue`/`HasSetting` — `logthreshold`, `netcorelogpattern`, `loggingapiurl`, `logroute`, and `logerrorroute` (whether read from the application-named section or from `tracingdefaults`) — but only when the host's `IEnvironmentClient` is `BaseEnvironmentClient`; see [Get setting value](../saif-netcore-environmentclient/operations/get-setting-value.md) and [BR-EC-18](../saif-netcore-environmentclient/business-rules.md#br-ec-18-a-missing-non-secure-setting-returns-an-empty-string-from-string-overloads) for that implementation's own missing-key behavior. | `src/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/BaseEnvironmentClient.cs` |

## Environment variables

**None.** No `Environment.GetEnvironmentVariable` call exists in this library. `Environment.MachineName`, `Environment.UserName`, and `Environment.UserDomainName` are read as process properties, not configuration, for correlation and error-payload fields.

## Database connection configuration

**None.** This library has no connection-string or database-provider settings of any kind.

## Secure settings

**None.** No `GetSecureSetting`/`GetSecureSettingAsync` call and no credential read exists in this library. Authentication of the outbound Logging API call, if any, is delegated to the injected `IHttpJsonClient` implementation and is outside this library.

## Transitive configuration (from dependencies)

| Setting key | Method | Source dependency | Dependency type | Purpose |
| --- | --- | --- | --- | --- |
| Bootstrap `AppSettings` section (application identity, host, Environment API URL) | implementation-owned | `SAIF.NetCore.EnvironmentClient` (`IEnvironmentClient` implementation) | Runtime collaborator selected by the host (not a `ProjectReference` of this library — this library's `.csproj` has none; it depends only on the `IEnvironmentClient` interface from the `SAIF.NetCore.ServiceContracts` package) | Required to construct the `IEnvironmentClient` this library depends on; a missing Environment API URL throws `MissingEnvironmentUrlVariableException` in the in-repo implementation. |
| `IHttpJsonClient` base URL/auth/timeout settings | implementation-owned | `IHttpJsonClient` implementation (ServiceContracts interface) | Runtime collaborator selected by the host | This library pushes only the Logging API base URL into the client via `SetClientInfo`; any authentication or timeout configuration is owned by the implementation. |

## Configuration dependencies

| Dependency | Type | Required at | Impact if missing |
| --- | --- | --- | --- |
| `tracingdefaults:logthreshold` (or the application-named equivalent) | Environment API setting | `Configure` time | `ArgumentException` from level parsing; `Configure` fails. `IsConfigured` stays `false` if this is the first `Configure` call, or keeps its prior `true` value if a previously-successful `Configure` is being retried and fails partway through ([BR-LOG-08](business-rules.md#br-log-08-log-entries-drop-until-logger-is-configured)); while `IsConfigured` is `false`, every subsequent log call is silently dropped. |
| `tracingdefaults:loggingapiurl` / `logroute` / `logerrorroute` | Environment API settings | `Configure` time (web/WinSvc) | For the observed `BaseEnvironmentClient` implementation, a missing value yields `""`, which is passed into `LoggingApiSink`'s constructor (`SetClientInfo`, then `MessageTemplateTextFormatter` construction) before any event is dispatched; whether that construction throws on an empty/invalid value, or instead succeeds and later POSTs to an invalid/empty endpoint, is not confirmed in this library's source.** A different `IEnvironmentClient` implementation is not required to behave the same way. When construction succeeds and a POST is attempted, an unsuccessful HTTP result is reported only to Console/Debug ([BR-LOG-15](business-rules.md#br-log-15-emit-is-async-void-with-no-exception-containment)); separately, because `LoggingApiSink.Emit` is `async void` rather than `async Task`, an exception thrown by the POST call itself is not captured on a `Task` for later observation — it propagates directly to the SynchronizationContext captured when `Emit` starts, or the thread pool if none was captured, rather than being reported anywhere by this library. See also the EnvironmentClient library's own [configuration settings](../saif-netcore-environmentclient/configuration.md) for bootstrap/developer-override behavior of that setting source. |
| `SaifLogging:BaseLevel` | `IConfiguration` key | `ConsoleLogService` construction | A present-but-invalid value throws `ArgumentException` from inside the constructor, which fails DI resolution of `IConsoleLogService`. |
| `SaifLogging:Loggers:{n}:Type` / `:Level` | `IConfiguration` keys | `Configure` time (web/WinSvc) | An invalid `Type` throws `SaifLogConfigurationException`; a missing `Level` throws `ArgumentException`. |

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Service registration](service-registration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [API reference](api/index.md)

> **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.

## Sources
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLogBase.cs`
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLog.cs`
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifWindowsServiceLog.cs`
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/ConsoleLogService.cs`
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLoggerConfig.cs`
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/StringValues.cs`
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Console/LogWriter.cs`
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Extensions/IConfigurationSectionExtensions.cs`
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Extensions/LogLevelExtensions.cs`
- `src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Loggers/LoggingApiSink.cs`
- `src/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/BaseEnvironmentClient.cs`
