Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions javascript/sentry-conventions/src/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3586,6 +3586,52 @@ export const BROWSER_WEB_VITAL_FP_VALUE = 'browser.web_vital.fp.value';
*/
export type BROWSER_WEB_VITAL_FP_VALUE_TYPE = number;

// Path: model/attributes/browser/browser__web_vital__inp__interaction_type.json

/**
* The kind of user interaction INP was reported on `browser.web_vital.inp.interaction_type`
*
* Attribute Value Type: `string` {@link BROWSER_WEB_VITAL_INP_INTERACTION_TYPE_TYPE}
*
* Apply Scrubbing: manual
*
* Attribute defined in OTEL: No
* Visibility: public
*
* @example "click"
* @example "hover"
* @example "drag"
* @example "press"
*/
export const BROWSER_WEB_VITAL_INP_INTERACTION_TYPE = 'browser.web_vital.inp.interaction_type';

/**
* Type for {@link BROWSER_WEB_VITAL_INP_INTERACTION_TYPE} browser.web_vital.inp.interaction_type
*/
export type BROWSER_WEB_VITAL_INP_INTERACTION_TYPE_TYPE = string;

// Path: model/attributes/browser/browser__web_vital__inp__target.json

/**
* The HTML element selector or component name of the element the user interacted with, for the interaction INP was reported on `browser.web_vital.inp.target`
*
* Attribute Value Type: `string` {@link BROWSER_WEB_VITAL_INP_TARGET_TYPE}
*
* Apply Scrubbing: manual
*
* Attribute defined in OTEL: No
* Visibility: public
*
* @example "body > div#app > button.submit"
* @example "SubmitButton"
*/
export const BROWSER_WEB_VITAL_INP_TARGET = 'browser.web_vital.inp.target';

/**
* Type for {@link BROWSER_WEB_VITAL_INP_TARGET} browser.web_vital.inp.target
*/
export type BROWSER_WEB_VITAL_INP_TARGET_TYPE = string;

// Path: model/attributes/browser/browser__web_vital__inp__value.json

