Skip to content

feat: supporting advanced trace cases#645

Open
abelonogov-ld wants to merge 18 commits into
mainfrom
docs/rn-distributed-tracing
Open

feat: supporting advanced trace cases#645
abelonogov-ld wants to merge 18 commits into
mainfrom
docs/rn-distributed-tracing

Conversation

@abelonogov-ld

Copy link
Copy Markdown
Contributor

Summary

  • Adds a distributed tracing cookbook for @launchdarkly/observability-react-native, the React Native analog of the existing .NET MAUI distributed tracing guide.
  • Recipes are adapted to the JS/OpenTelemetry API actually exposed by the RN SDK (LDObserve.startActiveSpan/startSpan/runWithHeaders/startWithHeaders/parseHeaders/getContextFromSpan, standard OTel Span operations, metrics/logs/errors).
  • Covers root/nested spans, manual HTTP spans, automatic fetch/XHR instrumentation, exception recording, correlated logs, explicit context propagation across async boundaries (the JS equivalent of .NET's AsyncLocal story), independent root spans, span events, and end-to-end mobile-to-backend trace linking via tracingOrigins.
  • Placed under guides/ (not docs/, which is gitignored and reserved for generated Typedoc output) and linked from the package README.

Notes

  • The original prompt referenced the react-native-ld-session-replay package, but that package has no tracing API — it is purely session replay/masking. The tracing API (and thus the true analog of the mobile-dotnet observability SDK) lives in observability-react-native, so the guide was added there.
  • The original .NET guide embeds a start-polling-trace.png screenshot; that section is described in prose here instead since no RN screenshot exists.

Test plan

  • Verify the guide renders correctly on GitHub (Markdown + mermaid diagrams).
  • Confirm the README "Guides" link resolves to guides/distributed-tracing.md.
  • Spot-check code snippets against the current LDObserve / Observe API surface.

Made with Cursor

Add a cookbook of distributed tracing patterns for the React Native
observability SDK, mirroring the existing .NET MAUI guide but adapted to
the JS/OpenTelemetry API (startActiveSpan/startSpan, explicit context
propagation across async boundaries, tracingOrigins-based mobile-to-backend
trace linking). Lives in guides/ since docs/ is reserved for generated
Typedoc output, and is linked from the package README.

Co-authored-by: Cursor <cursoragent@cursor.com>
@abelonogov-ld abelonogov-ld requested a review from a team as a code owner June 24, 2026 20:49
abelonogov-ld and others added 2 commits June 24, 2026 14:12
… guide

Document setting, reading, and updating W3C baggage and how it propagates
to backends via tracingOrigins, plus a note that baggage is not copied
onto spans automatically.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a Tracing tab to the session-replay example with a button per recipe
from the distributed tracing guide and a live output log, registering the
Observability plugin with tracingOrigins so the backend-propagation and
baggage recipes exercise real header injection.

Co-authored-by: Cursor <cursoragent@cursor.com>
abelonogov-ld and others added 3 commits June 24, 2026 14:42
Stop tracking the session-replay example's ios/Podfile.lock and Gemfile.lock,
which are regenerated per-machine and churn on every pod/bundle install. The
monorepo yarn.lock remains tracked for reproducible installs.

Co-authored-by: Cursor <cursoragent@cursor.com>
…s resource attributes

buildObservabilityResource strips the default service.name from the OTel
resource but never re-adds one from options, so exported spans, logs, and
metrics had an empty service.name (the value only flowed to Session Replay).

Populate service.name / service.version from ObservabilityOptions.serviceName
and serviceVersion in the shared resource builder so both init paths (LDClient
plugin and standalone LDObserve.init) emit a populated service identity.

Co-authored-by: Cursor <cursoragent@cursor.com>

@Vadman97 Vadman97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could note to @dyozie-ld that we should make a docs update based on some of this?

abelonogov-ld and others added 4 commits June 25, 2026 10:23
…-tracing

Bring in the launchdarkly-android-client-sdk bump (0.46.1).
abelonogov-ld and others added 7 commits June 25, 2026 10:34
Introduce a LaunchDarkly-owned SessionManager (LDSessionManager) that can
be seeded with an external session id, so the native instance can adopt a
session id created elsewhere (e.g. the JS SDK in a React Native app) and
report a single shared session.id across spans, logs, metrics, and replay.

- LDSessionManager: seedable session manager replicating OTel Android's
  rotation semantics (foreground never expires, background inactivity and
  max-lifetime rotation) and observer notifications.
- LDRumSessionManagerAccessor: same-package shim to call the package-private
  OpenTelemetryRumBuilder.setSessionManager, making our manager back the RUM
  SDK's session.id span/log appenders (single source of session identity).
- ObservabilityService: inject the custom manager, drop the old
  session-manager-bridge instrumentation and SessionConfig, drive the
  background-timeout from the app lifecycle, and read session.id from it.
- Thread an optional customSessionId through the Observability plugin and
  LDObserve.init for callers (RN integration to follow).

Co-authored-by: Cursor <cursoragent@cursor.com>
…on id

When a session id is supplied externally the caller owns the session
lifecycle, matching iOS's isCustomSession. Skip both background-inactivity
and max-lifetime rotation so the seeded id is used unchanged for the
lifetime of the manager.

Co-authored-by: Cursor <cursoragent@cursor.com>
…pendency

The OpenTelemetry Android `activity` instrumentation is always suppressed
(its app/activity lifecycle spans are superseded by our own), so the
dependency was dead weight. Remove it (also drops `common-api`) and keep
suppressInstrumentation("activity") as a defensive guard in case a host
reintroduces it transitively.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ound state

AppLifecycleTracker only reports genuine transitions (it suppresses the
initial replay and never emits a catch-up background), so an SDK init while
the app is already backgrounded left LDSessionManager stuck in FOREGROUND
and skipped background-inactivity rotation until the next stop/start cycle.
Query the process lifecycle at init and mark the manager backgrounded when
appropriate; a later genuine onStart settles it back to foreground.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ted-tracing

* feat/android-external-session-id:
  fix(observability-android): prime session manager with initial background state
  chore(observability-android): drop unused activity instrumentation dependency
  feat(observability-android): disable auto rotation for external session id
  feat(observability-android): support external session id
@abelonogov-ld abelonogov-ld changed the title docs(observability-react-native): add distributed tracing guide feat: supporting advanced trace cases Jun 25, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1a92ad8. Configure here.

?.takeIf { it.isNotBlank() }
this.customSessionId = options?.takeIf { it.hasKey("sessionId") }
?.getString("sessionId")
?.takeIf { it.isNotBlank() }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Native session id stale after rotation

Medium Severity

When session replay forwards the JS sessionId into the native Observability plugin, Android treats it as a custom session that never auto-rotates. The JS SessionManager can start a new session after a background timeout, but the native side keeps emitting spans and replay telemetry under the original id with no update path.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1a92ad8. Configure here.

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.

3 participants