feat: Support clicks and custom event tracing#432
feat: Support clicks and custom event tracing#432SpennyNDaJets wants to merge 4 commits intomainfrom
Conversation
| export const LD_INITIALIZE_EVENT = '$ld:telemetry:session:init' | ||
| export const LD_TRACK_EVENT = '$ld:telemetry:track' | ||
| export const LD_TRACK_SPAN_NAME = 'launchdarkly.track' |
There was a problem hiding this comment.
How the name will be displayed in traces
| }) | ||
| } | ||
|
|
||
| this.observe?.recordLog('LD.track', 'info', trackAttrs) |
There was a problem hiding this comment.
Do we still want a log?
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
| private _productAnalyticsEvents(): ProductAnalyticsEvents { | ||
| const pa = this._options?.productAnalytics | ||
| if (pa === false) { | ||
| return {} |
There was a problem hiding this comment.
Disabling product analytics still tracks clicks and page views
Medium Severity
When productAnalytics is false, _productAnalyticsEvents() returns {} (empty object). Downstream consumers check config.productAnalyticsEvents?.clicks !== false and config.productAnalyticsEvents?.pageViews !== false, which both evaluate to undefined !== false → true. This means click tracking and page view tracking remain enabled even when the user explicitly opts out by setting productAnalytics: false. The empty object needs to explicitly set clicks: false, pageViews: false, and trackEvents: false for the opt-out to propagate correctly.
Additional Locations (1)
| } | ||
| } | ||
| return paEvents | ||
| } |
There was a problem hiding this comment.
Duplicated _productAnalyticsEvents method across two files
Low Severity
_productAnalyticsEvents() is implemented identically in both ObserveSDK and the Highlight client class. This duplication means any bug fix (such as the productAnalytics: false issue) needs to be applied in two places, increasing the risk of divergent behavior over time. Extracting this into a shared utility function would reduce maintenance burden.
Additional Locations (1)
| @@ -45,8 +45,13 @@ export const FEATURE_FLAG_VARIATION_INDEX_ATTR = `${FEATURE_FLAG_SCOPE}.result.v | |||
| export const FEATURE_FLAG_APP_ID_ATTR = `${LD_SCOPE}.application.id` | |||
| export const FEATURE_FLAG_APP_VERSION_ATTR = `${LD_SCOPE}.application.version` | |||
|
|
|||
| export const PRODUCT_ANALYTICS_SCOPE = 'product_analytics' | |||
| export const PRODUCT_ANALYTICS_CONTEXT_ATTR = `${PRODUCT_ANALYTICS_SCOPE}.context_keys` | |||
There was a problem hiding this comment.
question: Do we want the context information under the product_analytics scope? At least in a spans attributes.
I imagine the context being a more generic attribute which we can add to spans across various use cases, so I prefer not locking it into PA even though it fits for this instance.
Maybe context.context_keys.<key>?
| * User interaction instrumentation event names to record. | ||
| * Defaults to 'click', 'input', 'submit' window events. | ||
| */ | ||
| eventNames?: EventName[] |
There was a problem hiding this comment.
Double checking, this is ok to remove?


Summary
Support tracing for the following product analytics events
Make sure to add the LD context to each of these traces
Note:
How did you test this change?
https://www.loom.com/share/e112659086f94a228279a97cc2b690b7
Are there any deployment considerations?
Breaking change: removal of event_names
Note
Medium Risk
Medium risk because it changes the OpenTelemetry instrumentation surface area (removes
otel.eventNamesand adds new history/location patching) and alters what events/spans are emitted, which can affect downstream analytics and performance.Overview
Adds product analytics tracing to the observability SDK: click spans (with full URL), page-view spans via new
LocationChangeInstrumentation, and optionalLD.trackspans controlled by a newproductAnalyticsoption.Removes support for configuring user-interaction spans via
otel.eventNames, and threads LaunchDarkly context keys into these product-analytics spans/logs by persisting context keys onafterIdentifyand attaching them to click/page-view/track spans.Updates the React Router e2e app to exercise the new behavior (new
/ldclientand/ldclient-lazyroutes/pages, plus updated staging OTLP/backend endpoints and anonymous LD context).Written by Cursor Bugbot for commit 1a76688. This will update automatically on new commits. Configure here.