/**
Expand Down Expand Up @@ -19530,6 +19576,8 @@ export const ATTRIBUTE_TYPE: Record<string, AttributeType> = {
'browser.web_vital.cls.value': 'double',
'browser.web_vital.fcp.value': 'double',
'browser.web_vital.fp.value': 'double',
'browser.web_vital.inp.interaction_type': 'string',
'browser.web_vital.inp.target': 'string',
'browser.web_vital.inp.value': 'double',
'browser.web_vital.lcp.element': 'string',
'browser.web_vital.lcp.id': 'string',
Expand Down Expand Up @@ -20395,6 +20443,8 @@ export type AttributeName =
| typeof BROWSER_WEB_VITAL_CLS_VALUE
| typeof BROWSER_WEB_VITAL_FCP_VALUE
| typeof BROWSER_WEB_VITAL_FP_VALUE
| typeof BROWSER_WEB_VITAL_INP_INTERACTION_TYPE
| typeof BROWSER_WEB_VITAL_INP_TARGET
| typeof BROWSER_WEB_VITAL_INP_VALUE
| typeof BROWSER_WEB_VITAL_LCP_ELEMENT
| typeof BROWSER_WEB_VITAL_LCP_ID
Expand Down Expand Up @@ -23664,6 +23714,42 @@ export const ATTRIBUTE_METADATA: Record<AttributeName, AttributeMetadata> = {
aliases: ['fp'],
changelog: [{ version: '0.5.0', prs: [235] }],
},
'browser.web_vital.inp.interaction_type': {
brief: 'The kind of user interaction INP was reported on',
type: 'string',
keys: ['browser.web_vital.inp.interaction_type'],
applyScrubbing: {
key: 'manual',
},
isInOtel: false,
visibility: 'public',
example: 'click',
examples: ['click', 'hover', 'drag', 'press'],
changelog: [{ version: 'next', prs: [641], description: 'Added browser.web_vital.inp.interaction_type attribute' }],
additionalContext: [
"One of `click`, `hover`, `drag` or `press`, derived from the DOM event name of the Event Timing entry: pointer, mouse and touch events map to `click`, `mouseover` and similar to `hover`, drag and drop events to `drag`, and keyboard and `input` events to `press`. The same value forms the suffix of the span's `ui.interaction.*` op.",
'Not to be confused with the `interactionType` of the web-vitals attribution build, which only distinguishes `pointer` and `keyboard`.',
'Omitted when INP is reported without an interaction to attribute it to, see `browser.web_vital.inp.target`. The op of such a span still falls into `ui.interaction.click` so that it stays within the interaction span family, which makes this attribute, not the op, the way to tell a real click from a value with no interaction.',
],
},
'browser.web_vital.inp.target': {
brief:
'The HTML element selector or component name of the element the user interacted with, for the interaction INP was reported on',
type: 'string',
keys: ['browser.web_vital.inp.target'],
applyScrubbing: {
key: 'manual',
},
isInOtel: false,
visibility: 'public',
example: 'body > div#app > button.submit',
examples: ['body > div#app > button.submit', 'SubmitButton'],
changelog: [{ version: 'next', prs: [641], description: 'Added browser.web_vital.inp.target attribute' }],
additionalContext: [
'Named after `PerformanceEventTiming.target`, the way `browser.web_vital.lcp.element` is named after `LargestContentfulPaint.element`. The value uses the same format as that attribute.',
'Omitted when INP is reported without an interaction to attribute it to. web-vitals reports such a value for a soft navigation whose interactions all stayed below the Event Timing duration threshold, so there is no element to name. The span is still named and still carries `browser.web_vital.inp.value`.',
],
},
'browser.web_vital.inp.value': {
brief: 'The value of the recorded Interaction to Next Paint (INP) web vital',
type: 'double',
Expand Down Expand Up @@ -35091,6 +35177,8 @@ export type Attributes = {
[BROWSER_WEB_VITAL_CLS_VALUE]?: BROWSER_WEB_VITAL_CLS_VALUE_TYPE;
[BROWSER_WEB_VITAL_FCP_VALUE]?: BROWSER_WEB_VITAL_FCP_VALUE_TYPE;
[BROWSER_WEB_VITAL_FP_VALUE]?: BROWSER_WEB_VITAL_FP_VALUE_TYPE;
[BROWSER_WEB_VITAL_INP_INTERACTION_TYPE]?: BROWSER_WEB_VITAL_INP_INTERACTION_TYPE_TYPE;
[BROWSER_WEB_VITAL_INP_TARGET]?: BROWSER_WEB_VITAL_INP_TARGET_TYPE;
[BROWSER_WEB_VITAL_INP_VALUE]?: BROWSER_WEB_VITAL_INP_VALUE_TYPE;
[BROWSER_WEB_VITAL_LCP_ELEMENT]?: BROWSER_WEB_VITAL_LCP_ELEMENT_TYPE;
[BROWSER_WEB_VITAL_LCP_ID]?: BROWSER_WEB_VITAL_LCP_ID_TYPE;
Expand Down
25 changes: 25 additions & 0 deletions javascript/sentry-conventions/src/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,16 @@ export const SEARCH_BROWSER__WEB_VITAL__FCP__VALUE = 'browser.web_vital.fcp.valu
*/
export const SEARCH_BROWSER__WEB_VITAL__FP__VALUE = 'browser.web_vital.fp.value';

/**
* Search name for {@link attributes.BROWSER_WEB_VITAL_INP_INTERACTION_TYPE}. `browser.web_vital.inp.interaction_type`
*/
export const SEARCH_BROWSER__WEB_VITAL__INP__INTERACTION_TYPE = 'browser.web_vital.inp.interaction_type';

/**
* Search name for {@link attributes.BROWSER_WEB_VITAL_INP_TARGET}. `browser.web_vital.inp.target`
*/
export const SEARCH_BROWSER__WEB_VITAL__INP__TARGET = 'browser.web_vital.inp.target';

