feat: migrate DB error logging onto the generic OCORE MultiLogger SQL sink
Playwright Tests / test (push) Canceled after 0s
Playwright Tests / test (push) Canceled after 0s
Retires Fuchs_intranet.debug_log() and every direct EXECUTE [dbo].[fds__admin_logdebug] call in favor of a single path: ILogger. A new SQL log sink (OCORE.MultiLogger.SqlLoggerProvider, gated by Fuchs:Logging:SqlSink:Enabled, default on) mirrors every _logger.LogWarning/-Error/ -Critical call into [dbo].[fds__debuglog] via a new fds__admin_logdebug_ext proc, at Warning+. - Program.cs registers the sink and RequestLogScopeMiddleware (request id/path/authenticated user, pushed after UseAuthentication) so every log line in a request — including ones written deep inside OCORE's SQL helpers — is attributed automatically. - FIS_SQLOptions, IntranetController.Do's catch-all, PdfPreviewAsync, and the banking-upload handlers now log once, with an explicit EventId preserving the exact CodeReference text the retired debug_log() calls used to write, so existing dashboards/queries over fds__debuglog keep working unchanged. - Fuchs_DataService/FdsMfr.cs's FdsSqlOptions had the identical double-write hazard (it's hosted in the same process per ADR 0010) — the original 2026-09-16 log review's mfr__getSchema/ fds__getUpdateableRequests deadlock rows came from exactly this class. Fixed the same way. - fds__debuglog gains LogLevel/Machine/Category/Account/AuthUser/IsDebug columns; the legacy fds__admin_logdebug proc is left in place unused, not dropped. - FdsDebug.DebugLog (Fuchs_DataService's other ~9 call sites) deliberately left on its direct DB-write path — no ILogger call sits alongside it there, so no duplication risk today. See ADR 0024 (supersedes 0023) and Docs/Concepts/error-logging-pipeline.md. New tests: ErrorLoggingTests (FIS_SQLOptions), FdsSqlOptionsTests, RequestLogScopeMiddlewareTests. 694/694 pass (the 4 PdfPipelineTests failures seen under full-suite parallel runs are a pre-existing, unrelated PdfSharp global-font-resolver test-isolation flake — they pass both individually and in most full-suite runs). Bumps the OCORE submodule to 3137b56 (SQL sink hardening: redaction matches short fragments as whole identifier segments, per-entry-tolerant serialization, lazy dataSerialized, opt-in SqlLoggerOptions.IncludeCategory, LogEntry.Category/AuthUser capture). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
a1e6002c3b
commit
bcf1f2dbb6
@@ -14,11 +14,18 @@ using static OCORE.commons;
|
||||
namespace fds;
|
||||
|
||||
/// <summary>
|
||||
/// Logs every SQL error both to the worker's structured <see cref="ILogger"/> (so it reaches
|
||||
/// whatever sink/OTel export is configured) and to <see cref="FdsDebug.DebugLog"/> (SQL/local-file
|
||||
/// debug trail). Passing <paramref name="logger"/> is optional for call sites that don't have one
|
||||
/// in scope, but every caller that does have one in scope should pass it — otherwise a failing
|
||||
/// stored procedure only ever shows up in the debug trail, never in the worker's own logs.
|
||||
/// Logs every SQL error through the worker's structured <see cref="ILogger"/> alone — which, when
|
||||
/// this worker runs hosted inside the Fuchs web app (ADR 0010), also reaches the OCORE MultiLogger
|
||||
/// SQL sink at Warning+ (ADR 0024) and lands in the same <c>fds__debuglog</c> table
|
||||
/// <c>FdsDebug.DebugLog</c> used to write to directly. Calling both here would double-write
|
||||
/// every row, which is exactly what the original 2026-09-16 log review's back-to-back
|
||||
/// "mfr__getSchema"/"fds__getUpdateableRequests" deadlock entries were heading towards once the
|
||||
/// SQL sink went live — so this class no longer calls <c>FdsDebug.DebugLog</c>. Passing a
|
||||
/// <c>logger</c> is optional; falls back to the static <see cref="OCORE.Logging.Logger"/>
|
||||
/// (set once in <c>Program.cs</c>) so a failing stored procedure is never silently dropped.
|
||||
/// <c>FdsDebug.DebugLog</c> remains the primary/only DB-attribution path for every other
|
||||
/// call site in this project that doesn't separately log through <see cref="ILogger"/> — it was
|
||||
/// deliberately not migrated onto the generic pipeline (see ADR 0024's Consequences).
|
||||
/// </summary>
|
||||
public class FdsSqlOptions : sqloptions
|
||||
{
|
||||
@@ -29,9 +36,12 @@ public class FdsSqlOptions : sqloptions
|
||||
_baseInfo = dic;
|
||||
OnError = (procedure, ex, data) =>
|
||||
{
|
||||
logger?.LogError(ex, "SQL error in {Procedure}: {Message} — ctrl_nfo={CtrlInfo} sql={Data}",
|
||||
var lg = logger ?? OCORE.Logging.Logger;
|
||||
// EventId.Name == procedure keeps the exact CodeReference the direct DebugLog() call
|
||||
// used to write (it passed `procedure` as-is, not prefixed).
|
||||
lg?.LogError(new EventId(0, procedure), ex,
|
||||
"SQL error in {Procedure}: {Message} — ctrl_nfo={CtrlInfo} sql={Data}",
|
||||
procedure, ex.Message, dic, data);
|
||||
FdsDebug.DebugLog(procedure, exc: ex, data: $"ctrl_nfo={dic}, sql={data}");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,18 @@
|
||||
<members>
|
||||
<member name="T:fds.FdsSqlOptions">
|
||||
<summary>
|
||||
Logs every SQL error both to the worker's structured <see cref="T:Microsoft.Extensions.Logging.ILogger"/> (so it reaches
|
||||
whatever sink/OTel export is configured) and to <see cref="M:fds.FdsDebug.DebugLog(System.String,Microsoft.Data.SqlClient.SqlConnection,System.Exception,System.String,System.Object)"/> (SQL/local-file
|
||||
debug trail). Passing <paramref name="logger"/> is optional for call sites that don't have one
|
||||
in scope, but every caller that does have one in scope should pass it — otherwise a failing
|
||||
stored procedure only ever shows up in the debug trail, never in the worker's own logs.
|
||||
Logs every SQL error through the worker's structured <see cref="T:Microsoft.Extensions.Logging.ILogger"/> alone — which, when
|
||||
this worker runs hosted inside the Fuchs web app (ADR 0010), also reaches the OCORE MultiLogger
|
||||
SQL sink at Warning+ (ADR 0024) and lands in the same <c>fds__debuglog</c> table
|
||||
<c>FdsDebug.DebugLog</c> used to write to directly. Calling both here would double-write
|
||||
every row, which is exactly what the original 2026-09-16 log review's back-to-back
|
||||
"mfr__getSchema"/"fds__getUpdateableRequests" deadlock entries were heading towards once the
|
||||
SQL sink went live — so this class no longer calls <c>FdsDebug.DebugLog</c>. Passing a
|
||||
<c>logger</c> is optional; falls back to the static <see cref="F:OCORE.Logging.Logger"/>
|
||||
(set once in <c>Program.cs</c>) so a failing stored procedure is never silently dropped.
|
||||
<c>FdsDebug.DebugLog</c> remains the primary/only DB-attribution path for every other
|
||||
call site in this project that doesn't separately log through <see cref="T:Microsoft.Extensions.Logging.ILogger"/> — it was
|
||||
deliberately not migrated onto the generic pipeline (see ADR 0024's Consequences).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:fds.FdsMfr.InvoiceFileDownloadConcurrency">
|
||||
|
||||
Reference in New Issue
Block a user