From ea2750cc3def6f20cc04ccab2653a228852280b1 Mon Sep 17 00:00:00 2001 From: Sagnik Ghosh Date: Thu, 23 Jul 2026 23:37:45 +0530 Subject: [PATCH] fix(ingester): template underscore-glued ids in message normalization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit \b never fires between _ and a digit (both word chars), so ids like prj_1013 / user_42 / order_9f3ac2d144 escaped NUMBER_RE and LONG_HEX_RE entirely — one defect fragmented into an issue per entity id and never crossed the incident threshold (observed live: 15 events → 15 one-event issues, no incident). Underscore-glued numbers/hex now template to _/_; letter-glued tokens (sha256, utf8) stay literal on purpose. Generated-By: PostHog Code Task-Id: 6e0925be-ecd5-42ee-9fde-895c4678bde4 --- packages/otlp-ingester/src/fingerprint.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/otlp-ingester/src/fingerprint.ts b/packages/otlp-ingester/src/fingerprint.ts index a8b07e3..40b15f7 100644 --- a/packages/otlp-ingester/src/fingerprint.ts +++ b/packages/otlp-ingester/src/fingerprint.ts @@ -17,6 +17,14 @@ const LONG_HEX_RE = /\b[0-9a-f]{8,}\b/gi; // template too, or per-value messages fragment into separate fingerprints. const NUMBER_RE = /\b\d+(\.\d+)?/g; const QUOTED_RE = /(["'`])(?:\\.|(?!\1).)*\1/g; +// `\b` never fires between `_` and a digit (both are word chars), so +// underscore-glued ids — "prj_1013", "user_42", "order_9f3ac2d144" — escape +// NUMBER_RE/LONG_HEX_RE entirely and fragment one defect into an issue per +// id. Template the value after the underscore explicitly. (Letter-glued +// digits like "sha256"/"utf8" stay literal on purpose — those are usually +// meaningful tokens, not per-entity ids.) +const UNDERSCORE_HEX_RE = /_[0-9a-f]{8,}\b/gi; +const UNDERSCORE_NUMBER_RE = /_\d+(\.\d+)?\b/g; export function normalizeMessage(message: string): string { return message @@ -24,6 +32,8 @@ export function normalizeMessage(message: string): string { .replace(QUOTED_RE, "") .replace(UUID_RE, "") .replace(LONG_HEX_RE, "") + .replace(UNDERSCORE_HEX_RE, "_") + .replace(UNDERSCORE_NUMBER_RE, "_") .replace(NUMBER_RE, "") .replace(/\s+/g, " ") .trim();