/**
* Search name for {@link attributes.BROWSER_WEB_VITAL_INP_VALUE}. `browser.web_vital.inp.value`
*/
Expand Down Expand Up @@ -5144,6 +5154,8 @@ export type AttributeSearchName =
| typeof SEARCH_BROWSER__WEB_VITAL__CLS__VALUE
| typeof SEARCH_BROWSER__WEB_VITAL__FCP__VALUE
| typeof SEARCH_BROWSER__WEB_VITAL__FP__VALUE
| typeof SEARCH_BROWSER__WEB_VITAL__INP__INTERACTION_TYPE
| typeof SEARCH_BROWSER__WEB_VITAL__INP__TARGET
| typeof SEARCH_BROWSER__WEB_VITAL__INP__VALUE
| typeof SEARCH_BROWSER__WEB_VITAL__LCP__ELEMENT
| typeof SEARCH_BROWSER__WEB_VITAL__LCP__ID
Expand Down Expand Up @@ -6908,6 +6920,19 @@ export const ATTRIBUTE_SEARCH_METADATA: Record<string, AttributeSearchMetadata>
brief: 'The time in milliseconds it takes for the browser to render the first pixel on the screen',
deprecationChain: ['browser.web_vital.fp.value', 'fp'],
},
'browser.web_vital.inp.interaction_type': {
canonicalName: 'browser.web_vital.inp.interaction_type',
type: 'string',
brief: 'The kind of user interaction INP was reported on',
deprecationChain: ['browser.web_vital.inp.interaction_type'],
},
'browser.web_vital.inp.target': {
canonicalName: 'browser.web_vital.inp.target',
type: 'string',
brief:
'The HTML element selector or component name of the element the user interacted with, for the interaction INP was reported on',
deprecationChain: ['browser.web_vital.inp.target'],
},
'browser.web_vital.inp.value': {
canonicalName: 'browser.web_vital.inp.value',
type: 'double',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"key": "browser.web_vital.inp.interaction_type",
"brief": "The kind of user interaction INP was reported on",
"type": "string",
"apply_scrubbing": {
"key": "manual"
},
"is_in_otel": false,
"visibility": "public",
"examples": ["click", "hover", "drag", "press"],
"additional_context": [
"One of `click`, `hover`, `drag` or `press`, derived from the DOM event name of the Event Timing entry: pointer, mouse and touch events map to `click`, `mouseover` and similar to `hover`, drag and drop events to `drag`, and keyboard and `input` events to `press`. The same value forms the suffix of the span's `ui.interaction.*` op.",
"Not to be confused with the `interactionType` of the web-vitals attribution build, which only distinguishes `pointer` and `keyboard`.",
"Omitted when INP is reported without an interaction to attribute it to, see `browser.web_vital.inp.target`. The op of such a span still falls into `ui.interaction.click` so that it stays within the interaction span family, which makes this attribute, not the op, the way to tell a real click from a value with no interaction."
],
"changelog": [
{
"version": "next",
"prs": [641],
"description": "Added browser.web_vital.inp.interaction_type attribute"
}
]
}
22 changes: 22 additions & 0 deletions model/attributes/browser/browser__web_vital__inp__target.json

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Generally fine with this but to think about: We have a browser.web_vital.lcp.element attribute. Does it make sense to rename this to browser.web_vital.inp.element?

Somewhat related, I'm planing on adding a ui.element.selector attribute to generically capture selectors but this likely doesn't fit here, given the target could also be a component name. Does that make sense to you?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

actually, on second thought, "target" is probably more fitting for using it interchangeably on selectors or component names. I'll probably go with ui.element.target myself

@logaretm logaretm Sep 22, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I did some of research on which name to use, I should've added it to the PR 😓

So we seem to be following the names that the relevant APIs expose, so by doing the same we end up with target because that is what the API exposes, also targetSelector in the future.

It looks like this now, across all web vitals:

LCP  LargestContentfulPaint.element  ->  browser.web_vital.lcp.element
CLS  LayoutShift.sources             ->  browser.web_vital.cls.source.N
INP  PerformanceEventTiming.target   ->  browser.web_vital.inp.target

For ui.element.* namespace, it mostly belongs to the element timing API which follows the same pattern we outlined above. I don't want to muddy that IMO.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"key": "browser.web_vital.inp.target",
"brief": "The HTML element selector or component name of the element the user interacted with, for the interaction INP was reported on",
"type": "string",
"apply_scrubbing": {
"key": "manual"
},
"is_in_otel": false,
"visibility": "public",
"examples": ["body > div#app > button.submit", "SubmitButton"],
"additional_context": [
"Named after `PerformanceEventTiming.target`, the way `browser.web_vital.lcp.element` is named after `LargestContentfulPaint.element`. The value uses the same format as that attribute.",
"Omitted when INP is reported without an interaction to attribute it to. web-vitals reports such a value for a soft navigation whose interactions all stayed below the Event Timing duration threshold, so there is no element to name. The span is still named and still carries `browser.web_vital.inp.value`."
],
"changelog": [
{
"version": "next",
"prs": [641],
"description": "Added browser.web_vital.inp.target attribute"
}
]
}
75 changes: 75 additions & 0 deletions python/src/sentry_conventions/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2467,6 +2467,36 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta):
Example: 477.1926
"""

# Path: model/attributes/browser/browser__web_vital__inp__interaction_type.json
BROWSER_WEB_VITAL_INP_INTERACTION_TYPE: Literal[
"browser.web_vital.inp.interaction_type"
] = "browser.web_vital.inp.interaction_type"
"""The kind of user interaction INP was reported on

