feat(traces): wire tracing into the client - #957
Draft
turnipdabeets wants to merge 2 commits into
Draft
turnipdabeets wants to merge 2 commits into
turnipdabeets wants to merge 2 commits into
Conversation
Contributor
posthog-python Compliance ReportDate: 2026-09-15 22:09:37 UTC ✅ All Tests Passed!111/111 tests passed Capture_V1 Tests✅ 94/94 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
|
Contributor
Prompt To Fix All With AI### Issue 1
posthog/client.py:2685-2688
**Exit flush exceeds its deadline**
If thread creation is rejected during interpreter shutdown, this fallback runs the span flush synchronously. The exporter permits its first request even when no budget remains, and that request uses the client's timeout (15 seconds by default). Each client can therefore delay process exit well beyond the shared one-second deadline. Use a worker started before interpreter shutdown for exit flushing rather than falling back to synchronous network I/O, and test the rejected-thread path with a slow request.
### Issue 2
posthog/client.py:2514-2519
**Tracing initialization races with shutdown**
If shutdown runs after the initial state check but before the pipeline assignment, it sees `_traces is None` and completes without closing tracing. Initialization then publishes an open pipeline, and ending the span can start background exports after shutdown has returned. Subsequent shutdown calls skip cleanup because it is already marked complete. Coordinate pipeline initialization and shutdown with shared synchronization so shutdown cannot miss an in-progress initialization.
### Issue 3
posthog/client.py:2278-2281
**Fork cleanup restores inherited spans**
Setting the active ContextVar to `None` does not invalidate tokens held by inherited spans. When a process forks inside nested span blocks, exiting the inherited inner block in the child resets its old token and restores the parent process's outer span. Subsequent child spans then attach to that inherited span, violating fork isolation. Create a fresh active-span ContextVar in the child and rebind the pipeline to it, leaving inherited handles attached to the old variable. Add a nested-span fork test that checks parenting after the inner block exits.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "feat(traces): wire tracing into the clie..." | Re-trigger Greptile |
This was referenced Sep 14, 2026
turnipdabeets
force-pushed
the
traces/09-client-wiring
branch
from
September 14, 2026 22:58
d7fda59 to
e0fb116
Compare
turnipdabeets
added this pull request to stack #958
September 14, 2026 23:03
turnipdabeets
force-pushed
the
traces/09-client-wiring
branch
from
September 15, 2026 14:09
e0fb116 to
6b3c45c
Compare
turnipdabeets
force-pushed
the
traces/09-client-wiring
branch
2 times, most recently
from
September 15, 2026 14:25
be93a2c to
e254ad7
Compare
Makes tracing usable. Adds the `traces` client option (tracing stays off until it is set), Client.start_span / get_active_span and their posthog module-level counterparts, with the active span scoped per client so two clients never parent to each other's spans. flush() drains spans alongside events within the same budget; shutdown() gives queued spans a final flush of up to 30 s and warns about any it discards; an exit flush bounded by the existing exit deadline covers scripts that never call shutdown(), and a forked child drops the parent's spans. Export failures, limits and the hook are documented on the option. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TkZAsCciW4PV8ZdcCHmAbA
Shutdown reads the pipeline under the same lock initialization publishes it with, so an initialization in flight is either closed by shutdown or sees the request and stays off. A forked child gets a fresh active-span variable: an inherited handle exiting in the child resets the old one, which would have restored the parent process's outer span.
turnipdabeets
force-pushed
the
traces/09-client-wiring
branch
from
September 15, 2026 22:04
e254ad7 to
2597c0e
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.
💡 Motivation and Context
Makes tracing usable. Adds the
tracesclient option (tracing stays off until it is set),Client.start_span/get_active_spanand theirposthogmodule-level counterparts, with the active span scoped per client so two clients never parent to each other's spans.flush()drains spans alongside events within the same budget.shutdown()gives queued spans a final flush of up to 30 s and warns about any it discards.shutdown(), and a forked child drops the parent's spans.Export failures, limits and the hook are documented on the option. Includes the changeset.
Stack (PR 9 of 9, based on
traces/08-before-span-send):traces/01-ids-traceparenttraces/02-otlp-encodingtraces/03-span-handlestraces/04-transporttraces/05-pipelinetraces/06-exporttraces/07-span-limitstraces/08-before-span-sendtraces/09-client-wiring← this PR💚 How did you test it?
Unit tests in
posthog/test/tracing/test_client_traces.pycover the option, the client and module APIs, per-client active spans, flush, shutdown, exit flush and fork. The wholeposthog/test/tracingsuite was run on the rebased stack tip.📝 Checklist
If releasing new changes
sampo addto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Implemented with Claude Code (Claude Opus 5) against the traces spec, one commit per slice so each PR reviews on its own. Rebased onto main and opened as a stacked draft in a later Claude Code session (Claude Fable 5.1).
🤖 Generated with Claude Code
https://claude.ai/code/session_012o7CtHLfcypjmXL7g9ZGRC