Files
Fuchs_Intranet/Fuchs/Docs/Decisions/0003-structured-diagnostic-logging.md
Stefan 882e97509a Enhance logging in FdsSqlOptions and related classes
- Updated FdsSqlOptions to accept an optional ILogger parameter for improved error logging.
- Modified FdsMfr and FdsMfrClient classes to pass the logger instance to FdsSqlOptions.
- Added detailed error logging in various methods to capture SQL execution issues and file handling errors.
- Improved documentation for FdsSqlOptions to clarify logging behavior.
- Updated Archive class to log compression errors, enhancing traceability of failures.
- Adjusted project configuration to suppress specific warnings related to transitive dependencies.
- Added NuGet.config to define package sources for dependency management.
- Updated submodule references for OCORE and related projects.
2026-07-03 20:22:05 +02:00

2.7 KiB

status, date, applyTo, supersededBy
status date applyTo supersededBy
Accepted 2026-07-03
Fuchs/Logging/**
Fuchs/Program.cs

0003 — The solution is equipped with structured diagnostic logging

Context

Diagnosing issues in a deployed intranet instance requires a durable, inspectable log of what the application did, independent of whether an OpenTelemetry collector is attached (see 0004) — logging must work out-of-the-box on every environment with zero external dependencies.

Decision

  • Fuchs/Logging/FuchsLoggerProvider.cs implements a custom ILoggerProvider/ILogger registered via builder.Logging.AddFuchsLogging() in Program.cs, with SetMinimumLevel(LogLevel.Debug).
  • Every log line always goes to Debug.WriteLine and to a rolling text file under <content root>/logs/AppLog.txt for Debug/Information/Warning, ErrorLog.txt for Error/Critical — so a failure investigation never depends on a debugger being attached.
  • Log lines are structured with timestamp, level tag, category, message, and (when present) the exception message + stack trace on continuation lines.
  • Database logging (fuchs__admin_logdebug) is prepared but disabled by default (FuchsLoggerProvider.DatabaseLoggingEnabled = false) — flip it on only where DB-durable diagnostics are specifically needed, since it adds a DB round-trip per log call.
  • All logger calls elsewhere in the codebase use ILogger<T> injected via DI with structured placeholders (_logger.LogInformation("Sent {InvoiceNumber} to {Email}", ...)), never interpolated strings — this is enforced project-wide (see Coding Standards / Observability in CLAUDE.md).
  • File writes are best-effort: AppendToFile swallows its own exceptions — a logging failure must never crash or interrupt the operation being logged.

Consequences

  • New code must inject ILogger<T> and log entry/result/timing/errors for meaningful operations (see 0004 for the matching tracing/metrics requirement) rather than adding ad-hoc Console.WriteLine/Debug.Print calls.
  • Because logs always write to logs/AppLog.txt and ErrorLog.txt regardless of telemetry configuration, these files are the first place to check when OTLP export isn't configured for an environment.
  • Enabling DatabaseLoggingEnabled is a deliberate, explicit choice per environment, not a default — it has a per-call DB cost.

Alternatives considered

  • Third-party logging framework (Serilog/NLog): rejected for now to avoid an extra dependency for a need the in-box ILogger abstraction plus a small custom provider already satisfies; revisit if requirements (e.g. structured JSON sinks, log shipping) outgrow this.