Skip to content

Comments

[Profiling] Add action and vital metadata to profiles#4148

Open
MandragoreVR wants to merge 5 commits intomainfrom
teo.chaillou/RUM-14305-browser-add-action-and-vital-metadata-to-profiles
Open

[Profiling] Add action and vital metadata to profiles#4148
MandragoreVR wants to merge 5 commits intomainfrom
teo.chaillou/RUM-14305-browser-add-action-and-vital-metadata-to-profiles

Conversation

@MandragoreVR
Copy link
Collaborator

@MandragoreVR MandragoreVR commented Feb 6, 2026

Motivation

To enable profiling aggregation on the backend for vitals and actions, we want to add vitals and actions data to the metadata of profiling events.

This PR adds these entries to the profiling events metadata.

Changes

  • Create a vitalHistory next to the profiler that catches vital events from the life cycle and stores them in the history
    • Vital events are currently only sent in the lifecycle when they end. However, one vital event might span over multiple profiles, so the profile where this vital event starts must be tagged with this vital event too.
      • This PR defines the id of duration vitals when they start instead of when they end, and adds a new lifecycle event to broadcast vitals when they start
      • Note: this will not cause issues if the vital doesn't end, because this is only used to tag profile events, so in the worst case, the id of this vital will not be used
  • Same thing for the actions: creation of an actionHistory
    • the id of the action was created on action start, but not returned by the event tracker, so I changed that to make the start method of the event tracker return the stored data
  • Update the build of a profile's attributes to add actions and vitals
    • update profiler's tests to make sure vitals and actions are collected

Test instructions

  • In the file sandbox/react-app/main.tsx, add:
profilingSampleRate: 100,
  site: 'datadoghq.com',
  service: 'sandbox-react-app',
  env: 'development',
  beforeSend: () => false,

to the SDK configuration, and add

  useEffect(() => {
    datadogRum.startDurationVital('test vital')

    const timeout = setTimeout(() => {
      datadogRum.stopDurationVital('test vital')
    }, 1000)

    return () => {
      clearTimeout(timeout)
    }
  }, [])

before the return of the Layout function to have a vital that will be displayed in the collected ones.

  • Run yarn dev and go to localhost:8080/react-app
  • Wait for a request to https://browser-intake-datadoghq.com/api/v2/profile in the network tab (profiles usually last one minute, so this might not come instantly, but you can also edit the constant collectIntervalMs in profiler.ts to make it faster)
  • Look at the payload, that contains two big objects.
    • The first one should contain the fields "action" and "vital", both with an object of the shape { "id": string[], "label": string[] }
    • The second one should contain the fields "action" and "vitals" with the following shape:
image

Checklist

  • Tested locally
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

@MandragoreVR MandragoreVR self-assigned this Feb 6, 2026
@github-actions
Copy link

github-actions bot commented Feb 6, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@cit-pr-commenter-54b7da
Copy link

cit-pr-commenter-54b7da bot commented Feb 6, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 171.96 KiB 172.07 KiB +110 B +0.06%
Rum Profiler 4.67 KiB 6.20 KiB +1.53 KiB +32.78%
Rum Recorder 24.72 KiB 24.72 KiB 0 B 0.00%
Logs 56.29 KiB 56.29 KiB 0 B 0.00%
Flagging 944 B 944 B 0 B 0.00%
Rum Slim 127.73 KiB 127.84 KiB +112 B +0.09%
Worker 23.63 KiB 23.63 KiB 0 B 0.00%
🚀 CPU Performance
Action Name Base CPU Time (ms) Local CPU Time (ms) 𝚫%
addglobalcontext N/A 0.005 N/A
addaction N/A 0.0141 N/A
adderror N/A 0.0135 N/A
addtiming N/A 0.0027 N/A
startview N/A 0.0136 N/A
startstopsessionreplayrecording N/A 0.0007 N/A
logmessage N/A 0.0188 N/A
🧠 Memory Performance
Action Name Base Memory Consumption Local Memory Consumption 𝚫
addglobalcontext N/A 26.57 KiB N/A
addaction N/A 110.66 KiB N/A
addtiming N/A 26.99 KiB N/A
adderror N/A 118.54 KiB N/A
startstopsessionreplayrecording N/A 25.68 KiB N/A
startview N/A 510.12 KiB N/A
logmessage N/A 44.74 KiB N/A

🔗 RealWorld

@MandragoreVR MandragoreVR force-pushed the teo.chaillou/RUM-14305-browser-add-action-and-vital-metadata-to-profiles branch 2 times, most recently from 59aa5b7 to f709051 Compare February 12, 2026 13:32
@MandragoreVR MandragoreVR marked this pull request as ready for review February 12, 2026 13:33
@MandragoreVR MandragoreVR requested a review from a team as a code owner February 12, 2026 13:33
@datadog-official
Copy link

