Skip to content
Draft
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
138 changes: 114 additions & 24 deletions javascript/sentry-conventions/src/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ export type APP_NAME_TYPE = string;
*
* Aliases: {@link APP_VITALS_START_COLD_VALUE} `app.vitals.start.cold.value`
*
* @deprecated Use {@link APP_VITALS_START_COLD_VALUE} (app.vitals.start.cold.value) instead - Replaced by app.vitals.start.cold.value to align with the app.vitals.* namespace for mobile performance attributes
* @deprecated Use {@link APP_VITALS_START_VALUE} (app.vitals.start.value) instead - Replaced by app.vitals.start.value plus app.vitals.start.type
* @example 1234.56
*/
export const APP_START_COLD = 'app_start_cold';
Expand Down Expand Up @@ -1226,7 +1226,7 @@ export type APP_START_TYPE_TYPE = string;
*
* Aliases: {@link APP_VITALS_START_WARM_VALUE} `app.vitals.start.warm.value`
*
* @deprecated Use {@link APP_VITALS_START_WARM_VALUE} (app.vitals.start.warm.value) instead - Replaced by app.vitals.start.warm.value to align with the app.vitals.* namespace for mobile performance attributes
* @deprecated Use {@link APP_VITALS_START_VALUE} (app.vitals.start.value) instead - Replaced by app.vitals.start.value plus app.vitals.start.type
* @example 1234.56
*/
export const APP_START_WARM = 'app_start_warm';
Expand Down Expand Up @@ -1457,6 +1457,7 @@ export type APP_VITALS_STALL_PERCENTAGE_TYPE = number;
*
* Aliases: {@link APP_START_COLD} `app_start_cold`
*
* @deprecated Use {@link APP_VITALS_START_VALUE} (app.vitals.start.value) instead - Replaced by app.vitals.start.value plus app.vitals.start.type. Cold and warm are not aliases of the unified value because they are mutually exclusive type-specific names.
* @example 1234.56
*/
export const APP_VITALS_START_COLD_VALUE = 'app.vitals.start.cold.value';
Expand Down Expand Up @@ -1552,6 +1553,27 @@ export const APP_VITALS_START_TYPE = 'app.vitals.start.type';
*/
export type APP_VITALS_START_TYPE_TYPE = string;

// Path: model/attributes/app/app__vitals__start__value.json

/**
* The duration of an app start in milliseconds. Use with app.vitals.start.type to distinguish cold vs warm starts. `app.vitals.start.value`
*
* Attribute Value Type: `number` {@link APP_VITALS_START_VALUE_TYPE}
*
* Apply Scrubbing: manual
*
* Attribute defined in OTEL: No
* Visibility: public
*
* @example 1234.56
*/
export const APP_VITALS_START_VALUE = 'app.vitals.start.value';

/**
* Type for {@link APP_VITALS_START_VALUE} app.vitals.start.value
*/
export type APP_VITALS_START_VALUE_TYPE = number;

// Path: model/attributes/app/app__vitals__start__warm__value.json

