From 9cce54fff615ea3d99484519eb4f60c88e0acd40 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 23 Jan 2026 11:42:36 +0100 Subject: [PATCH 1/3] feat(attributes): Add CLS web vital source attribute --- generated/attributes/all.md | 4 +- generated/attributes/browser.md | 13 ++++ generated/attributes/cls.md | 21 ++++++ generated/attributes/index.md | 1 + .../sentry-conventions/src/attributes.ts | 72 +++++++++++++++++++ ...wser__web_vital__cls__source__.json | 12 ++++ .../attributes/cls/cls__source__.json | 17 +++++ python/src/sentry_conventions/attributes.py | 44 ++++++++++++ 8 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 generated/attributes/cls.md create mode 100644 model/attributes/browser/browser__web_vital__cls__source__.json create mode 100644 model/attributes/cls/cls__source__.json diff --git a/generated/attributes/all.md b/generated/attributes/all.md index 42516ff..18bd330 100644 --- a/generated/attributes/all.md +++ b/generated/attributes/all.md @@ -4,7 +4,7 @@ This page lists all available attributes across all categories. -Total attributes: 422 +Total attributes: 424 ## Stable Attributes @@ -31,6 +31,7 @@ Total attributes: 422 | [`browser.script.invoker_type`](./browser.md#browserscriptinvoker_type) | Browser script entry point type. | | [`browser.script.source_char_position`](./browser.md#browserscriptsource_char_position) | A number representing the script character position of the script. | | [`browser.version`](./browser.md#browserversion) | The version of the browser. | +| [`browser.web_vital.cls.source.`](./browser.md#browserweb_vitalclssource) | The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N | | [`cache.hit`](./cache.md#cachehit) | If the cache was hit during this span. | | [`cache.item_size`](./cache.md#cacheitem_size) | The size of the requested item in the cache. In bytes. | | [`cache.key`](./cache.md#cachekey) | The key of the cache accessed. | @@ -42,6 +43,7 @@ Total attributes: 422 | [`cloudflare.d1.duration`](./cloudflare.md#cloudflared1duration) | The duration of a Cloudflare D1 operation. | | [`cloudflare.d1.rows_read`](./cloudflare.md#cloudflared1rows_read) | The number of rows read in a Cloudflare D1 operation. | | [`cloudflare.d1.rows_written`](./cloudflare.md#cloudflared1rows_written) | The number of rows written in a Cloudflare D1 operation. | +| [`cls.source.`](./cls.md#clssource) | The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N | | [`code.file.path`](./code.md#codefilepath) | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | | [`code.function.name`](./code.md#codefunctionname) | The method or function name, or equivalent (usually rightmost part of the code unit's name). | | [`code.line.number`](./code.md#codelinenumber) | The line number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function | diff --git a/generated/attributes/browser.md b/generated/attributes/browser.md index 2295102..dd3d10d 100644 --- a/generated/attributes/browser.md +++ b/generated/attributes/browser.md @@ -9,6 +9,7 @@ - [browser.script.invoker_type](#browserscriptinvoker_type) - [browser.script.source_char_position](#browserscriptsource_char_position) - [browser.version](#browserversion) + - [browser.web_vital.cls.source.](#browserweb_vitalclssource) ## Stable Attributes @@ -80,3 +81,15 @@ The version of the browser. | Example | `120.0.6099.130` | | Aliases | `sentry.browser.version` | +### browser.web_vital.cls.source. + +The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N + +| Property | Value | +| --- | --- | +| Type | `string` | +| Has PII | maybe | +| Exists in OpenTelemetry | No | +| Example | `body > div#app` | +| Aliases | `cls.source.` | + diff --git a/generated/attributes/cls.md b/generated/attributes/cls.md new file mode 100644 index 0000000..bba25a0 --- /dev/null +++ b/generated/attributes/cls.md @@ -0,0 +1,21 @@ + + +# Cls Attributes + +- [Stable Attributes](#stable-attributes) + - [cls.source.](#clssource) + +## Stable Attributes + +### cls.source. + +The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N + +| Property | Value | +| --- | --- | +| Type | `string` | +| Has PII | maybe | +| Exists in OpenTelemetry | No | +| Example | `body > div#app` | +| Aliases | `browser.web_vital.cls.source.` | + diff --git a/generated/attributes/index.md b/generated/attributes/index.md index 42ed24f..e53ac80 100644 --- a/generated/attributes/index.md +++ b/generated/attributes/index.md @@ -13,6 +13,7 @@ This directory contains documentation for all available attributes. - [`cache` Attributes](./cache.md) - [`client` Attributes](./client.md) - [`cloudflare` Attributes](./cloudflare.md) +- [`cls` Attributes](./cls.md) - [`code` Attributes](./code.md) - [`db` Attributes](./db.md) - [`device` Attributes](./device.md) diff --git a/javascript/sentry-conventions/src/attributes.ts b/javascript/sentry-conventions/src/attributes.ts index 7a5c875..316f1f5 100644 --- a/javascript/sentry-conventions/src/attributes.ts +++ b/javascript/sentry-conventions/src/attributes.ts @@ -878,6 +878,28 @@ export const BROWSER_VERSION = 'browser.version'; */ export type BROWSER_VERSION_TYPE = string; +// Path: model/attributes/browser/browser__web_vital__cls__source__.json + +/** + * The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N `browser.web_vital.cls.source.` + * + * Attribute Value Type: `string` {@link BROWSER_WEB_VITAL_CLS_SOURCE_INDEX_TYPE} + * + * Contains PII: maybe + * + * Attribute defined in OTEL: No + * + * Aliases: {@link CLS_SOURCE_INDEX} `cls.source.` + * + * @example "body > div#app" + */ +export const BROWSER_WEB_VITAL_CLS_SOURCE_INDEX = 'browser.web_vital.cls.source.'; + +/** + * Type for {@link BROWSER_WEB_VITAL_CLS_SOURCE_INDEX} browser.web_vital.cls.source. + */ +export type BROWSER_WEB_VITAL_CLS_SOURCE_INDEX_TYPE = string; + // Path: model/attributes/cache/cache__hit.json /** @@ -1100,6 +1122,28 @@ export const CLOUDFLARE_D1_ROWS_WRITTEN = 'cloudflare.d1.rows_written'; */ export type CLOUDFLARE_D1_ROWS_WRITTEN_TYPE = number; +// Path: model/attributes/cls/cls__source__.json + +/** + * The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N `cls.source.` + * + * Attribute Value Type: `string` {@link CLS_SOURCE_INDEX_TYPE} + * + * Contains PII: maybe + * + * Attribute defined in OTEL: No + * + * Aliases: {@link BROWSER_WEB_VITAL_CLS_SOURCE_INDEX} `browser.web_vital.cls.source.` + * + * @example "body > div#app" + */ +export const CLS_SOURCE_INDEX = 'cls.source.'; + +/** + * Type for {@link CLS_SOURCE_INDEX} cls.source. + */ +export type CLS_SOURCE_INDEX_TYPE = string; + // Path: model/attributes/code/code__filepath.json /** @@ -8849,6 +8893,7 @@ export const ATTRIBUTE_TYPE: Record = { [BROWSER_SCRIPT_INVOKER_TYPE]: 'string', [BROWSER_SCRIPT_SOURCE_CHAR_POSITION]: 'integer', [BROWSER_VERSION]: 'string', + [BROWSER_WEB_VITAL_CLS_SOURCE_INDEX]: 'string', [CACHE_HIT]: 'boolean', [CACHE_ITEM_SIZE]: 'integer', [CACHE_KEY]: 'string[]', @@ -8860,6 +8905,7 @@ export const ATTRIBUTE_TYPE: Record = { [CLOUDFLARE_D1_DURATION]: 'integer', [CLOUDFLARE_D1_ROWS_READ]: 'integer', [CLOUDFLARE_D1_ROWS_WRITTEN]: 'integer', + [CLS_SOURCE_INDEX]: 'string', [CODE_FILEPATH]: 'string', [CODE_FILE_PATH]: 'string', [CODE_FUNCTION]: 'string', @@ -9274,6 +9320,7 @@ export type AttributeName = | typeof BROWSER_SCRIPT_INVOKER_TYPE | typeof BROWSER_SCRIPT_SOURCE_CHAR_POSITION | typeof BROWSER_VERSION + | typeof BROWSER_WEB_VITAL_CLS_SOURCE_INDEX | typeof CACHE_HIT | typeof CACHE_ITEM_SIZE | typeof CACHE_KEY @@ -9285,6 +9332,7 @@ export type AttributeName = | typeof CLOUDFLARE_D1_DURATION | typeof CLOUDFLARE_D1_ROWS_READ | typeof CLOUDFLARE_D1_ROWS_WRITTEN + | typeof CLS_SOURCE_INDEX | typeof CODE_FILEPATH | typeof CODE_FILE_PATH | typeof CODE_FUNCTION @@ -10122,6 +10170,17 @@ export const ATTRIBUTE_METADATA: Record = { example: '120.0.6099.130', aliases: [SENTRY_BROWSER_VERSION], }, + [BROWSER_WEB_VITAL_CLS_SOURCE_INDEX]: { + brief: 'The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N', + type: 'string', + pii: { + isPii: 'maybe', + }, + isInOtel: false, + example: 'body > div#app', + aliases: [CLS_SOURCE_INDEX], + sdks: ['javascript-browser'], + }, [CACHE_HIT]: { brief: 'If the cache was hit during this span.', type: 'boolean', @@ -10231,6 +10290,17 @@ export const ATTRIBUTE_METADATA: Record = { example: 12, sdks: ['javascript-cloudflare'], }, + [CLS_SOURCE_INDEX]: { + brief: 'The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N', + type: 'string', + pii: { + isPii: 'maybe', + }, + isInOtel: false, + example: 'body > div#app', + aliases: [BROWSER_WEB_VITAL_CLS_SOURCE_INDEX], + sdks: ['javascript-browser'], + }, [CODE_FILEPATH]: { brief: 'The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path).', @@ -14026,6 +14096,7 @@ export type Attributes = { [BROWSER_SCRIPT_INVOKER_TYPE]?: BROWSER_SCRIPT_INVOKER_TYPE_TYPE; [BROWSER_SCRIPT_SOURCE_CHAR_POSITION]?: BROWSER_SCRIPT_SOURCE_CHAR_POSITION_TYPE; [BROWSER_VERSION]?: BROWSER_VERSION_TYPE; + [BROWSER_WEB_VITAL_CLS_SOURCE_INDEX]?: BROWSER_WEB_VITAL_CLS_SOURCE_INDEX_TYPE; [CACHE_HIT]?: CACHE_HIT_TYPE; [CACHE_ITEM_SIZE]?: CACHE_ITEM_SIZE_TYPE; [CACHE_KEY]?: CACHE_KEY_TYPE; @@ -14037,6 +14108,7 @@ export type Attributes = { [CLOUDFLARE_D1_DURATION]?: CLOUDFLARE_D1_DURATION_TYPE; [CLOUDFLARE_D1_ROWS_READ]?: CLOUDFLARE_D1_ROWS_READ_TYPE; [CLOUDFLARE_D1_ROWS_WRITTEN]?: CLOUDFLARE_D1_ROWS_WRITTEN_TYPE; + [CLS_SOURCE_INDEX]?: CLS_SOURCE_INDEX_TYPE; [CODE_FILEPATH]?: CODE_FILEPATH_TYPE; [CODE_FILE_PATH]?: CODE_FILE_PATH_TYPE; [CODE_FUNCTION]?: CODE_FUNCTION_TYPE; diff --git a/model/attributes/browser/browser__web_vital__cls__source__.json b/model/attributes/browser/browser__web_vital__cls__source__.json new file mode 100644 index 0000000..ee8195f --- /dev/null +++ b/model/attributes/browser/browser__web_vital__cls__source__.json @@ -0,0 +1,12 @@ +{ + "key": "browser.web_vital.cls.source.", + "brief": "The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", + "type": "string", + "pii": { + "key": "maybe" + }, + "is_in_otel": false, + "example": "body > div#app", + "alias": ["cls.source."], + "sdks": ["javascript-browser"] +} diff --git a/model/attributes/cls/cls__source__.json b/model/attributes/cls/cls__source__.json new file mode 100644 index 0000000..bfa6aa3 --- /dev/null +++ b/model/attributes/cls/cls__source__.json @@ -0,0 +1,17 @@ +{ + "key": "cls.source.", + "brief": "The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", + "type": "string", + "pii": { + "key": "maybe" + }, + "is_in_otel": false, + "example": "body > div#app", + "sdks": ["javascript-browser"], + "deprecation": { + "replacement": "browser.web_vital.cls.source.", + "reason": "The CLS source is now recorded as a browser.web_vital.cls.source. attribute.", + "_status": "backfill" + }, + "alias": ["browser.web_vital.cls.source."] +} diff --git a/python/src/sentry_conventions/attributes.py b/python/src/sentry_conventions/attributes.py index a167893..fa5de72 100644 --- a/python/src/sentry_conventions/attributes.py +++ b/python/src/sentry_conventions/attributes.py @@ -635,6 +635,19 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Example: "120.0.6099.130" """ + # Path: model/attributes/browser/browser__web_vital__cls__source__.json + BROWSER_WEB_VITAL_CLS_SOURCE_INDEX: Literal[ + "browser.web_vital.cls.source." + ] = "browser.web_vital.cls.source." + """The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N + + Type: str + Contains PII: maybe + Defined in OTEL: No + Aliases: cls.source. + Example: "body > div#app" + """ + # Path: model/attributes/cache/cache__hit.json CACHE_HIT: Literal["cache.hit"] = "cache.hit" """If the cache was hit during this span. @@ -750,6 +763,17 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Example: 12 """ + # Path: model/attributes/cls/cls__source__.json + CLS_SOURCE_INDEX: Literal["cls.source."] = "cls.source." + """The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N + + Type: str + Contains PII: maybe + Defined in OTEL: No + Aliases: browser.web_vital.cls.source. + Example: "body > div#app" + """ + # Path: model/attributes/code/code__file__path.json CODE_FILE_PATH: Literal["code.file.path"] = "code.file.path" """The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). @@ -5155,6 +5179,15 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): example="120.0.6099.130", aliases=["sentry.browser.version"], ), + "browser.web_vital.cls.source.": AttributeMetadata( + brief="The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", + type=AttributeType.STRING, + pii=PiiInfo(isPii=IsPii.MAYBE), + is_in_otel=False, + example="body > div#app", + aliases=["cls.source."], + sdks=["javascript-browser"], + ), "cache.hit": AttributeMetadata( brief="If the cache was hit during this span.", type=AttributeType.BOOLEAN, @@ -5241,6 +5274,15 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): example=12, sdks=["javascript-cloudflare"], ), + "cls.source.": AttributeMetadata( + brief="The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", + type=AttributeType.STRING, + pii=PiiInfo(isPii=IsPii.MAYBE), + is_in_otel=False, + example="body > div#app", + aliases=["browser.web_vital.cls.source."], + sdks=["javascript-browser"], + ), "code.file.path": AttributeMetadata( brief="The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path).", type=AttributeType.STRING, @@ -8156,6 +8198,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): "browser.script.invoker_type": str, "browser.script.source_char_position": int, "browser.version": str, + "browser.web_vital.cls.source.": str, "cache.hit": bool, "cache.item_size": int, "cache.key": List[str], @@ -8167,6 +8210,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): "cloudflare.d1.duration": int, "cloudflare.d1.rows_read": int, "cloudflare.d1.rows_written": int, + "cls.source.": str, "code.file.path": str, "code.filepath": str, "code.function": str, From 1c612e645ff0a0a80b31dbea023255d2a8239c89 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 23 Jan 2026 11:49:20 +0100 Subject: [PATCH 2/3] fix index/key syntax --- generated/attributes/all.md | 4 +- generated/attributes/browser.md | 8 +-- generated/attributes/cls.md | 16 ++++-- .../sentry-conventions/src/attributes.ts | 57 ++++++++++--------- ...owser__web_vital__cls__source__[key].json} | 6 +- ...__.json => cls__source__[key].json} | 10 ++-- python/src/sentry_conventions/attributes.py | 43 ++++++++------ shared/deprecated_attributes.json | 17 ++++++ 8 files changed, 97 insertions(+), 64 deletions(-) rename model/attributes/browser/{browser__web_vital__cls__source__.json => browser__web_vital__cls__source__[key].json} (60%) rename model/attributes/cls/{cls__source__.json => cls__source__[key].json} (58%) diff --git a/generated/attributes/all.md b/generated/attributes/all.md index 18bd330..f85453e 100644 --- a/generated/attributes/all.md +++ b/generated/attributes/all.md @@ -31,7 +31,7 @@ Total attributes: 424 | [`browser.script.invoker_type`](./browser.md#browserscriptinvoker_type) | Browser script entry point type. | | [`browser.script.source_char_position`](./browser.md#browserscriptsource_char_position) | A number representing the script character position of the script. | | [`browser.version`](./browser.md#browserversion) | The version of the browser. | -| [`browser.web_vital.cls.source.`](./browser.md#browserweb_vitalclssource) | The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N | +| [`browser.web_vital.cls.source.\`](./browser.md#browserweb_vitalclssourcekey) | The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N | | [`cache.hit`](./cache.md#cachehit) | If the cache was hit during this span. | | [`cache.item_size`](./cache.md#cacheitem_size) | The size of the requested item in the cache. In bytes. | | [`cache.key`](./cache.md#cachekey) | The key of the cache accessed. | @@ -43,7 +43,6 @@ Total attributes: 424 | [`cloudflare.d1.duration`](./cloudflare.md#cloudflared1duration) | The duration of a Cloudflare D1 operation. | | [`cloudflare.d1.rows_read`](./cloudflare.md#cloudflared1rows_read) | The number of rows read in a Cloudflare D1 operation. | | [`cloudflare.d1.rows_written`](./cloudflare.md#cloudflared1rows_written) | The number of rows written in a Cloudflare D1 operation. | -| [`cls.source.`](./cls.md#clssource) | The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N | | [`code.file.path`](./code.md#codefilepath) | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | | [`code.function.name`](./code.md#codefunctionname) | The method or function name, or equivalent (usually rightmost part of the code unit's name). | | [`code.line.number`](./code.md#codelinenumber) | The line number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function | @@ -381,6 +380,7 @@ Total attributes: 424 | [`ai.top_k`](./ai.md#aitop_k) | [`gen_ai.request.top_k`](./gen_ai.md#gen_airequesttop_k) | | [`ai.top_p`](./ai.md#aitop_p) | [`gen_ai.request.top_p`](./gen_ai.md#gen_airequesttop_p) | | [`ai.total_tokens.used`](./ai.md#aitotal_tokensused) | [`gen_ai.usage.total_tokens`](./gen_ai.md#gen_aiusagetotal_tokens) | +| [`cls.source.\`](./cls.md#clssourcekey) | [`browser.web_vital.cls.source.\`](./browser.md#browserweb_vitalclssourcekey) | | [`code.filepath`](./code.md#codefilepath) | [`code.file.path`](./code.md#codefilepath) | | [`code.function`](./code.md#codefunction) | [`code.function.name`](./code.md#codefunctionname) | | [`code.lineno`](./code.md#codelineno) | [`code.line.number`](./code.md#codelinenumber) | diff --git a/generated/attributes/browser.md b/generated/attributes/browser.md index dd3d10d..4d97909 100644 --- a/generated/attributes/browser.md +++ b/generated/attributes/browser.md @@ -9,7 +9,7 @@ - [browser.script.invoker_type](#browserscriptinvoker_type) - [browser.script.source_char_position](#browserscriptsource_char_position) - [browser.version](#browserversion) - - [browser.web_vital.cls.source.](#browserweb_vitalclssource) + - [browser.web_vital.cls.source.\](#browserweb_vitalclssourcekey) ## Stable Attributes @@ -81,9 +81,9 @@ The version of the browser. | Example | `120.0.6099.130` | | Aliases | `sentry.browser.version` | -### browser.web_vital.cls.source. +### browser.web_vital.cls.source.\ -The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N +The HTML elements or components responsible for the layout shift. \ is a numeric index from 1 to N | Property | Value | | --- | --- | @@ -91,5 +91,5 @@ The HTML elements or components responsible for the layout shift. is a n | Has PII | maybe | | Exists in OpenTelemetry | No | | Example | `body > div#app` | -| Aliases | `cls.source.` | +| Aliases | `cls.source.\` | diff --git a/generated/attributes/cls.md b/generated/attributes/cls.md index bba25a0..4f34f1b 100644 --- a/generated/attributes/cls.md +++ b/generated/attributes/cls.md @@ -2,14 +2,16 @@ # Cls Attributes -- [Stable Attributes](#stable-attributes) - - [cls.source.](#clssource) +- [Deprecated Attributes](#deprecated-attributes) + - [cls.source.\](#clssourcekey) -## Stable Attributes +## Deprecated Attributes -### cls.source. +These attributes are deprecated and will be removed in a future version. Please use the recommended replacements. -The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N +### cls.source.\ + +The HTML elements or components responsible for the layout shift. \ is a numeric index from 1 to N | Property | Value | | --- | --- | @@ -17,5 +19,7 @@ The HTML elements or components responsible for the layout shift. is a n | Has PII | maybe | | Exists in OpenTelemetry | No | | Example | `body > div#app` | -| Aliases | `browser.web_vital.cls.source.` | +| Deprecated | Yes, use `browser.web_vital.cls.source.\` instead | +| Deprecation Reason | The CLS source is now recorded as a browser.web_vital.cls.source.\ attribute. | +| Aliases | `browser.web_vital.cls.source.\` | diff --git a/javascript/sentry-conventions/src/attributes.ts b/javascript/sentry-conventions/src/attributes.ts index 316f1f5..3d9ab2d 100644 --- a/javascript/sentry-conventions/src/attributes.ts +++ b/javascript/sentry-conventions/src/attributes.ts @@ -878,27 +878,27 @@ export const BROWSER_VERSION = 'browser.version'; */ export type BROWSER_VERSION_TYPE = string; -// Path: model/attributes/browser/browser__web_vital__cls__source__.json +// Path: model/attributes/browser/browser__web_vital__cls__source__[key].json /** - * The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N `browser.web_vital.cls.source.` + * The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N `browser.web_vital.cls.source.` * - * Attribute Value Type: `string` {@link BROWSER_WEB_VITAL_CLS_SOURCE_INDEX_TYPE} + * Attribute Value Type: `string` {@link BROWSER_WEB_VITAL_CLS_SOURCE_KEY_TYPE} * * Contains PII: maybe * * Attribute defined in OTEL: No * - * Aliases: {@link CLS_SOURCE_INDEX} `cls.source.` + * Aliases: {@link CLS_SOURCE_KEY} `cls.source.` * * @example "body > div#app" */ -export const BROWSER_WEB_VITAL_CLS_SOURCE_INDEX = 'browser.web_vital.cls.source.'; +export const BROWSER_WEB_VITAL_CLS_SOURCE_KEY = 'browser.web_vital.cls.source.'; /** - * Type for {@link BROWSER_WEB_VITAL_CLS_SOURCE_INDEX} browser.web_vital.cls.source. + * Type for {@link BROWSER_WEB_VITAL_CLS_SOURCE_KEY} browser.web_vital.cls.source. */ -export type BROWSER_WEB_VITAL_CLS_SOURCE_INDEX_TYPE = string; +export type BROWSER_WEB_VITAL_CLS_SOURCE_KEY_TYPE = string; // Path: model/attributes/cache/cache__hit.json @@ -1122,27 +1122,28 @@ export const CLOUDFLARE_D1_ROWS_WRITTEN = 'cloudflare.d1.rows_written'; */ export type CLOUDFLARE_D1_ROWS_WRITTEN_TYPE = number; -// Path: model/attributes/cls/cls__source__.json +// Path: model/attributes/cls/cls__source__[key].json /** - * The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N `cls.source.` + * The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N `cls.source.` * - * Attribute Value Type: `string` {@link CLS_SOURCE_INDEX_TYPE} + * Attribute Value Type: `string` {@link CLS_SOURCE_KEY_TYPE} * * Contains PII: maybe * * Attribute defined in OTEL: No * - * Aliases: {@link BROWSER_WEB_VITAL_CLS_SOURCE_INDEX} `browser.web_vital.cls.source.` + * Aliases: {@link BROWSER_WEB_VITAL_CLS_SOURCE_KEY} `browser.web_vital.cls.source.` * + * @deprecated Use {@link BROWSER_WEB_VITAL_CLS_SOURCE_KEY} (browser.web_vital.cls.source.) instead - The CLS source is now recorded as a browser.web_vital.cls.source. attribute. * @example "body > div#app" */ -export const CLS_SOURCE_INDEX = 'cls.source.'; +export const CLS_SOURCE_KEY = 'cls.source.'; /** - * Type for {@link CLS_SOURCE_INDEX} cls.source. + * Type for {@link CLS_SOURCE_KEY} cls.source. */ -export type CLS_SOURCE_INDEX_TYPE = string; +export type CLS_SOURCE_KEY_TYPE = string; // Path: model/attributes/code/code__filepath.json @@ -8893,7 +8894,7 @@ export const ATTRIBUTE_TYPE: Record = { [BROWSER_SCRIPT_INVOKER_TYPE]: 'string', [BROWSER_SCRIPT_SOURCE_CHAR_POSITION]: 'integer', [BROWSER_VERSION]: 'string', - [BROWSER_WEB_VITAL_CLS_SOURCE_INDEX]: 'string', + [BROWSER_WEB_VITAL_CLS_SOURCE_KEY]: 'string', [CACHE_HIT]: 'boolean', [CACHE_ITEM_SIZE]: 'integer', [CACHE_KEY]: 'string[]', @@ -8905,7 +8906,7 @@ export const ATTRIBUTE_TYPE: Record = { [CLOUDFLARE_D1_DURATION]: 'integer', [CLOUDFLARE_D1_ROWS_READ]: 'integer', [CLOUDFLARE_D1_ROWS_WRITTEN]: 'integer', - [CLS_SOURCE_INDEX]: 'string', + [CLS_SOURCE_KEY]: 'string', [CODE_FILEPATH]: 'string', [CODE_FILE_PATH]: 'string', [CODE_FUNCTION]: 'string', @@ -9320,7 +9321,7 @@ export type AttributeName = | typeof BROWSER_SCRIPT_INVOKER_TYPE | typeof BROWSER_SCRIPT_SOURCE_CHAR_POSITION | typeof BROWSER_VERSION - | typeof BROWSER_WEB_VITAL_CLS_SOURCE_INDEX + | typeof BROWSER_WEB_VITAL_CLS_SOURCE_KEY | typeof CACHE_HIT | typeof CACHE_ITEM_SIZE | typeof CACHE_KEY @@ -9332,7 +9333,7 @@ export type AttributeName = | typeof CLOUDFLARE_D1_DURATION | typeof CLOUDFLARE_D1_ROWS_READ | typeof CLOUDFLARE_D1_ROWS_WRITTEN - | typeof CLS_SOURCE_INDEX + | typeof CLS_SOURCE_KEY | typeof CODE_FILEPATH | typeof CODE_FILE_PATH | typeof CODE_FUNCTION @@ -10170,15 +10171,15 @@ export const ATTRIBUTE_METADATA: Record = { example: '120.0.6099.130', aliases: [SENTRY_BROWSER_VERSION], }, - [BROWSER_WEB_VITAL_CLS_SOURCE_INDEX]: { - brief: 'The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N', + [BROWSER_WEB_VITAL_CLS_SOURCE_KEY]: { + brief: 'The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N', type: 'string', pii: { isPii: 'maybe', }, isInOtel: false, example: 'body > div#app', - aliases: [CLS_SOURCE_INDEX], + aliases: [CLS_SOURCE_KEY], sdks: ['javascript-browser'], }, [CACHE_HIT]: { @@ -10290,15 +10291,19 @@ export const ATTRIBUTE_METADATA: Record = { example: 12, sdks: ['javascript-cloudflare'], }, - [CLS_SOURCE_INDEX]: { - brief: 'The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N', + [CLS_SOURCE_KEY]: { + brief: 'The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N', type: 'string', pii: { isPii: 'maybe', }, isInOtel: false, example: 'body > div#app', - aliases: [BROWSER_WEB_VITAL_CLS_SOURCE_INDEX], + deprecation: { + replacement: 'browser.web_vital.cls.source.', + reason: 'The CLS source is now recorded as a browser.web_vital.cls.source. attribute.', + }, + aliases: [BROWSER_WEB_VITAL_CLS_SOURCE_KEY], sdks: ['javascript-browser'], }, [CODE_FILEPATH]: { @@ -14096,7 +14101,7 @@ export type Attributes = { [BROWSER_SCRIPT_INVOKER_TYPE]?: BROWSER_SCRIPT_INVOKER_TYPE_TYPE; [BROWSER_SCRIPT_SOURCE_CHAR_POSITION]?: BROWSER_SCRIPT_SOURCE_CHAR_POSITION_TYPE; [BROWSER_VERSION]?: BROWSER_VERSION_TYPE; - [BROWSER_WEB_VITAL_CLS_SOURCE_INDEX]?: BROWSER_WEB_VITAL_CLS_SOURCE_INDEX_TYPE; + [BROWSER_WEB_VITAL_CLS_SOURCE_KEY]?: BROWSER_WEB_VITAL_CLS_SOURCE_KEY_TYPE; [CACHE_HIT]?: CACHE_HIT_TYPE; [CACHE_ITEM_SIZE]?: CACHE_ITEM_SIZE_TYPE; [CACHE_KEY]?: CACHE_KEY_TYPE; @@ -14108,7 +14113,7 @@ export type Attributes = { [CLOUDFLARE_D1_DURATION]?: CLOUDFLARE_D1_DURATION_TYPE; [CLOUDFLARE_D1_ROWS_READ]?: CLOUDFLARE_D1_ROWS_READ_TYPE; [CLOUDFLARE_D1_ROWS_WRITTEN]?: CLOUDFLARE_D1_ROWS_WRITTEN_TYPE; - [CLS_SOURCE_INDEX]?: CLS_SOURCE_INDEX_TYPE; + [CLS_SOURCE_KEY]?: CLS_SOURCE_KEY_TYPE; [CODE_FILEPATH]?: CODE_FILEPATH_TYPE; [CODE_FILE_PATH]?: CODE_FILE_PATH_TYPE; [CODE_FUNCTION]?: CODE_FUNCTION_TYPE; diff --git a/model/attributes/browser/browser__web_vital__cls__source__.json b/model/attributes/browser/browser__web_vital__cls__source__[key].json similarity index 60% rename from model/attributes/browser/browser__web_vital__cls__source__.json rename to model/attributes/browser/browser__web_vital__cls__source__[key].json index ee8195f..677e997 100644 --- a/model/attributes/browser/browser__web_vital__cls__source__.json +++ b/model/attributes/browser/browser__web_vital__cls__source__[key].json @@ -1,12 +1,12 @@ { - "key": "browser.web_vital.cls.source.", - "brief": "The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", + "key": "browser.web_vital.cls.source.", + "brief": "The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", "type": "string", "pii": { "key": "maybe" }, "is_in_otel": false, "example": "body > div#app", - "alias": ["cls.source."], + "alias": ["cls.source."], "sdks": ["javascript-browser"] } diff --git a/model/attributes/cls/cls__source__.json b/model/attributes/cls/cls__source__[key].json similarity index 58% rename from model/attributes/cls/cls__source__.json rename to model/attributes/cls/cls__source__[key].json index bfa6aa3..046aa24 100644 --- a/model/attributes/cls/cls__source__.json +++ b/model/attributes/cls/cls__source__[key].json @@ -1,6 +1,6 @@ { - "key": "cls.source.", - "brief": "The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", + "key": "cls.source.", + "brief": "The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", "type": "string", "pii": { "key": "maybe" @@ -9,9 +9,9 @@ "example": "body > div#app", "sdks": ["javascript-browser"], "deprecation": { - "replacement": "browser.web_vital.cls.source.", - "reason": "The CLS source is now recorded as a browser.web_vital.cls.source. attribute.", + "replacement": "browser.web_vital.cls.source.", + "reason": "The CLS source is now recorded as a browser.web_vital.cls.source. attribute.", "_status": "backfill" }, - "alias": ["browser.web_vital.cls.source."] + "alias": ["browser.web_vital.cls.source."] } diff --git a/python/src/sentry_conventions/attributes.py b/python/src/sentry_conventions/attributes.py index fa5de72..d28b3c7 100644 --- a/python/src/sentry_conventions/attributes.py +++ b/python/src/sentry_conventions/attributes.py @@ -105,6 +105,7 @@ class _AttributeNamesMeta(type): "AI_TOP_K", "AI_TOP_P", "AI_TOTAL_TOKENS_USED", + "CLS_SOURCE_KEY", "CODE_FILEPATH", "CODE_FUNCTION", "CODE_LINENO", @@ -635,16 +636,16 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Example: "120.0.6099.130" """ - # Path: model/attributes/browser/browser__web_vital__cls__source__.json - BROWSER_WEB_VITAL_CLS_SOURCE_INDEX: Literal[ - "browser.web_vital.cls.source." - ] = "browser.web_vital.cls.source." - """The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N + # Path: model/attributes/browser/browser__web_vital__cls__source__[key].json + BROWSER_WEB_VITAL_CLS_SOURCE_KEY: Literal["browser.web_vital.cls.source."] = ( + "browser.web_vital.cls.source." + ) + """The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N Type: str Contains PII: maybe Defined in OTEL: No - Aliases: cls.source. + Aliases: cls.source. Example: "body > div#app" """ @@ -763,14 +764,15 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Example: 12 """ - # Path: model/attributes/cls/cls__source__.json - CLS_SOURCE_INDEX: Literal["cls.source."] = "cls.source." - """The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N + # Path: model/attributes/cls/cls__source__[key].json + CLS_SOURCE_KEY: Literal["cls.source."] = "cls.source." + """The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N Type: str Contains PII: maybe Defined in OTEL: No - Aliases: browser.web_vital.cls.source. + Aliases: browser.web_vital.cls.source. + DEPRECATED: Use browser.web_vital.cls.source. instead - The CLS source is now recorded as a browser.web_vital.cls.source. attribute. Example: "body > div#app" """ @@ -5179,13 +5181,13 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): example="120.0.6099.130", aliases=["sentry.browser.version"], ), - "browser.web_vital.cls.source.": AttributeMetadata( - brief="The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", + "browser.web_vital.cls.source.": AttributeMetadata( + brief="The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", type=AttributeType.STRING, pii=PiiInfo(isPii=IsPii.MAYBE), is_in_otel=False, example="body > div#app", - aliases=["cls.source."], + aliases=["cls.source."], sdks=["javascript-browser"], ), "cache.hit": AttributeMetadata( @@ -5274,13 +5276,18 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): example=12, sdks=["javascript-cloudflare"], ), - "cls.source.": AttributeMetadata( - brief="The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", + "cls.source.": AttributeMetadata( + brief="The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", type=AttributeType.STRING, pii=PiiInfo(isPii=IsPii.MAYBE), is_in_otel=False, example="body > div#app", - aliases=["browser.web_vital.cls.source."], + deprecation=DeprecationInfo( + replacement="browser.web_vital.cls.source.", + reason="The CLS source is now recorded as a browser.web_vital.cls.source. attribute.", + status=DeprecationStatus.BACKFILL, + ), + aliases=["browser.web_vital.cls.source."], sdks=["javascript-browser"], ), "code.file.path": AttributeMetadata( @@ -8198,7 +8205,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): "browser.script.invoker_type": str, "browser.script.source_char_position": int, "browser.version": str, - "browser.web_vital.cls.source.": str, + "browser.web_vital.cls.source.": str, "cache.hit": bool, "cache.item_size": int, "cache.key": List[str], @@ -8210,7 +8217,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): "cloudflare.d1.duration": int, "cloudflare.d1.rows_read": int, "cloudflare.d1.rows_written": int, - "cls.source.": str, + "cls.source.": str, "code.file.path": str, "code.filepath": str, "code.function": str, diff --git a/shared/deprecated_attributes.json b/shared/deprecated_attributes.json index f02695e..dbc9c93 100644 --- a/shared/deprecated_attributes.json +++ b/shared/deprecated_attributes.json @@ -444,6 +444,23 @@ }, "alias": ["gen_ai.usage.total_tokens"] }, + { + "key": "cls.source.", + "brief": "The HTML elements or components responsible for the layout shift. is a numeric index from 1 to N", + "type": "string", + "pii": { + "key": "maybe" + }, + "is_in_otel": false, + "example": "body > div#app", + "sdks": ["javascript-browser"], + "deprecation": { + "replacement": "browser.web_vital.cls.source.", + "reason": "The CLS source is now recorded as a browser.web_vital.cls.source. attribute.", + "_status": "backfill" + }, + "alias": ["browser.web_vital.cls.source."] + }, { "key": "code.filepath", "brief": "The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path).", From 775d93c0c62e528e1bcc0ff634b8e9a64e1556a8 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 23 Jan 2026 11:50:33 +0100 Subject: [PATCH 3/3] has_dynamic_suffix --- generated/attributes/browser.md | 1 + generated/attributes/cls.md | 1 + javascript/sentry-conventions/src/attributes.ts | 6 ++++++ .../browser/browser__web_vital__cls__source__[key].json | 3 ++- model/attributes/cls/cls__source__[key].json | 1 + python/src/sentry_conventions/attributes.py | 4 ++++ shared/deprecated_attributes.json | 1 + 7 files changed, 16 insertions(+), 1 deletion(-) diff --git a/generated/attributes/browser.md b/generated/attributes/browser.md index 4d97909..cdf579b 100644 --- a/generated/attributes/browser.md +++ b/generated/attributes/browser.md @@ -90,6 +90,7 @@ The HTML elements or components responsible for the layout shift. \ is a n | Type | `string` | | Has PII | maybe | | Exists in OpenTelemetry | No | +| Has dynamic suffix | Yes | | Example | `body > div#app` | | Aliases | `cls.source.\` | diff --git a/generated/attributes/cls.md b/generated/attributes/cls.md index 4f34f1b..743b649 100644 --- a/generated/attributes/cls.md +++ b/generated/attributes/cls.md @@ -18,6 +18,7 @@ The HTML elements or components responsible for the layout shift. \ is a n | Type | `string` | | Has PII | maybe | | Exists in OpenTelemetry | No | +| Has dynamic suffix | Yes | | Example | `body > div#app` | | Deprecated | Yes, use `browser.web_vital.cls.source.\` instead | | Deprecation Reason | The CLS source is now recorded as a browser.web_vital.cls.source.\ attribute. | diff --git a/javascript/sentry-conventions/src/attributes.ts b/javascript/sentry-conventions/src/attributes.ts index 3d9ab2d..62adbe7 100644 --- a/javascript/sentry-conventions/src/attributes.ts +++ b/javascript/sentry-conventions/src/attributes.ts @@ -889,6 +889,8 @@ export type BROWSER_VERSION_TYPE = string; * * Attribute defined in OTEL: No * + * Has Dynamic Suffix: true + * * Aliases: {@link CLS_SOURCE_KEY} `cls.source.` * * @example "body > div#app" @@ -1133,6 +1135,8 @@ export type CLOUDFLARE_D1_ROWS_WRITTEN_TYPE = number; * * Attribute defined in OTEL: No * + * Has Dynamic Suffix: true + * * Aliases: {@link BROWSER_WEB_VITAL_CLS_SOURCE_KEY} `browser.web_vital.cls.source.` * * @deprecated Use {@link BROWSER_WEB_VITAL_CLS_SOURCE_KEY} (browser.web_vital.cls.source.) instead - The CLS source is now recorded as a browser.web_vital.cls.source. attribute. @@ -10178,6 +10182,7 @@ export const ATTRIBUTE_METADATA: Record = { isPii: 'maybe', }, isInOtel: false, + hasDynamicSuffix: true, example: 'body > div#app', aliases: [CLS_SOURCE_KEY], sdks: ['javascript-browser'], @@ -10298,6 +10303,7 @@ export const ATTRIBUTE_METADATA: Record = { isPii: 'maybe', }, isInOtel: false, + hasDynamicSuffix: true, example: 'body > div#app', deprecation: { replacement: 'browser.web_vital.cls.source.', diff --git a/model/attributes/browser/browser__web_vital__cls__source__[key].json b/model/attributes/browser/browser__web_vital__cls__source__[key].json index 677e997..7414666 100644 --- a/model/attributes/browser/browser__web_vital__cls__source__[key].json +++ b/model/attributes/browser/browser__web_vital__cls__source__[key].json @@ -8,5 +8,6 @@ "is_in_otel": false, "example": "body > div#app", "alias": ["cls.source."], - "sdks": ["javascript-browser"] + "sdks": ["javascript-browser"], + "has_dynamic_suffix": true } diff --git a/model/attributes/cls/cls__source__[key].json b/model/attributes/cls/cls__source__[key].json index 046aa24..2a0549b 100644 --- a/model/attributes/cls/cls__source__[key].json +++ b/model/attributes/cls/cls__source__[key].json @@ -13,5 +13,6 @@ "reason": "The CLS source is now recorded as a browser.web_vital.cls.source. attribute.", "_status": "backfill" }, + "has_dynamic_suffix": true, "alias": ["browser.web_vital.cls.source."] } diff --git a/python/src/sentry_conventions/attributes.py b/python/src/sentry_conventions/attributes.py index d28b3c7..a856e37 100644 --- a/python/src/sentry_conventions/attributes.py +++ b/python/src/sentry_conventions/attributes.py @@ -645,6 +645,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Type: str Contains PII: maybe Defined in OTEL: No + Has Dynamic Suffix: true Aliases: cls.source. Example: "body > div#app" """ @@ -771,6 +772,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Type: str Contains PII: maybe Defined in OTEL: No + Has Dynamic Suffix: true Aliases: browser.web_vital.cls.source. DEPRECATED: Use browser.web_vital.cls.source. instead - The CLS source is now recorded as a browser.web_vital.cls.source. attribute. Example: "body > div#app" @@ -5186,6 +5188,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): type=AttributeType.STRING, pii=PiiInfo(isPii=IsPii.MAYBE), is_in_otel=False, + has_dynamic_suffix=True, example="body > div#app", aliases=["cls.source."], sdks=["javascript-browser"], @@ -5281,6 +5284,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): type=AttributeType.STRING, pii=PiiInfo(isPii=IsPii.MAYBE), is_in_otel=False, + has_dynamic_suffix=True, example="body > div#app", deprecation=DeprecationInfo( replacement="browser.web_vital.cls.source.", diff --git a/shared/deprecated_attributes.json b/shared/deprecated_attributes.json index dbc9c93..5ee0121 100644 --- a/shared/deprecated_attributes.json +++ b/shared/deprecated_attributes.json @@ -459,6 +459,7 @@ "reason": "The CLS source is now recorded as a browser.web_vital.cls.source. attribute.", "_status": "backfill" }, + "has_dynamic_suffix": true, "alias": ["browser.web_vital.cls.source."] }, {