Status Aware Error Sampling for OpenTelemetry - #285
Merged
trinachoudhury1mg merged 8 commits intoAug 24, 2026
Conversation
…catalyst-core into feature/suspense-vite-fixes-v17
|
DeputyDev will no longer review pull requests automatically.To request a review, simply comment #review on your pull request—this will trigger an on-demand review whenever you need it. |
20 tasks
…nfig Re-enable OTEL_ENABLE guard, fix skipPromotionCodes for 5xx codes, route promoted spans through the batch processor for backpressure, exclude bot traffic by default, and document the config in README/JSDoc.
vishalpolley-1mg
changed the base branch from
feature/suspense-vite-fixes-v17
to
fix/react-router-v7-upgrade-mweb-master
August 17, 2026 09:42
…tata1mg/catalyst-core into feature/status-aware-observability
…own hygiene
Excludes 4xx from isRootError so exceptions on 4xx paths promote at rate4xx not rate5xx, restricts hasChildError to actual child spans (closing a skipPromotionCodes bypass), gates the handled-errors branch to a real 2xx range plus !isSkipped, adds warn/debug logging around buffer eviction, and clears buffer/promotedTraces on shutdown().
trinachoudhury1mg
approved these changes
Aug 24, 2026
trinachoudhury1mg
merged commit Aug 24, 2026
231dcc0
into
tata1mg:fix/react-router-v7-upgrade-mweb-master
1 check passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR implements Status Aware Error Sampling natively in the
catalyst-coreOpenTelemetry integration (src/otel.js).In high-throughput environments operating at low head-sampling rates (e.g. 1%), standard head-sampling discards 99% of all traces, resulting in the loss of 99% of error traces (4xx and 5xx). This feature introduces a two-stage sampling flow that defers the export decision until a request finishes, allowing the system to selectively promote and export error traces at independent rates (typically 100% for 5xx and 10% for 4xx) without inflating successful trace volume or incurring excessive memory overhead.
The implementation is fully backwards-compatible and operates as an opt-in feature under the
errorSamplingconfiguration block.Key Features & Components
1. Custom Sampler: StatusAwareSampler
RECORD(instead ofNOT_RECORD). This instructs the SDK to build spans in memory so they can be analyzed upon request completion.0–12(first 48 bits) of thetraceIdhex string to evaluate the head-sampling probability.2. Custom Processor: PromotingSpanProcessor
SAMPLEDbit set) straight to the internalBatchSpanProcessorto preserve standard low-latency batch exports.RECORDonly) in an in-memory Map keyed bytraceId.http.response.is_bot: trueare excluded from every promotion rule below by default (PROMOTE_BOT_TRAFFIC), so bot-triggered errors can't inflate promoted volume unless explicitly opted in.RATE_5XX(typically 100%). Evaluated using characters12–24of thetraceIdstring.SKIP_PROMOTION_CODESis now consulted here too, not just for 4xx — gateway timeouts (504/524/598/599) are correctly excluded instead of always promoting anyway.RATE_4XX(excluding configured timeouts/gateway noise).BatchSpanProcessorused for head-sampled traffic (batchProcessor.onEnd()) rather than exported directly. A burst of promotions during an incident queues and batches like any other traffic instead of opening a flood of individual export calls against the collector. Trade-off: promoted spans export on the processor's next batch flush (scheduledDelayMillis, default ~5s) rather than instantly — tunable viabatchProcessorConfig.traceIdsso that asynchronous child spans completing after the root span are still successfully tagged and routed for export.init()registers a global OTEL error handler (setGlobalErrorHandler) that logs export failures — collector down, batch rejected, etc. — through the app logger, for both normal and promoted traffic, instead of failing silently.1024traces in the buffer to prevent OOM errors.Configuration Reference
You can activate the feature by passing the
errorSamplingblock toOtel.init:Full config reference, including all defaults, is now documented via JSDoc on
init()insrc/otel.js, and in a new "Observability" section inREADME.md.Fixes since the initial implementation
A follow-up audit surfaced several issues, all addressed in this PR:
OTEL_ENABLEopt-in guard ininit(), which had been temporarily commented out during development — without it, the SDK would initialize unconditionally in every environment.SKIP_PROMOTION_CODES: the skip check previously only gated the 4xx branch, so 4 of its 5 default entries (504/524/598/599) were unreachable and got promoted anyway despite being configured to skip.PROMOTE_BOT_TRAFFICto keep bot traffic from inflating promoted volume by default.Testing & Verification Done
traceFlags: 1(SAMPLED), and exported to Jaeger.mwebanddwebapps, confirming successful traces are exported according to the sampling rate, while 4xx and 5xx errors are successfully promoted and tagged with the"promoted": trueattribute.