/**
Expand All @@ -1566,6 +1588,7 @@ export type APP_VITALS_START_TYPE_TYPE = string;
*
* Aliases: {@link APP_START_WARM} `app_start_warm`
*
* @deprecated Use {@link APP_VITALS_START_VALUE} (app.vitals.start.value) instead - Replaced by app.vitals.start.value plus app.vitals.start.type. Cold and warm are not aliases of the unified value because they are mutually exclusive type-specific names.
* @example 1234.56
*/
export const APP_VITALS_START_WARM_VALUE = 'app.vitals.start.warm.value';
Expand Down Expand Up @@ -17769,6 +17792,7 @@ export const ATTRIBUTE_TYPE: Record<string, AttributeType> = {
'app.vitals.start.reason': 'string',
'app.vitals.start.screen': 'string',
'app.vitals.start.type': 'string',
'app.vitals.start.value': 'double',
'app.vitals.start.warm.value': 'double',
'app.vitals.ttfd.value': 'double',
'app.vitals.ttid.value': 'double',
Expand Down Expand Up @@ -18564,6 +18588,7 @@ export type AttributeName =
| typeof APP_VITALS_START_REASON
| typeof APP_VITALS_START_SCREEN
| typeof APP_VITALS_START_TYPE
| typeof APP_VITALS_START_VALUE
| typeof APP_VITALS_START_WARM_VALUE
| typeof APP_VITALS_TTFD_VALUE
| typeof APP_VITALS_TTID_VALUE
Expand Down Expand Up @@ -20162,21 +20187,26 @@ export const ATTRIBUTE_METADATA: Record<AttributeName, AttributeMetadata> = {
app_start_cold: {
brief: 'The duration of a cold app start in milliseconds',
type: 'double',
keys: ['app.vitals.start.cold.value', 'app_start_cold'],
keys: ['app_start_cold'],
applyScrubbing: {
key: 'manual',
},
isInOtel: false,
visibility: 'public',
example: 1234.56,
deprecation: {
replacement: 'app.vitals.start.cold.value',
reason:
'Replaced by app.vitals.start.cold.value to align with the app.vitals.* namespace for mobile performance attributes',
status: 'backfill',
replacement: 'app.vitals.start.value',
reason: 'Replaced by app.vitals.start.value plus app.vitals.start.type',
status: 'transform',
transformation: 'app_vitals_start_cold_warm_to_value',
},
aliases: ['app.vitals.start.cold.value'],
changelog: [
{
version: 'next',
prs: [576],
description: 'Retargeted deprecation replacement to app.vitals.start.value via transform',
},
{ version: '0.5.0', prs: [323], description: 'Added and deprecated in favor of app.vitals.start.cold.value' },
],
},
Expand Down Expand Up @@ -20219,21 +20249,26 @@ export const ATTRIBUTE_METADATA: Record<AttributeName, AttributeMetadata> = {
app_start_warm: {
brief: 'The duration of a warm app start in milliseconds',
type: 'double',
keys: ['app.vitals.start.warm.value', 'app_start_warm'],
keys: ['app_start_warm'],
applyScrubbing: {
key: 'manual',
},
isInOtel: false,
visibility: 'public',
example: 1234.56,
deprecation: {
replacement: 'app.vitals.start.warm.value',
reason:
'Replaced by app.vitals.start.warm.value to align with the app.vitals.* namespace for mobile performance attributes',
status: 'backfill',
replacement: 'app.vitals.start.value',
reason: 'Replaced by app.vitals.start.value plus app.vitals.start.type',
status: 'transform',
transformation: 'app_vitals_start_cold_warm_to_value',
},
aliases: ['app.vitals.start.warm.value'],
changelog: [
{
version: 'next',
prs: [576],
description: 'Retargeted deprecation replacement to app.vitals.start.value via transform',
},
{ version: '0.5.0', prs: [323], description: 'Added and deprecated in favor of app.vitals.start.warm.value' },
],
},
Expand Down Expand Up @@ -20373,15 +20408,29 @@ export const ATTRIBUTE_METADATA: Record<AttributeName, AttributeMetadata> = {
'app.vitals.start.cold.value': {
brief: 'The duration of a cold app start in milliseconds',
type: 'double',
keys: ['app.vitals.start.cold.value', 'app_start_cold'],
keys: ['app.vitals.start.cold.value'],
applyScrubbing: {
key: 'manual',
},
isInOtel: false,
visibility: 'public',
example: 1234.56,
deprecation: {
replacement: 'app.vitals.start.value',
reason:
'Replaced by app.vitals.start.value plus app.vitals.start.type. Cold and warm are not aliases of the unified value because they are mutually exclusive type-specific names.',
status: 'transform',
transformation: 'app_vitals_start_cold_warm_to_value',
},
aliases: ['app_start_cold'],
changelog: [{ version: '0.5.0', prs: [313], description: 'Added app.vitals.start.cold.value attribute' }],
changelog: [
{
version: 'next',
prs: [576],
description: 'Deprecated in favor of app.vitals.start.value plus app.vitals.start.type via transform',
},
{ version: '0.5.0', prs: [313], description: 'Added app.vitals.start.cold.value attribute' },
],
},
'app.vitals.start.prewarmed': {
brief: 'Whether the app start was prewarmed.',
Expand Down Expand Up @@ -20433,18 +20482,51 @@ export const ATTRIBUTE_METADATA: Record<AttributeName, AttributeMetadata> = {
aliases: ['app_start_type'],
changelog: [{ version: '0.5.0', prs: [313], description: 'Added app.vitals.start.type attribute' }],
},
'app.vitals.start.value': {
brief:
'The duration of an app start in milliseconds. Use with app.vitals.start.type to distinguish cold vs warm starts.',
type: 'double',
keys: ['app.vitals.start.value'],
applyScrubbing: {
key: 'manual',
},
isInOtel: false,
visibility: 'public',
example: 1234.56,
changelog: [
{ version: 'next', prs: [576], description: 'Added app.vitals.start.value as the unified app start duration' },
],
additionalContext: [
'Send this together with app.vitals.start.type (`cold` or `warm`). This replaces app.vitals.start.cold.value and app.vitals.start.warm.value.',
'Not aliased to the cold/warm attributes: those names are type-specific, not 1:1 copies of this key. Ingest derives this attribute (and type) from the older names via the app_vitals_start_cold_warm_to_value transformation.',
],
},
'app.vitals.start.warm.value': {
brief: 'The duration of a warm app start in milliseconds',
type: 'double',
keys: ['app.vitals.start.warm.value', 'app_start_warm'],
keys: ['app.vitals.start.warm.value'],
applyScrubbing: {
key: 'manual',
},
isInOtel: false,
visibility: 'public',
example: 1234.56,
deprecation: {
replacement: 'app.vitals.start.value',
reason:
'Replaced by app.vitals.start.value plus app.vitals.start.type. Cold and warm are not aliases of the unified value because they are mutually exclusive type-specific names.',
status: 'transform',
transformation: 'app_vitals_start_cold_warm_to_value',
},
aliases: ['app_start_warm'],
changelog: [{ version: '0.5.0', prs: [313], description: 'Added app.vitals.start.warm.value attribute' }],
changelog: [
{
version: 'next',
prs: [576],
description: 'Deprecated in favor of app.vitals.start.value plus app.vitals.start.type via transform',
},
{ version: '0.5.0', prs: [313], description: 'Added app.vitals.start.warm.value attribute' },
],
},
'app.vitals.ttfd.value': {
brief: 'The duration of time to full display in milliseconds',
Expand Down Expand Up @@ -31788,10 +31870,10 @@ export const ATTRIBUTE_SEARCH_METADATA: Record<string, AttributeSearchMetadata>
deprecationChain: ['app.vitals.stall.percentage', 'stall_percentage'],
},
'app.vitals.start.cold.value': {
canonicalName: 'app.vitals.start.cold.value',
canonicalName: 'app.vitals.start.value',
type: 'double',
brief: 'The duration of a cold app start in milliseconds',
deprecationChain: ['app.vitals.start.cold.value', 'app_start_cold'],
deprecationChain: ['app.vitals.start.cold.value'],
},
'app.vitals.start.prewarmed': {
canonicalName: 'app.vitals.start.prewarmed',
Expand All @@ -31818,11 +31900,18 @@ export const ATTRIBUTE_SEARCH_METADATA: Record<string, AttributeSearchMetadata>
brief: 'The type of app start, for example `cold` or `warm`',
deprecationChain: ['app.vitals.start.type', 'app_start_type'],
},
'app.vitals.start.value': {
canonicalName: 'app.vitals.start.value',
type: 'double',
brief:
'The duration of an app start in milliseconds. Use with app.vitals.start.type to distinguish cold vs warm starts.',
deprecationChain: ['app.vitals.start.value'],
},
'app.vitals.start.warm.value': {
canonicalName: 'app.vitals.start.warm.value',
canonicalName: 'app.vitals.start.value',
type: 'double',
brief: 'The duration of a warm app start in milliseconds',
deprecationChain: ['app.vitals.start.warm.value', 'app_start_warm'],
deprecationChain: ['app.vitals.start.warm.value'],
},
'app.vitals.ttfd.value': {
canonicalName: 'app.vitals.ttfd.value',
Expand All @@ -31837,10 +31926,10 @@ export const ATTRIBUTE_SEARCH_METADATA: Record<string, AttributeSearchMetadata>
deprecationChain: ['app.vitals.ttid.value', 'time_to_initial_display'],
},
app_start_cold: {
canonicalName: 'app.vitals.start.cold.value',
canonicalName: 'app.vitals.start.value',
type: 'double',
brief: 'The duration of a cold app start in milliseconds',
deprecationChain: ['app.vitals.start.cold.value', 'app_start_cold'],
deprecationChain: ['app_start_cold'],
},
app_start_type: {
canonicalName: 'app.vitals.start.type',
Expand All @@ -31849,10 +31938,10 @@ export const ATTRIBUTE_SEARCH_METADATA: Record<string, AttributeSearchMetadata>
deprecationChain: ['app.vitals.start.type', 'app_start_type'],
},
app_start_warm: {
canonicalName: 'app.vitals.start.warm.value',
canonicalName: 'app.vitals.start.value',
type: 'double',
brief: 'The duration of a warm app start in milliseconds',
deprecationChain: ['app.vitals.start.warm.value', 'app_start_warm'],
deprecationChain: ['app_start_warm'],
},
'art.gc.blocking_count': {
canonicalName: 'art.gc.blocking_count',
Expand Down Expand Up @@ -36414,6 +36503,7 @@ export type Attributes = {
[APP_VITALS_START_REASON]?: APP_VITALS_START_REASON_TYPE;
[APP_VITALS_START_SCREEN]?: APP_VITALS_START_SCREEN_TYPE;
[APP_VITALS_START_TYPE]?: APP_VITALS_START_TYPE_TYPE;
[APP_VITALS_START_VALUE]?: APP_VITALS_START_VALUE_TYPE;
[APP_VITALS_START_WARM_VALUE]?: APP_VITALS_START_WARM_VALUE_TYPE;
[APP_VITALS_TTFD_VALUE]?: APP_VITALS_TTFD_VALUE_TYPE;
[APP_VITALS_TTID_VALUE]?: APP_VITALS_TTID_VALUE_TYPE;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"id": "app_vitals_start_cold_warm_to_value",
"brief": "Derive unified app.vitals.start.value and app.vitals.start.type from the type-specific cold and warm duration attributes. Cold and warm are mutually exclusive, so they are not 1:1 aliases of the unified key.",
"inputs": [
{
"attribute": "app.vitals.start.cold.value",
"brief": "Deprecated cold app start duration."
},
{
"attribute": "app.vitals.start.warm.value",
"brief": "Deprecated warm app start duration."
},
{
"attribute": "app_start_cold",
"brief": "Legacy cold app start duration."
},
{
"attribute": "app_start_warm",
"brief": "Legacy warm app start duration."
}
],
"outputs": [
{
"attribute": "app.vitals.start.value",
"brief": "Unified app start duration in milliseconds."
},
{
"attribute": "app.vitals.start.type",
"brief": "App start type, cold or warm."
}
],
"actions": [
"If app.vitals.start.value is already present, keep it and do not overwrite it.",
"Prefer app.vitals.start.cold.value over app_start_cold, and app.vitals.start.warm.value over app_start_warm, when both a namespaced and a legacy name are present.",
"If a cold duration is present and app.vitals.start.value is missing, copy that duration to app.vitals.start.value and set app.vitals.start.type to \"cold\" when type is missing.",
"Otherwise, if a warm duration is present and app.vitals.start.value is missing, copy that duration to app.vitals.start.value and set app.vitals.start.type to \"warm\" when type is missing.",
"Do not copy a source duration that exceeds 180000 milliseconds.",
"Leave the source cold and warm attributes in place. Do not treat cold and warm as interchangeable copies of the unified key."
],
"examples": [
{
"name": "cold namespaced duration",
"input": {
"app.vitals.start.cold.value": 1234.0
},
"output": {
"app.vitals.start.value": 1234.0,
"app.vitals.start.type": "cold"
}
},
{
"name": "warm namespaced duration",
"input": {
"app.vitals.start.warm.value": 567.0
},
"output": {
"app.vitals.start.value": 567.0,
"app.vitals.start.type": "warm"
}
},
{
"name": "legacy cold duration",
"input": {
"app_start_cold": 1234.0
},
"output": {
"app.vitals.start.value": 1234.0,
"app.vitals.start.type": "cold"
}
},
{
"name": "legacy warm duration",
"input": {
"app_start_warm": 567.0
},
"output": {
"app.vitals.start.value": 567.0,
"app.vitals.start.type": "warm"
}
}
]
}
11 changes: 11 additions & 0 deletions model/attributes/app/app__vitals__start__cold__value.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,19 @@
"is_in_otel": false,
"example": 1234.56,
"alias": ["app_start_cold"],
"deprecation": {
"replacement": "app.vitals.start.value",
"reason": "Replaced by app.vitals.start.value plus app.vitals.start.type. Cold and warm are not aliases of the unified value because they are mutually exclusive type-specific names.",
"_status": "transform",
"transformation": "app_vitals_start_cold_warm_to_value"
},
Comment thread
cursor[bot] marked this conversation as resolved.
Comment thread
buenaflor marked this conversation as resolved.
"visibility": "public",
"changelog": [
{
"version": "next",
"prs": [576],
"description": "Deprecated in favor of app.vitals.start.value plus app.vitals.start.type via transform"
},
{
"version": "0.5.0",
"prs": [313],
Expand Down
Loading
Loading