@oneuptime/common 14.0.2 → 14.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/AlertFeed.ts +2 -0
- package/Models/DatabaseModels/IncidentAlert.ts +540 -0
- package/Models/DatabaseModels/IncidentFeed.ts +2 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/Project.ts +60 -0
- package/Models/DatabaseModels/RumApplication.ts +52 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Services/IncidentAlertService.ts +1811 -0
- package/Server/Services/IncidentService.ts +210 -10
- package/Server/Services/IncidentStateTimelineService.ts +24 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
- package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
- package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
- package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
- package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
- package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
- package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
- package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
- package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
- package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
- package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +38 -18
- package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
- package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
- package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
- package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
- package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
- package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
- package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
- package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
- package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
- package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
- package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
- package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
- package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
- package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
- package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
- package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
- package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
- package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
- package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
- package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
- package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
- package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
- package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
- package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
- package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
- package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
- package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
- package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
- package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
- package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
- package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
- package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
- package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
- package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
- package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
- package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
- package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
- package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
- package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
- package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
- package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
- package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
- package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
- package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
- package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
- package/Tests/Types/Rum/WebVitals.test.ts +173 -0
- package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
- package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
- package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
- package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
- package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
- package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
- package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
- package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
- package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
- package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
- package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
- package/Types/Incident/IncidentAlertLink.ts +38 -0
- package/Types/Permission.ts +48 -0
- package/Types/Rum/SessionReplay.ts +25 -6
- package/Types/Rum/WebVitals.ts +52 -0
- package/UI/Components/Detail/FieldLabel.tsx +8 -0
- package/UI/Components/InfoCard/InfoCard.tsx +47 -1
- package/UI/Components/ModelTable/BaseModelTable.tsx +95 -17
- package/UI/Components/ModelTable/Column.ts +5 -0
- package/UI/Components/Table/TableHeader.tsx +47 -2
- package/UI/Components/Table/Types/Column.ts +7 -0
- package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
- package/UI/Utils/PermissionGate.ts +11 -2
- package/Utils/Incident/IncidentFromAlerts.ts +516 -0
- package/Utils/Rum/SessionTraceState.ts +212 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
- package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +62 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
- package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
- package/build/dist/Server/Services/IncidentService.js +164 -12
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +21 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rum/WebVitals.js +25 -0
- package/build/dist/Types/Rum/WebVitals.js.map +1 -1
- package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
- package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +66 -14
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +18 -2
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
- package/build/dist/UI/Utils/PermissionGate.js +4 -2
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
- package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
- package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
- package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import ObjectID from "../../Types/ObjectID";
|
|
2
|
+
import { MAX_ALERTS_PER_INCIDENT_LINK_ACTION } from "../../Types/Incident/IncidentAlertLink";
|
|
3
|
+
/*
|
|
4
|
+
* The resource lists the incident form supports besides monitors (which come
|
|
5
|
+
* from each alert's single `monitor`). Exported so the create page and the
|
|
6
|
+
* tests walk the same list.
|
|
7
|
+
*/
|
|
8
|
+
export const INCIDENT_PREFILL_RESOURCE_KEYS = ["hosts", "kubernetesClusters", "dockerHosts", "podmanHosts", "services"];
|
|
9
|
+
const INCIDENT_PREFILL_LIST_KEYS = [
|
|
10
|
+
"monitors",
|
|
11
|
+
...INCIDENT_PREFILL_RESOURCE_KEYS,
|
|
12
|
+
];
|
|
13
|
+
export default class IncidentFromAlerts {
|
|
14
|
+
/*
|
|
15
|
+
* Reads the create page's `alertIds` query parameter: comma separated,
|
|
16
|
+
* whitespace tolerant, invalid ids dropped, duplicates removed (first one
|
|
17
|
+
* wins), capped at MAX_ALERTS_PER_INCIDENT_LINK_ACTION.
|
|
18
|
+
*/
|
|
19
|
+
static parseAlertIdsQueryParam(value) {
|
|
20
|
+
if (!value) {
|
|
21
|
+
return { alertIds: [], wasTruncated: false };
|
|
22
|
+
}
|
|
23
|
+
const alertIds = [];
|
|
24
|
+
for (const rawId of value.split(",")) {
|
|
25
|
+
const id = rawId.trim();
|
|
26
|
+
if (!id || !ObjectID.isValidUUID(id) || alertIds.includes(id)) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
alertIds.push(id);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
alertIds: alertIds.slice(0, MAX_ALERTS_PER_INCIDENT_LINK_ACTION),
|
|
33
|
+
wasTruncated: alertIds.length > MAX_ALERTS_PER_INCIDENT_LINK_ACTION,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/*
|
|
37
|
+
* Severities ordered most severe first: ascending `order`, the way the
|
|
38
|
+
* project's severity settings list them. A severity without an order sorts
|
|
39
|
+
* after every ordered one; ties keep their input order.
|
|
40
|
+
*/
|
|
41
|
+
static sortSeveritiesByOrder(severities) {
|
|
42
|
+
return severities
|
|
43
|
+
.map((severity, index) => {
|
|
44
|
+
return { severity, index };
|
|
45
|
+
})
|
|
46
|
+
.sort((a, b) => {
|
|
47
|
+
const aHasOrder = typeof a.severity.order === "number";
|
|
48
|
+
const bHasOrder = typeof b.severity.order === "number";
|
|
49
|
+
if (aHasOrder && bHasOrder) {
|
|
50
|
+
const difference = a.severity.order - b.severity.order;
|
|
51
|
+
if (difference !== 0) {
|
|
52
|
+
return difference;
|
|
53
|
+
}
|
|
54
|
+
return a.index - b.index;
|
|
55
|
+
}
|
|
56
|
+
if (aHasOrder !== bHasOrder) {
|
|
57
|
+
return aHasOrder ? -1 : 1;
|
|
58
|
+
}
|
|
59
|
+
return a.index - b.index;
|
|
60
|
+
})
|
|
61
|
+
.map((entry) => {
|
|
62
|
+
return entry.severity;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/*
|
|
66
|
+
* 0 for the most severe severity, 1 for the next and so on; null when the
|
|
67
|
+
* id is not one of the given severities.
|
|
68
|
+
*/
|
|
69
|
+
static getSeverityRank(severityId, severities) {
|
|
70
|
+
if (!severityId) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const rank = this.sortSeveritiesByOrder(severities).findIndex((severity) => {
|
|
74
|
+
return severity.id === severityId;
|
|
75
|
+
});
|
|
76
|
+
return rank < 0 ? null : rank;
|
|
77
|
+
}
|
|
78
|
+
/*
|
|
79
|
+
* The alert whose severity ranks highest. Alerts without a known severity
|
|
80
|
+
* never win over one with a severity; ties go to the alert listed first.
|
|
81
|
+
* With no known severity anywhere, the first alert.
|
|
82
|
+
*/
|
|
83
|
+
static getMostSevereAlert(alerts, alertSeverities) {
|
|
84
|
+
let mostSevere = null;
|
|
85
|
+
let mostSevereRank = null;
|
|
86
|
+
for (const alert of alerts) {
|
|
87
|
+
const rank = this.getSeverityRank(alert.alertSeverityId, alertSeverities);
|
|
88
|
+
if (!mostSevere) {
|
|
89
|
+
mostSevere = alert;
|
|
90
|
+
mostSevereRank = rank;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (rank === null) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (mostSevereRank === null || rank < mostSevereRank) {
|
|
97
|
+
mostSevere = alert;
|
|
98
|
+
mostSevereRank = rank;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return mostSevere;
|
|
102
|
+
}
|
|
103
|
+
/*
|
|
104
|
+
* The incident severity an alert severity corresponds to. An incident
|
|
105
|
+
* severity with the same name (ignoring case and surrounding spaces) wins;
|
|
106
|
+
* otherwise the alert severity's rank among the alert severities picks the
|
|
107
|
+
* incident severity at the same rank, clamped to the least severe one when
|
|
108
|
+
* the project has fewer incident severities than alert severities.
|
|
109
|
+
*/
|
|
110
|
+
static mapAlertSeverityToIncidentSeverity(data) {
|
|
111
|
+
if (!data.alertSeverityId || data.incidentSeverities.length === 0) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const alertSeverity = data.alertSeverities.find((severity) => {
|
|
115
|
+
return severity.id === data.alertSeverityId;
|
|
116
|
+
});
|
|
117
|
+
if (!alertSeverity) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
const alertSeverityName = (alertSeverity.name || "")
|
|
121
|
+
.trim()
|
|
122
|
+
.toLowerCase();
|
|
123
|
+
if (alertSeverityName) {
|
|
124
|
+
const sameName = data.incidentSeverities.find((severity) => {
|
|
125
|
+
return ((severity.name || "").trim().toLowerCase() === alertSeverityName);
|
|
126
|
+
});
|
|
127
|
+
if (sameName) {
|
|
128
|
+
return sameName.id;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const rank = this.getSeverityRank(alertSeverity.id, data.alertSeverities);
|
|
132
|
+
if (rank === null) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
const sortedIncidentSeverities = this.sortSeveritiesByOrder(data.incidentSeverities);
|
|
136
|
+
const target = sortedIncidentSeverities[Math.min(rank, sortedIncidentSeverities.length - 1)];
|
|
137
|
+
return target ? target.id : null;
|
|
138
|
+
}
|
|
139
|
+
/* "Alert #42" / "Alert ALT-42", or "Alert" when the number is unknown. */
|
|
140
|
+
static getAlertReference(alert) {
|
|
141
|
+
if (alert.alertNumberWithPrefix) {
|
|
142
|
+
return `Alert ${alert.alertNumberWithPrefix}`;
|
|
143
|
+
}
|
|
144
|
+
if (typeof alert.alertNumber === "number") {
|
|
145
|
+
return `Alert #${alert.alertNumber}`;
|
|
146
|
+
}
|
|
147
|
+
return "Alert";
|
|
148
|
+
}
|
|
149
|
+
static buildIncidentPrefill(input) {
|
|
150
|
+
const alerts = input.alerts;
|
|
151
|
+
const prefill = {
|
|
152
|
+
title: "",
|
|
153
|
+
description: "",
|
|
154
|
+
incidentSeverityId: undefined,
|
|
155
|
+
monitors: [],
|
|
156
|
+
hosts: [],
|
|
157
|
+
kubernetesClusters: [],
|
|
158
|
+
dockerHosts: [],
|
|
159
|
+
podmanHosts: [],
|
|
160
|
+
services: [],
|
|
161
|
+
labelIds: [],
|
|
162
|
+
isPrivate: false,
|
|
163
|
+
};
|
|
164
|
+
if (alerts.length === 0) {
|
|
165
|
+
return prefill;
|
|
166
|
+
}
|
|
167
|
+
const mostSevere = this.getMostSevereAlert(alerts, input.alertSeverities);
|
|
168
|
+
if (alerts.length === 1) {
|
|
169
|
+
prefill.title = alerts[0].title || "";
|
|
170
|
+
prefill.description = alerts[0].description || "";
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
prefill.title = (mostSevere === null || mostSevere === void 0 ? void 0 : mostSevere.title) || "";
|
|
174
|
+
prefill.description = alerts
|
|
175
|
+
.map((alert) => {
|
|
176
|
+
return `- ${this.getAlertReference(alert)}: ${alert.title || ""}`.trimEnd();
|
|
177
|
+
})
|
|
178
|
+
.join("\n");
|
|
179
|
+
}
|
|
180
|
+
prefill.incidentSeverityId =
|
|
181
|
+
this.mapAlertSeverityToIncidentSeverity({
|
|
182
|
+
alertSeverityId: mostSevere === null || mostSevere === void 0 ? void 0 : mostSevere.alertSeverityId,
|
|
183
|
+
alertSeverities: input.alertSeverities,
|
|
184
|
+
incidentSeverities: input.incidentSeverities,
|
|
185
|
+
}) || undefined;
|
|
186
|
+
for (const alert of alerts) {
|
|
187
|
+
if (alert.monitor) {
|
|
188
|
+
this.addResource(prefill.monitors, alert.monitor);
|
|
189
|
+
}
|
|
190
|
+
for (const key of INCIDENT_PREFILL_RESOURCE_KEYS) {
|
|
191
|
+
for (const resource of alert[key] || []) {
|
|
192
|
+
this.addResource(prefill[key], resource);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
for (const labelId of alert.labelIds || []) {
|
|
196
|
+
if (labelId && !prefill.labelIds.includes(labelId)) {
|
|
197
|
+
prefill.labelIds.push(labelId);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (alert.isPrivate) {
|
|
201
|
+
prefill.isPrivate = true;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return prefill;
|
|
205
|
+
}
|
|
206
|
+
/*
|
|
207
|
+
* Folds the prefill into the form's initial values without undoing what is
|
|
208
|
+
* already there (an incident template, say): title, description and
|
|
209
|
+
* severity only fill blanks, resource and label lists are unioned, and a
|
|
210
|
+
* private incident stays private. On-call policies are never touched -
|
|
211
|
+
* declaring an incident from alerts must not page anyone the alerts did
|
|
212
|
+
* not already page.
|
|
213
|
+
*/
|
|
214
|
+
static applyPrefillToInitialValues(initialValues, prefill) {
|
|
215
|
+
const merged = Object.assign({}, initialValues);
|
|
216
|
+
if (!this.hasText(merged["title"]) && prefill.title) {
|
|
217
|
+
merged["title"] = prefill.title;
|
|
218
|
+
}
|
|
219
|
+
if (!this.hasText(merged["description"]) && prefill.description) {
|
|
220
|
+
merged["description"] = prefill.description;
|
|
221
|
+
}
|
|
222
|
+
if (!this.hasText(merged["incidentSeverity"]) &&
|
|
223
|
+
prefill.incidentSeverityId) {
|
|
224
|
+
merged["incidentSeverity"] = prefill.incidentSeverityId;
|
|
225
|
+
}
|
|
226
|
+
for (const key of INCIDENT_PREFILL_LIST_KEYS) {
|
|
227
|
+
const resources = [];
|
|
228
|
+
for (const existing of this.asArray(merged[key])) {
|
|
229
|
+
const resource = this.toNamedResource(existing);
|
|
230
|
+
if (resource) {
|
|
231
|
+
this.addResource(resources, resource);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
for (const resource of prefill[key]) {
|
|
235
|
+
this.addResource(resources, resource);
|
|
236
|
+
}
|
|
237
|
+
if (resources.length > 0) {
|
|
238
|
+
merged[key] = resources;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const labelIds = [];
|
|
242
|
+
for (const existing of this.asArray(merged["labels"])) {
|
|
243
|
+
const id = this.toId(existing);
|
|
244
|
+
if (id && !labelIds.includes(id)) {
|
|
245
|
+
labelIds.push(id);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
for (const labelId of prefill.labelIds) {
|
|
249
|
+
if (!labelIds.includes(labelId)) {
|
|
250
|
+
labelIds.push(labelId);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (labelIds.length > 0) {
|
|
254
|
+
merged["labels"] = labelIds;
|
|
255
|
+
}
|
|
256
|
+
if (prefill.isPrivate) {
|
|
257
|
+
merged["isPrivate"] = true;
|
|
258
|
+
}
|
|
259
|
+
return merged;
|
|
260
|
+
}
|
|
261
|
+
static addResource(resources, resource) {
|
|
262
|
+
if (!resource._id) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const alreadyAdded = resources.some((existing) => {
|
|
266
|
+
return existing._id === resource._id;
|
|
267
|
+
});
|
|
268
|
+
if (!alreadyAdded) {
|
|
269
|
+
resources.push({ _id: resource._id, name: resource.name || "" });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
static hasText(value) {
|
|
273
|
+
if (value === null || value === undefined) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
return value.toString().trim().length > 0;
|
|
277
|
+
}
|
|
278
|
+
static asArray(value) {
|
|
279
|
+
return Array.isArray(value) ? value : [];
|
|
280
|
+
}
|
|
281
|
+
static toId(value) {
|
|
282
|
+
var _a;
|
|
283
|
+
if (typeof value === "string") {
|
|
284
|
+
return value || null;
|
|
285
|
+
}
|
|
286
|
+
if (value && typeof value === "object") {
|
|
287
|
+
const id = (_a = value["_id"]) !== null && _a !== void 0 ? _a : value["id"];
|
|
288
|
+
if (id !== null && id !== undefined) {
|
|
289
|
+
const idString = id.toString();
|
|
290
|
+
return idString || null;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
static toNamedResource(value) {
|
|
296
|
+
const id = this.toId(value);
|
|
297
|
+
if (!id) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
const name = value && typeof value === "object"
|
|
301
|
+
? value["name"]
|
|
302
|
+
: undefined;
|
|
303
|
+
return { _id: id, name: typeof name === "string" ? name : "" };
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
//# sourceMappingURL=IncidentFromAlerts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IncidentFromAlerts.js","sourceRoot":"","sources":["../../../../Utils/Incident/IncidentFromAlerts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The replay session id, carried on W3C trace context.
|
|
3
|
+
*
|
|
4
|
+
* The browser recorder adds one `tracestate` list member to the requests a
|
|
5
|
+
* page makes to its own origin:
|
|
6
|
+
*
|
|
7
|
+
* tracestate: oneuptime=sid:<32 hex session id>[;p:<16 hex parent id>]
|
|
8
|
+
*
|
|
9
|
+
* tracestate is the one channel a stock OpenTelemetry backend carries
|
|
10
|
+
* without being told to. Every SDK's W3C propagator extracts it onto the
|
|
11
|
+
* remote parent, every child span inherits it, every OTLP exporter sends
|
|
12
|
+
* it as the span's `traceState`, and every outgoing call re-injects it. So
|
|
13
|
+
* span ingest can stamp Span.sessionId for every service a browser request
|
|
14
|
+
* touched, with no code in the customer's backend. (OTLP log records carry
|
|
15
|
+
* no trace state; logs are joined to a session by trace id instead.)
|
|
16
|
+
*
|
|
17
|
+
* `p` is present only when the recorder MINTED the traceparent. Its parent
|
|
18
|
+
* id then names a browser span that is never exported, so the backend's
|
|
19
|
+
* entry span would otherwise arrive pointing at a parent that does not
|
|
20
|
+
* exist: never a root span, flagged as missing its parent. Ingest treats a
|
|
21
|
+
* span whose parent is exactly `p` as the root it really is.
|
|
22
|
+
*
|
|
23
|
+
* Both halves live here so the recorder that writes the member and the
|
|
24
|
+
* ingest that reads it cannot drift. Standalone functions rather than
|
|
25
|
+
* class statics, because the recorder bundle tree-shakes unused exports
|
|
26
|
+
* but not unused statics - the recorder imports only the builder.
|
|
27
|
+
*
|
|
28
|
+
* Dependency-free: bundled into the browser recorder as well as imported
|
|
29
|
+
* by the server.
|
|
30
|
+
*/
|
|
31
|
+
/* The list-member key. A valid W3C tracestate simple key. */
|
|
32
|
+
export const SESSION_TRACE_STATE_KEY = "oneuptime";
|
|
33
|
+
/*
|
|
34
|
+
* Hostile-input bounds for the parser. W3C caps a well-formed header at 32
|
|
35
|
+
* members, and the OpenTelemetry JS SDK at 512 characters, but other SDKs
|
|
36
|
+
* only cap member count and member length, so a legitimate value carrying
|
|
37
|
+
* other vendors' members can be longer than 512. Past these a value is not
|
|
38
|
+
* one the recorder wrote, so no session is read out of it - but our
|
|
39
|
+
* members are still stripped from it.
|
|
40
|
+
*/
|
|
41
|
+
const MAX_TRACE_STATE_LENGTH = 8192;
|
|
42
|
+
const MAX_TRACE_STATE_MEMBERS = 64;
|
|
43
|
+
const SESSION_ID_PATTERN = /^[0-9a-f]{32}$/;
|
|
44
|
+
const PARENT_SPAN_ID_PATTERN = /^[0-9a-f]{16}$/;
|
|
45
|
+
const ALL_ZERO_PATTERN = /^0+$/;
|
|
46
|
+
/*
|
|
47
|
+
* The tracestate list member for a session. Callers pass recorder-minted
|
|
48
|
+
* values (a 32-hex session id, a 16-hex parent id); nothing here needs
|
|
49
|
+
* escaping, because hex and the ':' / ';' separators are all legal in a
|
|
50
|
+
* tracestate value.
|
|
51
|
+
*/
|
|
52
|
+
export function buildSessionTraceStateMember(sessionId, syntheticParentSpanId) {
|
|
53
|
+
return (SESSION_TRACE_STATE_KEY +
|
|
54
|
+
"=sid:" +
|
|
55
|
+
sessionId +
|
|
56
|
+
(syntheticParentSpanId ? ";p:" + syntheticParentSpanId : ""));
|
|
57
|
+
}
|
|
58
|
+
/*
|
|
59
|
+
* Read the session member out of a span's trace state.
|
|
60
|
+
*
|
|
61
|
+
* Accepts anything, because the value comes from an OTLP body a customer
|
|
62
|
+
* (or anyone holding an ingestion key) controls: a non-string, an
|
|
63
|
+
* oversized string or a malformed member yields no session and never
|
|
64
|
+
* throws. The first `oneuptime` member wins, as in the W3C rule that a
|
|
65
|
+
* vendor's own member is the left-most one; fields inside it are
|
|
66
|
+
* `name:value` pairs separated by ';', in any order, and unknown fields are
|
|
67
|
+
* ignored so the format can grow.
|
|
68
|
+
*/
|
|
69
|
+
export function parseSessionTraceState(traceState) {
|
|
70
|
+
if (typeof traceState !== "string") {
|
|
71
|
+
return { sessionTraceState: null, remainingTraceState: "" };
|
|
72
|
+
}
|
|
73
|
+
/*
|
|
74
|
+
* Fast path, and the path almost every span takes: no member of ours,
|
|
75
|
+
* nothing to parse and nothing to strip.
|
|
76
|
+
*/
|
|
77
|
+
if (traceState.indexOf(SESSION_TRACE_STATE_KEY) === -1) {
|
|
78
|
+
return { sessionTraceState: null, remainingTraceState: traceState };
|
|
79
|
+
}
|
|
80
|
+
const members = traceState.split(",");
|
|
81
|
+
/*
|
|
82
|
+
* Past the bounds nothing is READ as a session - a value this far out of
|
|
83
|
+
* spec is not one the recorder wrote - but our members are still
|
|
84
|
+
* stripped, so an id cannot survive in the raw trace state just because
|
|
85
|
+
* the value around it was oversized.
|
|
86
|
+
*/
|
|
87
|
+
const isWithinBounds = traceState.length <= MAX_TRACE_STATE_LENGTH &&
|
|
88
|
+
members.length <= MAX_TRACE_STATE_MEMBERS;
|
|
89
|
+
let sessionTraceState = null;
|
|
90
|
+
let sawSessionMember = false;
|
|
91
|
+
const remaining = [];
|
|
92
|
+
for (const rawMember of members) {
|
|
93
|
+
const member = rawMember.trim();
|
|
94
|
+
if (member === "") {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const equalsIndex = member.indexOf("=");
|
|
98
|
+
const key = equalsIndex === -1 ? member : member.slice(0, equalsIndex).trim();
|
|
99
|
+
if (key !== SESSION_TRACE_STATE_KEY) {
|
|
100
|
+
remaining.push(member);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
/*
|
|
104
|
+
* Every member under our key is stripped, parsed or not: a malformed
|
|
105
|
+
* one can still hold an id, and the point of stripping is that no id
|
|
106
|
+
* survives outside the sessionId column.
|
|
107
|
+
*/
|
|
108
|
+
if (isWithinBounds && !sawSessionMember && equalsIndex !== -1) {
|
|
109
|
+
sessionTraceState = readSessionMemberValue(member.slice(equalsIndex + 1));
|
|
110
|
+
}
|
|
111
|
+
sawSessionMember = true;
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
sessionTraceState: sessionTraceState,
|
|
115
|
+
remainingTraceState: remaining.join(","),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function readSessionMemberValue(value) {
|
|
119
|
+
let sessionId = null;
|
|
120
|
+
let syntheticParentSpanId = null;
|
|
121
|
+
for (const rawField of value.split(";")) {
|
|
122
|
+
const field = rawField.trim();
|
|
123
|
+
const colonIndex = field.indexOf(":");
|
|
124
|
+
if (colonIndex === -1) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const name = field.slice(0, colonIndex);
|
|
128
|
+
const fieldValue = field.slice(colonIndex + 1).toLowerCase();
|
|
129
|
+
if (name === "sid" && sessionId === null) {
|
|
130
|
+
if (!SESSION_ID_PATTERN.test(fieldValue)) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
sessionId = fieldValue;
|
|
134
|
+
}
|
|
135
|
+
else if (name === "p" && syntheticParentSpanId === null) {
|
|
136
|
+
/*
|
|
137
|
+
* A malformed parent id costs only the root-span repair, never the
|
|
138
|
+
* session: the session id is what the member is for.
|
|
139
|
+
*/
|
|
140
|
+
if (PARENT_SPAN_ID_PATTERN.test(fieldValue) &&
|
|
141
|
+
!ALL_ZERO_PATTERN.test(fieldValue)) {
|
|
142
|
+
syntheticParentSpanId = fieldValue;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (sessionId === null || ALL_ZERO_PATTERN.test(sessionId)) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
sessionId: sessionId,
|
|
151
|
+
syntheticParentSpanId: syntheticParentSpanId,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=SessionTraceState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionTraceState.js","sourceRoot":"","sources":["../../../../Utils/Rum/SessionTraceState.ts"],"names":[],"mappings":"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"}
|