-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
Copy pathutils.ts
148 lines (131 loc) · 4.42 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import {DURATION_UNITS} from 'sentry/utils/discover/fieldRenderers';
import type {DiscoverDatasets} from 'sentry/utils/discover/types';
import getDuration from 'sentry/utils/duration/getDuration';
import {formatPercentage} from 'sentry/utils/number/formatPercentage';
import {VitalState} from 'sentry/views/performance/vitalDetail/utils';
const formatMetricValue = (metric: MetricValue, field?: string | undefined): string => {
if (metric.value === undefined) {
return '-';
}
if (typeof metric.value === 'number' && metric.type === 'duration' && metric.unit) {
const seconds =
// @ts-ignore TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
(metric.value * ((metric.unit && DURATION_UNITS[metric.unit]) ?? 1)) / 1000;
return getDuration(seconds, 2, true);
}
if (typeof metric.value === 'number' && metric.type === 'number') {
if (isFinite(metric.value)) {
return metric.value.toFixed(2);
}
return '-';
}
if (
field === 'division(mobile.slow_frames,mobile.total_frames)' ||
field === 'division(mobile.frozen_frames,mobile.total_frames)'
) {
if (typeof metric.value === 'number' && isFinite(metric.value)) {
return formatPercentage(metric.value, 2, {minimumValue: 0.0001});
}
return '-';
}
return String(metric.value);
};
// maps to PERFORMANCE_SCORE_COLORS keys
export enum PerformanceScore {
GOOD = 'good',
NEEDS_IMPROVEMENT = 'needsImprovement',
BAD = 'bad',
NONE = 'none',
}
export type VitalStatus = {
description: string | undefined;
formattedValue: string | undefined;
score: PerformanceScore;
value: MetricValue | undefined;
};
export type VitalItem = {
dataset: DiscoverDatasets;
description: string;
docs: React.ReactNode;
field: string;
getStatus: (value: MetricValue, field?: string | undefined) => VitalStatus;
platformDocLinks: Record<string, string>;
sdkDocLinks: Record<string, string>;
setup: React.ReactNode | undefined;
title: string;
};
export type MetricValue = {
// the field type if defined, e.g. duration
type: string | undefined;
// the unit of the value, e.g. milliseconds
unit: string | undefined;
// the actual value
value: string | number | undefined;
};
export const STATUS_UNKNOWN: VitalStatus = {
description: undefined,
formattedValue: undefined,
value: undefined,
score: PerformanceScore.NONE,
};
export function getColdAppStartPerformance(metric: MetricValue): VitalStatus {
let description = '';
let status = PerformanceScore.NONE;
if (typeof metric.value === 'number' && metric.unit) {
// @ts-ignore TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
const durationMs = metric.value * DURATION_UNITS[metric.unit];
// TODO should be platform dependant
if (durationMs > 5000) {
status = PerformanceScore.BAD;
description = VitalState.POOR;
} else if (durationMs > 3000) {
status = PerformanceScore.NEEDS_IMPROVEMENT;
description = VitalState.MEH;
} else if (durationMs > 0) {
status = PerformanceScore.GOOD;
description = VitalState.GOOD;
}
}
return {
value: metric,
formattedValue: formatMetricValue(metric),
score: status,
description,
};
}
export function getWarmAppStartPerformance(metric: MetricValue): VitalStatus {
let description = '';
let status = PerformanceScore.NONE;
if (typeof metric.value === 'number' && metric.unit) {
// @ts-ignore TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
const durationMs = metric.value * DURATION_UNITS[metric.unit];
// TODO should be platform dependant
if (durationMs > 2000) {
status = PerformanceScore.BAD;
description = VitalState.POOR;
} else if (durationMs > 1000) {
status = PerformanceScore.NEEDS_IMPROVEMENT;
description = VitalState.MEH;
} else if (durationMs > 0) {
status = PerformanceScore.GOOD;
description = VitalState.GOOD;
}
}
return {
value: metric,
formattedValue: formatMetricValue(metric),
score: status,
description,
};
}
export function getDefaultMetricPerformance(
metric: MetricValue,
field?: string | undefined
): VitalStatus {
return {
description: undefined,
formattedValue: formatMetricValue(metric, field),
value: metric,
score: PerformanceScore.NONE,
};
}