Skip to content

WIP Traces#428

Open
abelonogov-ld wants to merge 93 commits intomainfrom
andrey/dotnet-traces
Open

WIP Traces#428
abelonogov-ld wants to merge 93 commits intomainfrom
andrey/dotnet-traces

Conversation

@abelonogov-ld
Copy link
Contributor

@abelonogov-ld abelonogov-ld commented Mar 24, 2026

Summary

How did you test this change?

Are there any deployment considerations?


Note

Medium Risk
Medium risk because it adds a new OpenTelemetry trace-export path from .NET to native (Android/iOS) and refactors plugin initialization/hook wiring, which can affect telemetry correctness and session replay linkage.

Overview
Adds .NET MAUI trace support by introducing an OpenTelemetry TracerProvider (LDTracer) and exporter (LDTraceExporter/TraceBuilderAdapter) that forwards completed Activity spans into the native SDK via new native tracer/SpanBuilder bridge types.

Expands the .NET native bridge to fully implement logs, errors, and metrics on Android/iOS (including attribute conversion/flattening), and refactors initialization by replacing NativePluginConnector with a centralized PluginOrchestrator plus updated hook exporters for observability and session replay.

Updates Android/iOS native layers to support the bridge (new com.launchdarkly.observability.bridge APIs, session replay afterIdentify proxy, wake-up/reload replay events, and bridge-supplied trace/span ID overrides in the span exporter), and refreshes the MAUI sample/docs (renamed README to Observability, new DialogsPage, richer log attributes, span examples, dependency/version bumps).

Written by Cursor Bugbot for commit d586f2e. This will update automatically on new commits. Configure here.

* main:
  feat: Optional Jet Compose (#402)
  feat: Android Incremental Image Diff compression (#390)
  chore: add CLAUDE.md (#398)
  chore: release main (#400)
  fix: correct react native session replay build step (#399)
  chore: release main (#396)
  fix: Android span e2e tests (#397)
  fix: improve network response capture (#379)

# Conflicts:
#	sdk/@launchdarkly/mobile-dotnet/.vscode/tasks.json
(cherry picked from commit f883e975ca79da891b4178d8a12e27868f0931eb)
* main:
  chore: release main (#401)
(cherry picked from commit 9901600)
* main:
  chore: release main (#406)
  feat: Make Android SDK35 compilable (#405)
* andrey/hooks:
  comment identify stuff
  fat working
  working
  can launch
@abelonogov-ld abelonogov-ld requested a review from a team as a code owner March 24, 2026 02:02
// put wake up in the try/catch do not break buffering logic
logger.error(e)
}
}
Copy link

Choose a reason for hiding this comment

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

Wake-up failure leaks payload ID counter increment

Low Severity

wakeUpEvents calls nextPayloadId() inside its own try-catch, so if the wake-up pushPayload fails, the exception is swallowed and the outer rollback logic never executes. This means payloadIdCounter keeps its incremented value even though the payload was never delivered, creating a gap in the sequence of payload IDs sent to the server.

Fix in Cursor Fix in Web

.anonymous(true)
.build()

//LDClient.get().identify(anonContext)
Copy link

Choose a reason for hiding this comment

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

Commented-out code and unused variable in e2e app

Low Severity

anonContext is constructed but only referenced in the commented-out LDClient.get().identify(anonContext) call. This is dead code that appears to be leftover debugging or testing scaffolding from development.

Fix in Cursor Fix in Web

Copy link

@cursor cursor bot left a comment

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 and found 2 potential issues.

There are 4 total unresolved issues (including 2 from previous reviews).

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.

#elif ANDROID
var nativeTracer = LDObserveBridgeAdapter.Tracer;
_adapter = nativeTracer != null ? new TraceBuilderAdapter(nativeTracer) : null;
#endif
Copy link

Choose a reason for hiding this comment

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

Exporter singleton permanently drops spans if initialized early

High Severity

LDTraceExporter captures the native tracer reference in its constructor and stores it in a readonly field. Since it's created inside the LDTracer lazy singleton, this constructor runs exactly once. If the native SDK hasn't finished initializing when LDTracer.Instance is first accessed, _adapter will be null permanently, and all C#-originated spans will be silently dropped forever (the Export method returns ExportResult.Success even when _adapter is null). The adapter lookup needs to be deferred to export time or support re-initialization.

Additional Locations (1)
Fix in Cursor Fix in Web

}

otelRUM = rumBuilder.build()
sessionManager = capturedSessionManager!!
Copy link

Choose a reason for hiding this comment

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

Force-unwrap on nullable sessionManager may crash

Medium Severity

capturedSessionManager!! will throw a NullPointerException if the ld-session-manager-bridge instrumentation's install callback was never invoked during rumBuilder.build(). If OpenTelemetry RUM skips the instrumentation for any reason (e.g., configuration change, initialization error), this causes an unrecoverable crash at startup. A safer approach would handle the null case gracefully.

Fix in Cursor Fix in Web

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.

1 participant