datadog-official bot commented Feb 12, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 88.06%
Overall Coverage: 77.21% (+0.03%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 5e88cac | Docs | Datadog PR Page | Was this helpful? Give us feedback!

@MandragoreVR MandragoreVR marked this pull request as draft February 17, 2026 15:51
@MandragoreVR MandragoreVR force-pushed the teo.chaillou/RUM-14305-browser-add-action-and-vital-metadata-to-profiles branch from f709051 to 2d17fef Compare February 17, 2026 22:25
@MandragoreVR MandragoreVR force-pushed the teo.chaillou/RUM-14305-browser-add-action-and-vital-metadata-to-profiles branch from 5059362 to ac62ddd Compare February 18, 2026 17:14
@MandragoreVR MandragoreVR marked this pull request as ready for review February 18, 2026 17:28
Copy link
Collaborator

@thomasbertet thomasbertet left a comment

Choose a reason for hiding this comment

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

Looks good to me!

I believe we could have a more generic history combining all of the profiler's tracked events in one place, it would be slightly less code.

{
id: vitalStart.id,
startClocks: vitalStart.startClocks,
duration: 0 as Duration,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if we should have another value for "non-stopped" events 🤔
Relying on 0 seems like it could be error prone and the BE that process should be aware 0 means "not stopped".
Maybe just undefined would work instead ? WDYT ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good question... could we maybe settle for something like -1, though, to not have to re-do a rum-events-format PR to allow undefined here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, but we will need to adjust the logic, I kinda forgot about this when I did the BE logic : https://github.com/DataDog/profiling-backend/pull/7969/changes#diff-fe24f465d52fe19d3a52bfd86ac3eaa5e441e710eca6bb9c26a14cac5ce169e4R339-R346

You can see I'm just using the duration field without taking into account if the duration is 0 or undefined.
Let's have -1 as signal for unfinished events. I'll prepare the BE to support that value.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually maybe that's cleaner if that's undefined, even if we have to do another PR for the format, WDYT ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Works for me, I just updated!

@MandragoreVR MandragoreVR force-pushed the teo.chaillou/RUM-14305-browser-add-action-and-vital-metadata-to-profiles branch from ade4eac to 65b9912 Compare February 23, 2026 15:56
@MandragoreVR
Copy link
Collaborator Author

/to-staging

@gh-worker-devflow-routing-ef8351
Copy link

gh-worker-devflow-routing-ef8351 bot commented Feb 23, 2026

View all feedbacks in Devflow UI.

2026-02-23 16:01:46 UTC ℹ️ Start processing command /to-staging


2026-02-23 16:01:53 UTC ℹ️ Branch Integration: starting soon, merge expected in approximately 14m (p90)

Commit 65b99121e9 will soon be integrated into staging-09.


2026-02-23 16:16:03 UTC ℹ️ Branch Integration: this commit was successfully integrated

Commit 65b99121e9 has been merged into staging-09 in merge commit 848b6b79d7.

Check out the triggered DDCI request.

If you need to revert this integration, you can use the following command: /code revert-integration -b staging-09

gh-worker-dd-mergequeue-cf854d bot added a commit that referenced this pull request Feb 23, 2026
…a-to-profiles (#4148) into staging-09

Integrated commit sha: 65b9912

Co-authored-by: MandragoreVR <teo.chaillou@datadoghq.com>
@MandragoreVR MandragoreVR force-pushed the teo.chaillou/RUM-14305-browser-add-action-and-vital-metadata-to-profiles branch from 65b9912 to a68787a Compare February 24, 2026 09:32
@MandragoreVR
Copy link
Collaborator Author

/to-staging

@gh-worker-devflow-routing-ef8351
Copy link

gh-worker-devflow-routing-ef8351 bot commented Feb 24, 2026

View all feedbacks in Devflow UI.

2026-02-24 09:32:53 UTC ℹ️ Start processing command /to-staging


2026-02-24 09:33:01 UTC ℹ️ Branch Integration: starting soon, merge expected in approximately 14m (p90)

Commit a68787a74c will soon be integrated into staging-09.


2026-02-24 09:46:05 UTC ℹ️ Branch Integration: this commit was successfully integrated

Commit a68787a74c has been merged into staging-09 in merge commit 661ba0a622.

Check out the triggered DDCI request.

If you need to revert this integration, you can use the following command: /code revert-integration -b staging-09

@MandragoreVR MandragoreVR force-pushed the teo.chaillou/RUM-14305-browser-add-action-and-vital-metadata-to-profiles branch from a68787a to 5e88cac Compare February 24, 2026 09:44
@MandragoreVR
Copy link
Collaborator Author

/to-staging -c

gh-worker-dd-mergequeue-cf854d bot added a commit that referenced this pull request Feb 24, 2026
…a-to-profiles (#4148) into staging-09

Integrated commit sha: a68787a

Co-authored-by: MandragoreVR <teo.chaillou@datadoghq.com>
@gh-worker-devflow-routing-ef8351

View all feedbacks in Devflow UI.

2026-02-24 09:45:39 UTC ℹ️ Start processing command /to-staging -c
If you need support, contact us on Slack #devflow!


2026-02-24 09:45:42 UTCDevflow: /to-staging -c

Cannot cancel integration of into staging-09:

This merge request was already processed and can't be unqueued anymore.

To get help about command usage, write /to-staging --help

If you need support, contact us on Slack #devflow with those details!


lifeCycle.subscribe(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, ({ rawRumEvent, startClocks, duration }) => {
if (rawRumEvent.type === 'action') {
const durationForEntry = duration ?? (0 as Duration)
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can use duration! like we do in longTaskHistory

.add(
{
id: rawRumEvent.action.id,
label: '',
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ question: ‏Is it expected not to have a label? Shouldn't it be the action name?

expireDelay: ACTION_ID_HISTORY_TIME_OUT_DELAY,
})

const startedActions = new Map<string, ValueHistoryEntry<ActionContext>>()
Copy link
Collaborator

Choose a reason for hiding this comment

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

💬 suggestion: You can use only the history and do history.findAll(startClocks.relative).find((action) => action.id === rawRumEvent.action.id)to locate the startedAction you want to update.

{ isChildEvent: isActionChildEvent }
)

lifeCycle.notify(LifeCycleEventType.ACTION_STARTED, startedManualAction)
Copy link
Collaborator

@amortemousque amortemousque Feb 25, 2026

Choose a reason for hiding this comment

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

💬 suggestion: ‏You could make this part of eventTracker so you have the lifecycle event for click and manual actions. We also are planning to use eventTracker for vitals.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants