feat: add anonymous_id user enrichment to RUM and Logs#151
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4d07789047
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (not trackAnonymousUser) | ||
| clearDatadogAnonymousId() |
There was a problem hiding this comment.
Scrub cached last-view user data on opt-out
When a channel previously ran with anonymous tracking enabled, sendViewUpdate now persists the last view event with usr.anonymous_id for crash recovery. If the next launch passes trackAnonymousUser: false after a reportable crash, this branch only clears the registry, while RumCrashReporterTask.sendCrashReportFromViewEventFile still reads the cached _last_view_* event and copies lastViewEvent.usr into the crash payload. That lets the old anonymous id be uploaded after the integrator has opted out, so the opt-out path also needs to remove or scrub cached last-view events before crash reporting can send them.
Useful? React with 👍 / 👎.
4d07789 to
71c68d8
Compare
Mirror the browser SDK's anonymous-user tracking on Roku. - Add the `trackAnonymousUser` init config flag (default `true`). - Resolve a stable `anonymousId` once at init, before any agent/task starts: read it from the Roku registry (section "datadog", key "anonymous_id") or generate one with GetRandomUUID() and persist it, so it survives channel relaunches. Disabling tracking clears the persisted id. Stored in the immutable global `datadogAnonymousId`. - Add `identityStorage.bs` (registry read/write/clear helpers). - `getDatadogUserInfo(userInfo, anonymousId)` enriches the `usr` payload with `anonymous_id` only when the integrator hasn't supplied one, shallow-copying so the shared global user info is never mutated. - Route all `usr:` builders (logs, view, action, error, resource, vital) through the helper. Performance: the helper takes already-read values instead of touching the global node, so callers cache `anonymousId` once rather than reading it per event. On the RumAgent Task thread every `m.global` read is a cross-thread rendezvous; LogsAgent keeps its observer-cached `usr` path and reads no globals per log. Tests: getDatadogUserInfo enrichment/passthrough/mutation-safety, identityStorage registry round-trip, RUM view-event enrichment, and LogsAgent anonymous_id behavior. Docs added to README. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
71c68d8 to
0a732ac
Compare
What does this PR do?
Adds browser-SDK-style
anonymous_idenrichment to the Roku SDK so RUM and Logs events can be tied back to a stable, anonymous device identity across both sessions and channel launches.trackAnonymousUserinit configuration flag (defaulttrue).anonymous_idis persisted in the Roku registry (section"datadog", key"anonymous_id"), generate one viaroDeviceInfo.GetRandomUUID()and persist it back to the registry. This mirrors browser-sdk's cookie behavior — the id survives channel relaunches and reboots, scoped per-channel.trackAnonymousUser: falseis passed at init, any previously persistedanonymous_idis removed from the registry so the identifier does not outlive the integrator's consent signal.getDatadogUserInfo(global)helper enrichesusrpayloads withanonymous_idonly when not already set by the user, and only when tracking is enabled.usr:payload builders in Logs and RUM (view, action, error, resource, vital) now go through the helper.library/source/identityStorage.bsmodule wraps registry read/write/delete so future identity values can be persisted the same way.Motivation
Mirror the behavior already shipped in
browser-sdkso anonymous Roku sessions are attributable and consistent with other Datadog SDKs. The same precedence rules apply: a user-providedanonymous_idalways wins over the SDK-generated one, and explicit user opt-out (trackAnonymousUser: false) disables enrichment entirely and clears any persisted id. Persistence in the Roku registry is the closest analogue to a browser cookie: per-channel-sandboxed, survives reboots.Additional Notes
test/source/tests/Test__datadog.bscover the three precedence cases (enrich, preserve user value, opt-out) plus registry cleanup ontrackAnonymousUser: false.test/source/tests/logs/Test__LogsAgent.bsverify the helper is wired into log payloads.test/source/tests/rum/Test__datadog.bscover registry reuse (WhenInitialize_WithRegistryValue_ThenReuseAnonymousId) and first-launch generation/persistence (WhenInitialize_WithEmptyRegistry_ThenGenerateAndPersistAnonymousId). The sharedTearDownclears the registry key for isolation.dist/is regenerated and included in the commits, consistent with the repo's existing workflow.Review checklist (to be filled by reviewers)
🤖 Generated with Claude Code