Skip to content

fix(gs): exclude self-emitted audit lines from TRACES_BY_MESSAGE results#3756

Closed
TaprootFreak wants to merge 5 commits into
developfrom
fix/realunit-trace-template-exclude-audit
Closed

fix(gs): exclude self-emitted audit lines from TRACES_BY_MESSAGE results#3756
TaprootFreak wants to merge 5 commits into
developfrom
fix/realunit-trace-template-exclude-audit

Conversation

@TaprootFreak

@TaprootFreak TaprootFreak commented May 23, 2026

Copy link
Copy Markdown
Collaborator

Symptom

The RealUnit tracing dashboard (polls /gs/logs with template=traces-by-message every ~5 s) saw 0 real traces. Reason: the endpoint emits its own audit line at verbose severity ([GsService] Log query by <user>: template=..., params={...}). With the dashboard's frequent polling, those self-emitted lines monopolised the 200-row default response, evicting actual traces.

Approaches considered and discarded

  • Blanket severityLevel filter — would silently hide ~100+ other legitimate verbose-producing services across the API. Too broad.
  • In-code redaction (redactAuditDto) — previous attempt on this branch. Rejected by senior-architect review:
    • leaks input length via [redacted-len=N]
    • denylist trap: every new free-text DTO field would silently re-introduce the self-match
    • brittle type (Partial<LogQueryDto>)
    • half-baked: didn't cover the catch-block failure-audit line, which also matches the same query

What remains

A single-line KQL post-filter in the TRACES_BY_MESSAGE template in gs.dto.ts:

| where not(message startswith "[GsService] Log query by ")
  • Both audit pathways (success-verbose + failure-info) share that prefix — one condition handles both.
  • The audit log itself stays intact and forensically searchable via other queries (e.g. TRACES_BY_OPERATION, App Insights direct).
  • Zero service-code mutation: gs.service.ts and gs.service.spec.ts are byte-identical to develop. The only diff in this PR is one KQL line plus an inline comment explaining the self-match concern.

Test plan

  • npx prettier --check "src/subdomains/generic/gs/**/*.ts" — clean
  • npx eslint "src/subdomains/generic/gs/**/*.ts" --no-fix — clean
  • npx jest --testPathPattern 'gs.service' — 29/29 green
  • npm run build — clean
  • git diff develop..HEAD -- src/subdomains/generic/gs/gs.service.ts — empty
  • git diff develop..HEAD -- src/subdomains/generic/gs/__tests__/gs.service.spec.ts — empty
  • Manual DEV verification: poll TRACES_BY_MESSAGE from RealUnit dashboard, confirm real traces visible again

Related

DFXswiss/services#1113

/gs/debug/logs writes a verbose audit entry on every call that
includes the messageFilter verbatim. With a high-frequency caller
(the RealUnit tracing dashboard polling at 5 s), these audit entries
recursively match the same messageFilter and crowd real traces out
of the 200-row response — the dashboard sees its own queries
instead of the data it asked for.

Filtering out severityLevel == 0 (Verbose) at the template level
keeps Info+ traces, which is what every consumer of this template
actually wants.
Reverts the earlier blanket severityLevel filter in TRACES_BY_MESSAGE
(which suppressed ~100 unrelated logger.verbose call sites from the
/gs/debug/logs results) and instead fixes the root cause: the audit
log emitted by gs.service stringified the full DTO, including
messageFilter and eventName verbatim — which a same-filter query then
matched against itself. Redacting those two free-text fields makes
self-match structurally impossible and keeps the verbose-level
visibility for legitimate verbose producers (Sift, Exchange,
liquidity-management, KYC, etc.).

Adds a regression spec that asserts the audit log argument never
contains a sentinel messageFilter value.
@TaprootFreak TaprootFreak changed the title fix(gs): exclude verbose audit logs from traces-by-message results fix(gs): redact user-supplied filter values in audit log May 23, 2026
Moves the messageFilter/eventName redaction out of the inline DTO
spread into a named helper method with JSDoc that flags the
self-match-recursion risk and reminds future contributors to redact
any new free-text DTO fields here too.

Adds spec coverage for eventName redaction and a positive assertion
that legitimate non-free-text fields (template, hours, user) remain
visible in the audit log.
Replaces the in-code redactAuditDto approach with a KQL-level filter
directly in the TRACES_BY_MESSAGE template:

    | where not(message startswith "[GsService] Log query by ")

Both the verbose success-audit and the info failure-audit emitted by
gs.service share that prefix, so a single line covers both. The audit
log itself stays intact and forensically searchable via other means.

Reverts the redactAuditDto helper, its JSDoc, the inline call site,
and the three audit-redaction spec tests introduced earlier on this
branch. gs.service.ts and the spec are byte-identical to develop;
the only remaining change in this PR is one line in gs.dto.ts plus
a comment that explains the self-match concern.
@TaprootFreak TaprootFreak changed the title fix(gs): redact user-supplied filter values in audit log fix(gs): exclude self-emitted audit lines from TRACES_BY_MESSAGE results May 23, 2026
@TaprootFreak TaprootFreak marked this pull request as ready for review May 23, 2026 15:20
@TaprootFreak TaprootFreak requested a review from davidleomay as a code owner May 23, 2026 15:20
@TaprootFreak

Copy link
Copy Markdown
Collaborator Author

Verworfen: bei 60s-Polling (statt 5s) im Dashboard reduziert sich die Audit-Last um Faktor 12 auf ~60/h, was bei normalem RealUnit-Traffic (~700 Traces/h) eine echte/audit-Ratio von ~85-90% in den 200 neuesten Rows ergibt. Der Frontend-Parser filtert [GsService]-Audit-Lines ohnehin schon raus (Regex matcht nur [RealUnitTrace]-Headlines). Damit ist die API-seitige KQL-Filter-Anpassung unnötig — Branch bleibt für eventuelle spätere Wiederaufnahme erhalten.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant