Skip to content

fix(aspnetcore): add request context to application spans - #347

Merged
pauldambra merged 2 commits into
mainfrom
posthog/aspnet-activity-request-context
Oct 23, 2026
Merged

pauldambra merged 2 commits into
mainfrom
posthog/aspnet-activity-request-context

Conversation

@pauldambra

Copy link
Copy Markdown
Member

[Robot] Prepared with PostHog Desktop on behalf of @pauldambra.

💡 Motivation and Context

Developers need to connect browser sessions to ASP.NET Core request traces. Request middleware currently applies browser context to events but leaves application spans without those IDs.

  • Add missing sessionId and posthogDistinctId tags to the incoming request activity, even when it started before middleware runs.
  • Add the same context to child activities through an internal ActivityListener. The application keeps its sampling decisions, provider, processors, and exporters.
  • Preserve explicit activity tags and keep request context separate across concurrent requests. Reject ended request scopes retained by background tasks.
  • Keep OpenTelemetry optional and public APIs unchanged. Document child-activity setup and include patch changesets for both affected packages.

Child enrichment requires the host builder's AddPostHog() or service configuration with UseAspNetCore(), followed by UsePostHogRequestContext(). Manual client-only middleware setup still runs and enriches the active request activity. The SDK does not add a native span API or trace exporter.

Related: SDK span context tracking. This PR uses the existing span attribute names from the traces spec. The broader application-owned OpenTelemetry acceptance contract remains under discussion in that issue.

💚 How did you test it?

  • TDD: the new request/child span cases failed before the implementation and pass after it.
  • Parameterized pipeline tests cover native activities, ActivitySource children, explicit tags, absent/invalid/disabled headers, concurrent requests, error cleanup, late export, ended background context, sampling, and listener disposal.
  • Locked restore, release solution build, and bin/fmt --check pass.
  • ASP.NET Core: 64 passed. Core net8.0: 1,235 passed, two skipped. AI: 19 passed. Core netcoreapp3.1: 1,225 passed, two skipped.
  • Both skips are existing cancellation cases marked as needing integration tests. Tests use SDK 10.0.402 and runtime 10.0.13 through the repository's roll-forward setting; the legacy target uses x64.

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

A patch changeset was written in the repository's existing format for PostHog and PostHog.AspNetCore.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

GPT-6 (Codex), using PostHog Desktop, shell tools, and the GitHub CLI. The implementation uses the supported .NET Activity API to keep OpenTelemetry optional. A service-owned listener has no sampling delegates and is disposed with the host service provider. Human review is required.


Created with PostHog Desktop

Generated-By: PostHog Desktop
Task-Id: 5681be44-4986-48db-b140-1bda88f75f96
@pauldambra
pauldambra requested a review from a team as a code owner October 16, 2026 18:30
@pauldambra pauldambra self-assigned this Oct 16, 2026
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

posthog-dotnet Compliance Report

Date: 2026-10-18T10:54:15.375633+00:00
Duration: 124764ms

✅ All Tests Passed!

47/47 tests passed


Capture Tests

✅ 30/30 tests passed

View Details
Test Status Duration
Format Validation.Event Has Required Fields ✅ 222ms
Format Validation.Event Has Uuid ✅ 123ms
Format Validation.Event Has Lib Properties ✅ 109ms
Format Validation.Distinct Id Is String ✅ 112ms
Format Validation.Token Is Present ✅ 109ms
Format Validation.Custom Properties Preserved ✅ 114ms
Format Validation.Event Has Timestamp ✅ 109ms
Format Validation.Non Utc Event Timestamp Is Converted To Utc ✅ 118ms
Retry Behavior.Retries On 503 ✅ 8120ms
Retry Behavior.Does Not Retry On 400 ✅ 2116ms
Retry Behavior.Does Not Retry On 401 ✅ 2111ms
Retry Behavior.Respects Retry After Header ✅ 8118ms
Retry Behavior.Implements Backoff ✅ 22130ms
Retry Behavior.Retries On 500 ✅ 6116ms
Retry Behavior.Retries On 502 ✅ 6117ms
Retry Behavior.Retries On 504 ✅ 6116ms
Retry Behavior.Max Retries Respected ✅ 22133ms
Deduplication.Generates Unique Uuids ✅ 114ms
Deduplication.Preserves Uuid On Retry ✅ 6116ms
Deduplication.Preserves Uuid And Timestamp On Retry ✅ 13126ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 6120ms
Deduplication.No Duplicate Events In Batch ✅ 114ms
Deduplication.Different Events Have Different Uuids ✅ 109ms
Compression.Sends Gzip When Enabled ✅ 108ms
Batch Format.Uses Proper Batch Structure ✅ 108ms
Batch Format.Flush With No Events Sends Nothing ✅ 104ms
Batch Format.Multiple Events Batched Together ✅ 112ms
Error Handling.Does Not Retry On 403 ✅ 2110ms
Error Handling.Does Not Retry On 413 ✅ 2111ms
Error Handling.Retries On 408 ✅ 6115ms

Feature_Flags Tests

✅ 17/17 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id ✅ 139ms
Request Payload.Flags Request Uses V2 Query Param ✅ 108ms
Request Payload.Flags Request Hits Flags Path Not Decide ✅ 108ms
Request Payload.Flags Request Omits Authorization Header ✅ 109ms
Request Payload.Token In Flags Body Matches Init ✅ 107ms
Request Payload.Groups Round Trip ✅ 112ms
Request Payload.Groups Default To Empty Object ✅ 108ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False ✅ 108ms
Request Payload.Disable Geoip Omitted Defaults To False ✅ 109ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key ✅ 107ms
Request Lifecycle.No Flags Request On Init Alone ✅ 3ms
Request Lifecycle.No Flags Request On Normal Capture ✅ 108ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests ✅ 212ms
Request Lifecycle.Mock Response Value Is Returned To Caller ✅ 112ms
Retry Behavior.Retries Flags On 502 ✅ 1111ms
Retry Behavior.Retries Flags On 504 ✅ 1109ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event ✅ 210ms

@pauldambra

pauldambra commented Oct 17, 2026 •

Copy link
Copy Markdown
Member Author

Note

🤖 Automated comment by QA Swarm — not written by a human

Verdict: ✅ APPROVE (privacy round @ deb7271)

Middleware now sets a request-scope flag from the client's construction-time disabled state. Disabled clients add no activity tags. No public API changes.

Checks

Independent review accepted the change. Known limit: an app that wraps IPostHogClient in its own type keeps the earlier tagging behavior.

Earlier rounds

Verdict: ✅ APPROVE (round 1 @ 57bcd38)

No remaining actionable finding in the reviewed change. Activity identity precedence, request cleanup, and host-owned listener lifetime were checked.

Key findings

  • None remain in this revision. Existing focused tests and completed independent review coverage were reused.
  • Human review and the shared specification decision remain required. This comment does not approve a merge or release.

Convergence

No remaining duplicate finding.

Reviewer summaries

Reviewer Assessment
Router (gpt-6-sol) Complexity HIGH, confidence HIGH. Completed independent API and concurrency coverage was reused. No further delegation was needed.

Automated by QA Swarm. Human review is required. This comment does not approve a merge or release.

Generated-By: PostHog Desktop
Task-Id: bfd18848-e498-4352-a58a-b9ba85de4198

@marandaneto marandaneto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good; no qualifying findings. Verdict: correct.

@pauldambra
pauldambra merged commit d9225f7 into main Oct 23, 2026
21 checks passed
@pauldambra
pauldambra deleted the posthog/aspnet-activity-request-context branch October 23, 2026 13:00
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.

2 participants