From 9d1b35d4c62f9ad299790f549344c756951b36f1 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 16 Jul 2024 12:43:32 +0200 Subject: [PATCH] feat(browser): Add user agent to INP standalone span attributes (#12896) Add the `window.navigator.userAgent` string as the [`user_agent.original`](https://opentelemetry.io/docs/specs/semconv/attributes-registry/user-agent/) attribute to INP standalone spans. --- .../suites/tracing/metrics/web-vitals-inp-late/test.ts | 1 + .../tracing/metrics/web-vitals-inp-parametrized-late/test.ts | 1 + .../tracing/metrics/web-vitals-inp-parametrized/test.ts | 1 + .../suites/tracing/metrics/web-vitals-inp/test.ts | 1 + .../create-remix-app/tests/client-inp.test.ts | 4 ++++ .../test-applications/react-17/tests/transactions.test.ts | 1 + .../react-router-6/tests/transactions.test.ts | 1 + packages/browser-utils/src/metrics/inp.ts | 4 ++++ 8 files changed, 14 insertions(+) diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts index 1ec7ec50998a..1b6bc5bc686d 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts @@ -77,6 +77,7 @@ sentryTest('should capture an INP click event span after pageload', async ({ bro 'sentry.sample_rate': 1, 'sentry.source': 'custom', transaction: 'test-url', + 'user_agent.original': expect.stringContaining('Chrome'), }, measurements: { inp: { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts index 1354c373253e..a9d5191b5cf3 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts @@ -80,6 +80,7 @@ sentryTest( 'sentry.sample_rate': 1, 'sentry.source': 'custom', transaction: 'test-route', + 'user_agent.original': expect.stringContaining('Chrome'), }, measurements: { inp: { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts index 248cb7d1e510..87ba1fd8632c 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts @@ -76,6 +76,7 @@ sentryTest( 'sentry.op': 'ui.interaction.click', 'sentry.origin': 'auto.http.browser.inp', transaction: 'test-route', + 'user_agent.original': expect.stringContaining('Chrome'), }, measurements: { inp: { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts index 3f9684cf7f2a..594bd9904052 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts @@ -77,6 +77,7 @@ sentryTest( 'sentry.op': 'ui.interaction.click', 'sentry.origin': 'auto.http.browser.inp', transaction: 'test-url', + 'user_agent.original': expect.stringContaining('Chrome'), }, measurements: { inp: { diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-inp.test.ts b/dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-inp.test.ts index 9469a4462563..8fe1993db3f8 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-inp.test.ts +++ b/dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-inp.test.ts @@ -30,6 +30,7 @@ test('sends an INP span during pageload', async ({ page }) => { 'sentry.sample_rate': 1, 'sentry.source': 'custom', replay_id: expect.any(String), + 'user_agent.original': expect.stringContaining('Chrome'), }, description: 'body > div > input#exception-button[type="button"]', op: 'ui.interaction.click', @@ -81,6 +82,7 @@ test('sends an INP span after pageload', async ({ page }) => { 'sentry.sample_rate': 1, 'sentry.source': 'custom', replay_id: expect.any(String), + 'user_agent.original': expect.stringContaining('Chrome'), }, description: 'body > div > input#exception-button[type="button"]', op: 'ui.interaction.click', @@ -125,6 +127,7 @@ test('sends an INP span during navigation', async ({ page }) => { transaction: 'routes/user.$id', 'sentry.exclusive_time': expect.any(Number), replay_id: expect.any(String), + 'user_agent.original': expect.stringContaining('Chrome'), }, description: '', op: 'ui.interaction.click', @@ -178,6 +181,7 @@ test('sends an INP span after navigation', async ({ page }) => { replay_id: expect.any(String), 'sentry.sample_rate': 1, 'sentry.source': 'custom', + 'user_agent.original': expect.stringContaining('Chrome'), }, description: '', op: 'ui.interaction.click', diff --git a/dev-packages/e2e-tests/test-applications/react-17/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/react-17/tests/transactions.test.ts index 665b5c02aafe..3b9c5ab1fdaf 100644 --- a/dev-packages/e2e-tests/test-applications/react-17/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-17/tests/transactions.test.ts @@ -82,6 +82,7 @@ test('sends an INP span', async ({ page }) => { transaction: '/', 'sentry.exclusive_time': expect.any(Number), replay_id: expect.any(String), + 'user_agent.original': expect.stringContaining('Chrome'), }, description: 'body > div#root > input#exception-button[type="button"]', op: 'ui.interaction.click', diff --git a/dev-packages/e2e-tests/test-applications/react-router-6/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/react-router-6/tests/transactions.test.ts index 39e07b89c0ee..3f108931b00e 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-6/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-router-6/tests/transactions.test.ts @@ -82,6 +82,7 @@ test('sends an INP span', async ({ page }) => { transaction: '/', 'sentry.exclusive_time': expect.any(Number), replay_id: expect.any(String), + 'user_agent.original': expect.stringContaining('Chrome'), }, description: 'body > div#root > input#exception-button[type="button"]', op: 'ui.interaction.click', diff --git a/packages/browser-utils/src/metrics/inp.ts b/packages/browser-utils/src/metrics/inp.ts index 1055635bc32f..c4186a20f17e 100644 --- a/packages/browser-utils/src/metrics/inp.ts +++ b/packages/browser-utils/src/metrics/inp.ts @@ -12,6 +12,7 @@ import { } from '@sentry/core'; import type { Integration, Span, SpanAttributes } from '@sentry/types'; import { browserPerformanceTimeOrigin, dropUndefinedKeys, htmlTreeAsString } from '@sentry/utils'; +import { WINDOW } from '../types'; import { addInpInstrumentationHandler, addPerformanceInstrumentationHandler, @@ -129,6 +130,9 @@ function _trackINP(): () => void { user: userDisplay || undefined, profile_id: profileId || undefined, replay_id: replayId || undefined, + // INP score calculation in the sentry backend relies on the user agent + // to account for different INP values being reported from different browsers + 'user_agent.original': WINDOW.navigator && WINDOW.navigator.userAgent, }); const span = startInactiveSpan({