Skip to content

ops(observability): audit_log_insert_failed metric (closes #3574)#3769

Merged
EmmaLouise2018 merged 2 commits into
mainfrom
EmmaLouise2018/check-issue-3574
May 1, 2026
Merged

ops(observability): audit_log_insert_failed metric (closes #3574)#3769
EmmaLouise2018 merged 2 commits into
mainfrom
EmmaLouise2018/check-issue-3574

Conversation

@EmmaLouise2018

Copy link
Copy Markdown
Contributor

Summary

  • Closes ops(observability): metrics counter for type_reclassification_log insert failures #3574. The audit-log insert helper (server/src/db/type-reclassification-log-db.ts) intentionally swallows DB errors so a failed audit write never blocks the caller's primary intent (member-profile save / crawler promote / backfill row). Until now, the only signal of a swallowed insert was a warn log line — fragile to alert on.
  • Adds a PostHog metric in the catch block: captureEvent("server-metrics", "audit_log_insert_failed", { source, error_class }). error_class is the 2-char SQLSTATE class (e.g. '23' for integrity violations, '08' for connection failures) — the class, not the full 5-char code, is what ops alerts on. Falls back to 'unknown' when the thrown error has no pg .code.
  • Pairs with feat(registry): type_reclassification_log table — audit trail for type transitions (closes #3550) #3567 (the table itself, merged today) and the future audit-log query admin UI, both of which assume audit-log volume is reliable. Ops can now alert on audit_log_insert_failed > 0 over 5m.

Why this metrics surface

The triage on #3574 noted there's no metrics.increment() helper in this repo — the canonical metrics layer is PostHog via captureEvent() (see server/src/middleware/request-metrics.ts:43). This PR uses that same pattern.

Test plan

  • npx vitest run tests/unit/type-reclassification-log-db.test.ts — 9/9 pass (6 existing + 3 new)
    • emits error_class: '23' from a code: '23505' error
    • falls back to error_class: 'unknown' for plain Error
    • does not emit on a successful insert
  • npm run typecheck — clean
  • npm run build — clean
  • precommit hook (full unit suite + dynamic-import check + callapi state-change + typecheck) — clean

Out of scope

  • Alerting policy / Grafana dashboard — runbook concern, per the issue.
  • A standalone metrics framework — this repo already has PostHog; no new infrastructure needed.

…ssification_log insert failure (closes #3574)

The audit-log insert helper intentionally swallows DB errors so observability
never blocks a profile save / crawler promote / backfill row. Until now the
only signal of a failed insert was a warn log line — too fragile to alert on.
The catch block now also fires a PostHog metric:

  captureEvent("server-metrics", "audit_log_insert_failed",
               { source, error_class })

error_class is the 2-char SQLSTATE class (e.g. '23' = integrity violation,
'08' = connection failure) or 'unknown' when the thrown error has no pg code.
The class — not the full 5-char code — is what ops alerts on.

Pairs with #3567 (the table itself) and the future audit-log query UI, both
of which assume audit-log volume is reliable.
@EmmaLouise2018 EmmaLouise2018 requested a review from bokelley as a code owner May 1, 2026 17:33
…ice (review nits)

Two follow-ups from review on PR #3769:

1. SQLSTATE length check is now strict (=== 5 instead of >= 2). A 5-char
   well-formed SQLSTATE yields its 2-char class; anything else is 'unknown'.
   The previous '>= 2' guard was inconsistent: a malformed 1-char code fell
   back to 'unknown' but a malformed 3-char code yielded a truncated 2-char
   "class" that wouldn't map to any real PostgreSQL class. Refuse ambiguous
   input — pick one shape and stick to it.

2. Added a comment next to the captureEvent call explaining why agent_url
   and member_id are not labels: unbounded cardinality would blow up event
   volume. The {source × error_class} cross product is the alertable shape;
   the warn log already carries per-row detail for forensics.

New test pins the malformed-code boundary: code: 'XYZ' → error_class:
'unknown' (not 'XY'). 10/10 unit tests pass.
@EmmaLouise2018 EmmaLouise2018 merged commit b9f3f11 into main May 1, 2026
14 checks passed
@EmmaLouise2018 EmmaLouise2018 deleted the EmmaLouise2018/check-issue-3574 branch May 1, 2026 20:27
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.

ops(observability): metrics counter for type_reclassification_log insert failures

1 participant