Type: str
Apply Scrubbing: manual
Defined in OTEL: No
Visibility: public
Example: "click"
Example: "hover"
Example: "drag"
Example: "press"
"""

# Path: model/attributes/browser/browser__web_vital__inp__target.json
BROWSER_WEB_VITAL_INP_TARGET: Literal["browser.web_vital.inp.target"] = (
"browser.web_vital.inp.target"
)
"""The HTML element selector or component name of the element the user interacted with, for the interaction INP was reported on

Type: str
Apply Scrubbing: manual
Defined in OTEL: No
Visibility: public
Example: "body > div#app > button.submit"
Example: "SubmitButton"
"""

# Path: model/attributes/browser/browser__web_vital__inp__value.json
BROWSER_WEB_VITAL_INP_VALUE: Literal["browser.web_vital.inp.value"] = (
"browser.web_vital.inp.value"
Expand Down Expand Up @@ -14394,6 +14424,49 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta):
ChangelogEntry(version="0.5.0", prs=[235]),
],
),
"browser.web_vital.inp.interaction_type": AttributeMetadata(
brief="The kind of user interaction INP was reported on",
type=AttributeType.STRING,
keys=("browser.web_vital.inp.interaction_type",),
apply_scrubbing=ApplyScrubbingInfo(key=ApplyScrubbing.MANUAL),
is_in_otel=False,
visibility=Visibility.PUBLIC,
example="click",
examples=["click", "hover", "drag", "press"],
changelog=[
ChangelogEntry(
version="next",
prs=[641],
description="Added browser.web_vital.inp.interaction_type attribute",
),
],
additional_context=[
"One of `click`, `hover`, `drag` or `press`, derived from the DOM event name of the Event Timing entry: pointer, mouse and touch events map to `click`, `mouseover` and similar to `hover`, drag and drop events to `drag`, and keyboard and `input` events to `press`. The same value forms the suffix of the span's `ui.interaction.*` op.",
"Not to be confused with the `interactionType` of the web-vitals attribution build, which only distinguishes `pointer` and `keyboard`.",
"Omitted when INP is reported without an interaction to attribute it to, see `browser.web_vital.inp.target`. The op of such a span still falls into `ui.interaction.click` so that it stays within the interaction span family, which makes this attribute, not the op, the way to tell a real click from a value with no interaction.",
],
),
"browser.web_vital.inp.target": AttributeMetadata(
brief="The HTML element selector or component name of the element the user interacted with, for the interaction INP was reported on",
type=AttributeType.STRING,
keys=("browser.web_vital.inp.target",),
apply_scrubbing=ApplyScrubbingInfo(key=ApplyScrubbing.MANUAL),
is_in_otel=False,
visibility=Visibility.PUBLIC,
example="body > div#app > button.submit",
examples=["body > div#app > button.submit", "SubmitButton"],
changelog=[
ChangelogEntry(
version="next",
prs=[641],
description="Added browser.web_vital.inp.target attribute",
),
],
additional_context=[
"Named after `PerformanceEventTiming.target`, the way `browser.web_vital.lcp.element` is named after `LargestContentfulPaint.element`. The value uses the same format as that attribute.",
"Omitted when INP is reported without an interaction to attribute it to. web-vitals reports such a value for a soft navigation whose interactions all stayed below the Event Timing duration threshold, so there is no element to name. The span is still named and still carries `browser.web_vital.inp.value`.",
],
),
"browser.web_vital.inp.value": AttributeMetadata(
brief="The value of the recorded Interaction to Next Paint (INP) web vital",
type=AttributeType.DOUBLE,
Expand Down Expand Up @@ -27540,6 +27613,8 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta):
"browser.web_vital.cls.value": float,
"browser.web_vital.fcp.value": float,
"browser.web_vital.fp.value": float,
"browser.web_vital.inp.interaction_type": str,
"browser.web_vital.inp.target": str,
"browser.web_vital.inp.value": float,
"browser.web_vital.lcp.element": str,
"browser.web_vital.lcp.id": str,
Expand Down
Loading