feat(node): add a beforeSpanSend hook - #4584
Draft
turnipdabeets wants to merge 3 commits into
Draft
Conversation
Contributor
Contributor
|
Size Change: +4.17 kB (+0.02%) Total Size: 20.2 MB 📦 View Changed
ℹ️ View Unchanged
|
23 tasks
turnipdabeets
force-pushed
the
feat/traces-node-mvp
branch
from
August 21, 2026 12:45
a9ff420 to
5c7301c
Compare
turnipdabeets
force-pushed
the
feat/traces-before-span-send
branch
from
August 21, 2026 12:45
9d824fd to
2f1c9aa
Compare
Runs on every finished span before it is queued: scrub attributes, or return null to drop it. A throwing hook drops the span, since it is the documented scrubbing point.
A frozen or rebuilt record could throw out of end() into application code, and a hook-written timestamp could poison the whole batch it shipped in.
turnipdabeets
force-pushed
the
feat/traces-node-mvp
branch
from
August 24, 2026 11:25
e36495f to
9365a6c
Compare
turnipdabeets
force-pushed
the
feat/traces-before-span-send
branch
from
August 24, 2026 11:25
2f1c9aa to
2204f06
Compare
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.
Problem
Stacked on #4579 — review that first.
Spans carry whatever attributes the application puts on them, and a service that instruments its HTTP layer will end up with headers, query strings and user fields on those spans. There is currently no way to strip any of it before it leaves the process, and no way to drop a span you don't want exported at all (health checks, noisy internal polling).
Implements the
Gating and beforeSpanSendrequirement of the traces capability spec.Changes
Adds
traces.beforeSpanSend— a hook that runs on every finished span before it is queued.Behaviour, each point taken from a spec scenario:
nullto drop the span. Nothing is enqueued and no error surfaces.userId: 42, not{ intValue: "42" }. It runs after auto-context attributes are attached, soposthogDistinctIdandsessionIdare visible and scrubbable.traceId,spanIdandparentSpanIdare typedreadonly, and an assignment that slips past the type system is reverted with a debug warning — rewriting ids after children have already shipped corrupts parentage.beforeSendfail-open rule: the hook is the documented scrubbing point, so a broken scrubber must not leak an unscrubbed record.nullstops the chain.Reviewer notes
beforeSpanSend. Only then does the queue-depth check run, so a dropped span never counts against the queue."type": "TracesConfig"by name without expanding the interface, so adding a field to it produces no diff. Worth knowing thatbeforeSpanSendwon't appear in the generated reference until that generator expands config types.SpanRecord(public shape) is exported from@posthog/types, deliberately not core's internal record, which also carriestraceState.Verification
Six core tests covering each spec scenario, plus two node-level tests exercising the hook through the real client (scrubbing an attribute, dropping a health-check span).
packages/core1003 pass,packages/node951 pass, both build clean, lint clean.Release info Sub-libraries affected
Libraries affected
@posthog/coreis also bumped (minor); it has no checkbox above.Checklist
Purely additive: one new optional config field and two new exported types. No behaviour change when
beforeSpanSendis unset — the chain short-circuits on an empty array.If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Built with Claude Code, directed by @turnipdabeets, against the
Gating and beforeSpanSendrequirement in the traces capability spec.Before writing anything I checked whether the spec had unmerged updates, since the shape of this hook is entirely spec-driven: no open PR in
PostHog/sdk-specstouches traces, and the live spec is byte-identical to the version the MVP was reviewed against (last modified 2026-07-31). So this is built against settled contract, not a moving one.The one judgement call worth review is fail-closed on a throwing hook. It contradicts how
beforeSendbehaves for logs, which fails open and sends the record anyway. The spec calls this divergence out explicitly and ties it to the scrubbing designation, and I followed it — but it does mean a buggy hook silently costs you spans, so it is worth a second opinion.