Skip to content

SAIF.NetCore.Logging dependencies

SAIF.NetCore.Logging takes a single internal NuGet package dependency on the foundation layer, SAIF.NetCore.ServiceContracts, consumes a small set of Serilog and Newtonsoft packages (some declared, some transitive), and makes one direct outbound API call of its own — to the central SAIF Logging API — through its registered ISaifLogService/ISaifWindowsServiceLogService implementations.

Internal dependencies

Dependency Reference Type Usage
SAIF.NetCore.ServiceContracts NuGet Package (same-repo) Implements ISaifLoggable, ISaifLogService, ISaifWindowsServiceLogService, and IWebRequestLogInfo; consumes IEnvironmentClient, IHttpJsonClient, SAIFException, and the LogLevel/LoggerType enums.

External dependencies

Dependency Version Usage
Serilog.AspNetCore 3.4.0 UseSerilog() in Web/WebHostBuilderExtensions.cs; brings in Serilog core and LogContext.
Serilog.Enrichers.Thread 3.1.0 .Enrich.WithThreadId() in SaifLog and SaifWindowsServiceLog.
Serilog.Sinks.Console 3.1.1 .WriteTo.Console() on every host-style logger.
Serilog.Sinks.EventLog 3.1.0 .WriteTo.EventLog(EnvironmentClient.ApplicationName, outputTemplate: Patterns[LoggerType.EventLog], restrictedToMinimumLevel: LogEventLevel.Fatal) in ConsoleLogService.cs (with additional logName/manageEventSource arguments in SaifLog.cs and SaifWindowsServiceLog.cs); Windows-only sink.
Serilog.Sinks.File not declared (transitive via Serilog.AspNetCore 3.4.0) .WriteTo.File(FilePath, flushToDiskInterval: TimeSpan.FromSeconds(1)) in Console/LogWriter.cs; the library depends on it without declaring it directly*.
Newtonsoft.Json not declared (transitive) JsonConvert serialization in SaifLogBase.cs, ExceptionFormatService.cs, and LogEventExtensions.cs*.

API dependencies

Endpoint Method Called from Source library Reached via Usage
{LoggingApiUrl}{LoggingApiRoute} (configured logroute) POST LoggingApiSink.Emit (Loggers/LoggingApiSink.cs) This library — Ships a non-error LogItem { ApplicationId, EnvironmentTrack, Message } to the SAIF Logging API.
{LoggingApiUrl}{LoggingApiErrorRoute}?errorId={LogId} (configured logerrorroute) POST LoggingApiSink.Emit (Loggers/LoggingApiSink.cs) This library — Ships an ErrorLogItem when the log event carries an exception and LogExceptionDetails.

Both endpoint base URLs and routes are resolved at Configure time from IEnvironmentClient.GetSettingValue under the tracingdefaults section (keys loggingapiurl, logroute, logerrorroute), not hard-coded in this library. The outbound HTTP call itself is made through ServiceContracts' IHttpJsonClient.PostAsync, with the client identifying itself as "SaifLog" via IHttpJsonClient.SetClientInfo.

Dependency risks and notes

  • SAIF.NetCore.Services.Messaging declares a direct PackageReference on SAIF.NetCore.Logging (version 1.3.21025.2, on the end-of-life netcoreapp3.1 target), but only to call the pure in-process conversion utility LogLevelExtensions.ToLogLevel. This is a documented implementation-to-implementation exception in Architecture.md. Messaging reaches the actual outbound-logging behavior exclusively through the ServiceContracts interfaces (ISaifLogService), never through this direct package reference*.
  • SAIF.NetCore.ServiceExtensions is the other consumer; it registers and configures all three loggers and uses WebRequestDetails/IConsoleLogService directly.
  • Consumers that only resolve ISaifLogService/ISaifWindowsServiceLogService (PingableService, OIDC, ErrorHandler) depend on ServiceContracts, not on this library directly; the concrete implementation is supplied at runtime through ServiceExtensions registration*.
  • LoggingApiSink.Emit is async void with no try/catch of its own. An unsuccessful HTTP result (RequestResult.IsSuccessful == false) is reported to Console/Debug only, with no retry, so delivery of log/error records to the SAIF Logging API is best-effort for that failure mode; separately, an exception thrown by the PostAsync call itself (network failure, serialization error, etc.) is not caught anywhere in the sink. Because Emit is async void rather than async Task, that exception is not stored on a Task the way an async Task method's exception would be — it propagates directly to the SynchronizationContext captured when Emit starts, or the thread pool if none was captured, outside this library's own call stack, and can surface as an unhandled exception that terminates the process; it is not a value this library reports or contains at all.
  • Serilog.Sinks.File and Newtonsoft.Json are used directly in source but not declared as direct PackageReference entries; both currently resolve transitively through Serilog.AspNetCore version 3.4.0, and an upgrade or replacement of that package is a latent risk to this library's file-logging and JSON-serialization code paths*.

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging.csproj
  • src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Loggers/LoggingApiSink.cs
  • src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SaifLogBase.cs
  • src/SAIF.NetCore.Logging/SAIF.NetCore.Logging/SAIF.NetCore.Logging/Console/LogWriter.cs
  • src/Messaging/src/SAIF.NetCore.Services.Messaging/SAIF.NetCore.Services.Messaging/SAIF.NetCore.Services.Messaging.csproj
  • src/Messaging/src/SAIF.NetCore.Services.Messaging/SAIF.NetCore.Services.Messaging/RabbitMq/Services/LogService.cs
  • Architecture.md