@oneuptime/common 11.5.10 → 11.5.12
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/AnalyticsModels/NetworkFlow.ts +12 -1
- package/Server/API/StatusPageAPI.ts +14 -1
- package/Server/Services/IncidentService.ts +62 -67
- package/Server/Services/MonitorGroupService.ts +15 -2
- package/Server/Services/MonitorService.ts +91 -3
- package/Server/Services/MonitorStatusTimelineService.ts +285 -100
- package/Server/Services/StatusPageService.ts +59 -34
- package/Server/Utils/Monitor/MonitorResource.ts +43 -14
- package/Server/Utils/Monitor/MonitorStatusTimeline.ts +32 -7
- package/Server/Utils/Monitor/MonitorStatusTimelineReconciler.ts +362 -0
- package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +235 -0
- package/Tests/Server/Utils/Monitor/MonitorStatusTimelineReconciler.test.ts +555 -0
- package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +216 -0
- package/Tests/Types/Database/GreaterThan.test.ts +5 -1
- package/Tests/Types/Database/GreaterThanOrEqual.test.ts +5 -1
- package/Tests/Types/Database/GreaterThanOrNull.test.ts +24 -1
- package/Tests/Types/Database/LessThan.test.ts +5 -1
- package/Tests/Types/Database/LessThanOrEqual.test.ts +24 -1
- package/Tests/Types/Database/LessThanOrNull.test.ts +5 -1
- package/Tests/Utils/Uptime/UptimeUtil.test.ts +726 -0
- package/Types/BaseDatabase/GreaterThan.ts +8 -1
- package/Types/BaseDatabase/GreaterThanOrEqual.ts +8 -1
- package/Types/BaseDatabase/GreaterThanOrNull.ts +9 -1
- package/Types/BaseDatabase/LessThan.ts +8 -1
- package/Types/BaseDatabase/LessThanOrEqual.ts +9 -1
- package/Types/BaseDatabase/LessThanOrNull.ts +8 -1
- package/Utils/StatusPage/ResourceUptime.ts +11 -1
- package/Utils/Uptime/UptimeUtil.ts +142 -36
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js +12 -1
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +12 -2
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +47 -56
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/MonitorGroupService.js +15 -2
- package/build/dist/Server/Services/MonitorGroupService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +66 -3
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +244 -102
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +57 -33
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +34 -12
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +25 -8
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimelineReconciler.js +268 -0
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimelineReconciler.js.map +1 -0
- package/build/dist/Types/BaseDatabase/GreaterThan.js +8 -1
- package/build/dist/Types/BaseDatabase/GreaterThan.js.map +1 -1
- package/build/dist/Types/BaseDatabase/GreaterThanOrEqual.js +8 -1
- package/build/dist/Types/BaseDatabase/GreaterThanOrEqual.js.map +1 -1
- package/build/dist/Types/BaseDatabase/GreaterThanOrNull.js +9 -1
- package/build/dist/Types/BaseDatabase/GreaterThanOrNull.js.map +1 -1
- package/build/dist/Types/BaseDatabase/LessThan.js +8 -1
- package/build/dist/Types/BaseDatabase/LessThan.js.map +1 -1
- package/build/dist/Types/BaseDatabase/LessThanOrEqual.js +9 -1
- package/build/dist/Types/BaseDatabase/LessThanOrEqual.js.map +1 -1
- package/build/dist/Types/BaseDatabase/LessThanOrNull.js +8 -1
- package/build/dist/Types/BaseDatabase/LessThanOrNull.js.map +1 -1
- package/build/dist/Utils/StatusPage/ResourceUptime.js +4 -1
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/Uptime/UptimeUtil.js +86 -33
- package/build/dist/Utils/Uptime/UptimeUtil.js.map +1 -1
- package/package.json +3 -2
|
@@ -11,7 +11,14 @@ export default class GreaterThan<T extends CompareType> extends CompareBase<T> {
|
|
|
11
11
|
public override toJSON(): JSONObject {
|
|
12
12
|
return {
|
|
13
13
|
_type: ObjectType.GreaterThan,
|
|
14
|
-
|
|
14
|
+
/*
|
|
15
|
+
* The RAW value is serialized (like InBetween), not toString():
|
|
16
|
+
* toString() collapses a Date to a local-timezone date-only string
|
|
17
|
+
* (asDateForDatabaseQuery), shifting Date bounds sent from the browser
|
|
18
|
+
* by up to a day. JSON.stringify emits a raw Date as its full ISO
|
|
19
|
+
* timestamp, which the server binds at full precision.
|
|
20
|
+
*/
|
|
21
|
+
value: (this as GreaterThan<T>).value,
|
|
15
22
|
};
|
|
16
23
|
}
|
|
17
24
|
|
|
@@ -13,7 +13,14 @@ export default class GreaterThanOrEqual<
|
|
|
13
13
|
public override toJSON(): JSONObject {
|
|
14
14
|
return {
|
|
15
15
|
_type: ObjectType.GreaterThanOrEqual,
|
|
16
|
-
|
|
16
|
+
/*
|
|
17
|
+
* The RAW value is serialized (like InBetween), not toString():
|
|
18
|
+
* toString() collapses a Date to a local-timezone date-only string
|
|
19
|
+
* (asDateForDatabaseQuery), shifting Date bounds sent from the browser
|
|
20
|
+
* by up to a day. JSON.stringify emits a raw Date as its full ISO
|
|
21
|
+
* timestamp, which the server binds at full precision.
|
|
22
|
+
*/
|
|
23
|
+
value: (this as GreaterThanOrEqual<T>).value,
|
|
17
24
|
};
|
|
18
25
|
}
|
|
19
26
|
|
|
@@ -10,10 +10,18 @@ export default class GreaterThanOrNull<
|
|
|
10
10
|
super(value);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/*
|
|
14
|
+
* Serializes the RAW value (like InBetween does), not toString(): toString()
|
|
15
|
+
* collapses a Date to a date-only string in the LOCAL timezone
|
|
16
|
+
* (asDateForDatabaseQuery), so a Date bound would arrive at the server as
|
|
17
|
+
* midnight of the browser's calendar date and shift the query bound by up to
|
|
18
|
+
* a day. JSON.stringify turns a raw Date into its full ISO timestamp, which
|
|
19
|
+
* the server binds at full precision.
|
|
20
|
+
*/
|
|
13
21
|
public override toJSON(): JSONObject {
|
|
14
22
|
return {
|
|
15
23
|
_type: ObjectType.GreaterThanOrNull,
|
|
16
|
-
value: (this as GreaterThanOrNull<T>).
|
|
24
|
+
value: (this as GreaterThanOrNull<T>).value,
|
|
17
25
|
};
|
|
18
26
|
}
|
|
19
27
|
|
|
@@ -11,7 +11,14 @@ export default class LessThan<T extends CompareType> extends CompareBase<T> {
|
|
|
11
11
|
public override toJSON(): JSONObject {
|
|
12
12
|
return {
|
|
13
13
|
_type: ObjectType.LessThan,
|
|
14
|
-
|
|
14
|
+
/*
|
|
15
|
+
* The RAW value is serialized (like InBetween), not toString():
|
|
16
|
+
* toString() collapses a Date to a local-timezone date-only string
|
|
17
|
+
* (asDateForDatabaseQuery), shifting Date bounds sent from the browser
|
|
18
|
+
* by up to a day. JSON.stringify emits a raw Date as its full ISO
|
|
19
|
+
* timestamp, which the server binds at full precision.
|
|
20
|
+
*/
|
|
21
|
+
value: (this as LessThan<T>).value,
|
|
15
22
|
};
|
|
16
23
|
}
|
|
17
24
|
|
|
@@ -10,10 +10,18 @@ export default class LessThanOrEqual<
|
|
|
10
10
|
super(value);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/*
|
|
14
|
+
* Serializes the RAW value (like InBetween does), not toString(): toString()
|
|
15
|
+
* collapses a Date to a date-only string in the LOCAL timezone
|
|
16
|
+
* (asDateForDatabaseQuery), so a bound of "now" would arrive at the server as
|
|
17
|
+
* midnight of the browser's calendar date and silently exclude every row from
|
|
18
|
+
* today. JSON.stringify turns a raw Date into its full ISO timestamp, which
|
|
19
|
+
* the server binds at full precision.
|
|
20
|
+
*/
|
|
13
21
|
public override toJSON(): JSONObject {
|
|
14
22
|
return {
|
|
15
23
|
_type: ObjectType.LessThanOrEqual,
|
|
16
|
-
value: (this as LessThanOrEqual<T>).
|
|
24
|
+
value: (this as LessThanOrEqual<T>).value,
|
|
17
25
|
};
|
|
18
26
|
}
|
|
19
27
|
|
|
@@ -13,7 +13,14 @@ export default class LessThanOrNull<
|
|
|
13
13
|
public override toJSON(): JSONObject {
|
|
14
14
|
return {
|
|
15
15
|
_type: ObjectType.LessThanOrNull,
|
|
16
|
-
|
|
16
|
+
/*
|
|
17
|
+
* The RAW value is serialized (like InBetween), not toString():
|
|
18
|
+
* toString() collapses a Date to a local-timezone date-only string
|
|
19
|
+
* (asDateForDatabaseQuery), shifting Date bounds sent from the browser
|
|
20
|
+
* by up to a day. JSON.stringify emits a raw Date as its full ISO
|
|
21
|
+
* timestamp, which the server binds at full precision.
|
|
22
|
+
*/
|
|
23
|
+
value: (this as LessThanOrNull<T>).value,
|
|
17
24
|
};
|
|
18
25
|
}
|
|
19
26
|
|
|
@@ -6,7 +6,7 @@ import StatusPageResource from "../../Models/DatabaseModels/StatusPageResource";
|
|
|
6
6
|
import Dictionary from "../../Types/Dictionary";
|
|
7
7
|
import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
|
|
8
8
|
import StatusPageGroup from "../../Models/DatabaseModels/StatusPageGroup";
|
|
9
|
-
import UptimeUtil from "../Uptime/UptimeUtil";
|
|
9
|
+
import UptimeUtil, { UptimeWindow } from "../Uptime/UptimeUtil";
|
|
10
10
|
|
|
11
11
|
export default class StatusPageResourceUptimeUtil {
|
|
12
12
|
public static getWorstMonitorStatus(data: {
|
|
@@ -137,6 +137,8 @@ export default class StatusPageResourceUptimeUtil {
|
|
|
137
137
|
precision: UptimePrecision;
|
|
138
138
|
downtimeMonitorStatuses: Array<MonitorStatus>;
|
|
139
139
|
monitorsInGroup: Dictionary<Array<ObjectID>>;
|
|
140
|
+
// if supplied, uptime is measured over this window instead of "first event -> now".
|
|
141
|
+
uptimeWindow?: UptimeWindow | undefined;
|
|
140
142
|
}): number | null {
|
|
141
143
|
if (!data.statusPageResource.showUptimePercent) {
|
|
142
144
|
return null;
|
|
@@ -156,6 +158,7 @@ export default class StatusPageResourceUptimeUtil {
|
|
|
156
158
|
monitorStatusTimelines,
|
|
157
159
|
data.precision,
|
|
158
160
|
downtimeMonitorStatuses,
|
|
161
|
+
data.uptimeWindow,
|
|
159
162
|
);
|
|
160
163
|
|
|
161
164
|
return uptimePercent;
|
|
@@ -168,6 +171,8 @@ export default class StatusPageResourceUptimeUtil {
|
|
|
168
171
|
downtimeMonitorStatuses: Array<MonitorStatus>;
|
|
169
172
|
statusPageResources: Array<StatusPageResource>;
|
|
170
173
|
monitorsInGroup: Dictionary<Array<ObjectID>>;
|
|
174
|
+
// if supplied, uptime is measured over this window instead of "first event -> now".
|
|
175
|
+
uptimeWindow?: UptimeWindow | undefined;
|
|
171
176
|
}): number | null {
|
|
172
177
|
if (!data.statusPageGroup.showUptimePercent) {
|
|
173
178
|
return null;
|
|
@@ -193,6 +198,7 @@ export default class StatusPageResourceUptimeUtil {
|
|
|
193
198
|
precision: data.precision,
|
|
194
199
|
downtimeMonitorStatuses: data.downtimeMonitorStatuses,
|
|
195
200
|
monitorsInGroup: data.monitorsInGroup,
|
|
201
|
+
uptimeWindow: data.uptimeWindow,
|
|
196
202
|
});
|
|
197
203
|
|
|
198
204
|
if (calculateUptimePercentOfResource !== null) {
|
|
@@ -252,6 +258,8 @@ export default class StatusPageResourceUptimeUtil {
|
|
|
252
258
|
statusPageResources: Array<StatusPageResource>;
|
|
253
259
|
resourceGroups: Array<StatusPageGroup>;
|
|
254
260
|
monitorsInGroup: Dictionary<Array<ObjectID>>;
|
|
261
|
+
// if supplied, uptime is measured over this window instead of "first event -> now".
|
|
262
|
+
uptimeWindow?: UptimeWindow | undefined;
|
|
255
263
|
}): number | null {
|
|
256
264
|
const showUptimePercentage: boolean = Boolean(
|
|
257
265
|
data.statusPageResources.find((item: StatusPageResource) => {
|
|
@@ -276,6 +284,7 @@ export default class StatusPageResourceUptimeUtil {
|
|
|
276
284
|
downtimeMonitorStatuses: data.downtimeMonitorStatuses,
|
|
277
285
|
statusPageResources: data.statusPageResources,
|
|
278
286
|
monitorsInGroup: data.monitorsInGroup,
|
|
287
|
+
uptimeWindow: data.uptimeWindow,
|
|
279
288
|
});
|
|
280
289
|
|
|
281
290
|
if (calculateAvgUptimePercentOfStatusPageGroup !== null) {
|
|
@@ -298,6 +307,7 @@ export default class StatusPageResourceUptimeUtil {
|
|
|
298
307
|
precision: data.precision,
|
|
299
308
|
downtimeMonitorStatuses: data.downtimeMonitorStatuses,
|
|
300
309
|
monitorsInGroup: data.monitorsInGroup,
|
|
310
|
+
uptimeWindow: data.uptimeWindow,
|
|
301
311
|
});
|
|
302
312
|
|
|
303
313
|
if (calculateUptimePercentOfResource !== null) {
|
|
@@ -7,15 +7,30 @@ import MonitorStatus from "../../Models/DatabaseModels/MonitorStatus";
|
|
|
7
7
|
import MonitorStatusTimeline from "../../Models/DatabaseModels/MonitorStatusTimeline";
|
|
8
8
|
import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* The time period an uptime calculation is reported over. When this is supplied, events are
|
|
12
|
+
* clipped to it and the denominator of the uptime percentage is the window itself - clipped to
|
|
13
|
+
* now, and starting no earlier than the first recorded event (so a monitor younger than the
|
|
14
|
+
* window is measured from its first event, not diluted by time it did not exist). Without it,
|
|
15
|
+
* events run to the start of the next event (or now) and the denominator is "first event -> now",
|
|
16
|
+
* which lets an open (endsAt = null) row from months ago leak into an unrelated report.
|
|
17
|
+
*/
|
|
18
|
+
export interface UptimeWindow {
|
|
19
|
+
startDate: Date;
|
|
20
|
+
endDate: Date;
|
|
21
|
+
}
|
|
22
|
+
|
|
10
23
|
export default class UptimeUtil {
|
|
11
24
|
/**
|
|
12
25
|
* This function, `getMonitorEventsForId`, takes a `monitorId` as an argument and returns an array of `MonitorEvent` objects.
|
|
13
26
|
* @param {ObjectID} monitorId - The ID of the monitor for which events are to be fetched.
|
|
27
|
+
* @param {UptimeWindow | undefined} window - If supplied, events are clipped to this window and events outside it are dropped.
|
|
14
28
|
* @returns {Array<MonitorEvent>} - An array of `MonitorEvent` objects.
|
|
15
29
|
*/
|
|
16
30
|
public static getMonitorEventsForId(
|
|
17
31
|
monitorId: ObjectID,
|
|
18
32
|
statusTimelineItems: Array<MonitorStatusTimeline>,
|
|
33
|
+
window?: UptimeWindow | undefined,
|
|
19
34
|
): Array<MonitorEvent> {
|
|
20
35
|
// Initialize an empty array to store the monitor events.
|
|
21
36
|
|
|
@@ -65,15 +80,54 @@ export default class UptimeUtil {
|
|
|
65
80
|
// check if there's next event, if there is, set the end date to the start date of the next event.
|
|
66
81
|
if (i < monitorEvents.length - 1) {
|
|
67
82
|
endDate = monitorEvents[i + 1]!.startsAt;
|
|
68
|
-
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// if this is the last event, or the next event has no start date, then this event is still open and runs until now.
|
|
86
|
+
if (!endDate) {
|
|
69
87
|
endDate = OneUptimeDate.getCurrentDate();
|
|
70
88
|
}
|
|
71
89
|
}
|
|
72
90
|
|
|
91
|
+
let eventStartDate: Date = startDate;
|
|
92
|
+
let eventEndDate: Date = endDate;
|
|
93
|
+
|
|
94
|
+
if (window) {
|
|
95
|
+
/*
|
|
96
|
+
* Clip the event to the reporting window. Without this an open (endsAt = null) row that
|
|
97
|
+
* started months before the window contributes its entire life to the report.
|
|
98
|
+
*
|
|
99
|
+
* The end is also capped at "now", to match the denominator in
|
|
100
|
+
* getTotalDowntimeInSeconds, which measures the window only up to the
|
|
101
|
+
* current time (min(window.endDate, now)). If the numerator were allowed
|
|
102
|
+
* to run to a future window.endDate while the denominator stopped at now,
|
|
103
|
+
* a closed row ending in the future could make downtime exceed the elapsed
|
|
104
|
+
* period and drive the raw percentage negative.
|
|
105
|
+
*/
|
|
106
|
+
eventStartDate = OneUptimeDate.getGreaterDate(
|
|
107
|
+
eventStartDate,
|
|
108
|
+
window.startDate,
|
|
109
|
+
);
|
|
110
|
+
eventEndDate = OneUptimeDate.getLesserDate(
|
|
111
|
+
eventEndDate,
|
|
112
|
+
OneUptimeDate.getLesserDate(
|
|
113
|
+
window.endDate,
|
|
114
|
+
OneUptimeDate.getCurrentDate(),
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// if the event does not overlap the window at all, then drop it.
|
|
119
|
+
if (
|
|
120
|
+
OneUptimeDate.getSecondsBetweenDates(eventStartDate, eventEndDate) <=
|
|
121
|
+
0
|
|
122
|
+
) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
73
127
|
// Push a new MonitorEvent object to the eventList array with properties from the current item and calculated dates.
|
|
74
128
|
eventList.push({
|
|
75
|
-
startDate:
|
|
76
|
-
endDate:
|
|
129
|
+
startDate: eventStartDate,
|
|
130
|
+
endDate: eventEndDate,
|
|
77
131
|
label: monitorEvents[i]?.monitorStatus?.name || "Operational",
|
|
78
132
|
priority: monitorEvents[i]?.monitorStatus?.priority || 0,
|
|
79
133
|
color: monitorEvents[i]?.monitorStatus?.color || Green,
|
|
@@ -88,8 +142,12 @@ export default class UptimeUtil {
|
|
|
88
142
|
|
|
89
143
|
public static getNonOverlappingMonitorEvents(
|
|
90
144
|
items: Array<MonitorStatusTimeline>,
|
|
145
|
+
window?: UptimeWindow | undefined,
|
|
91
146
|
): Array<Event> {
|
|
92
|
-
const monitorEventList: Array<MonitorEvent> = this.getMonitorEvents(
|
|
147
|
+
const monitorEventList: Array<MonitorEvent> = this.getMonitorEvents(
|
|
148
|
+
items,
|
|
149
|
+
window,
|
|
150
|
+
);
|
|
93
151
|
|
|
94
152
|
const eventList: Array<Event> = [];
|
|
95
153
|
|
|
@@ -98,20 +156,6 @@ export default class UptimeUtil {
|
|
|
98
156
|
|
|
99
157
|
const monitorEvent: MonitorEvent = monitorEventList[i]!;
|
|
100
158
|
|
|
101
|
-
if (!monitorEvent.endDate) {
|
|
102
|
-
// if this is the last event then set endDate to current date.
|
|
103
|
-
|
|
104
|
-
// otherwise set it to start date of next event.
|
|
105
|
-
|
|
106
|
-
if (i === monitorEventList.length - 1) {
|
|
107
|
-
monitorEvent.endDate = OneUptimeDate.getCurrentDate();
|
|
108
|
-
} else {
|
|
109
|
-
monitorEvent.endDate =
|
|
110
|
-
monitorEventList[i + 1]!.startDate ||
|
|
111
|
-
OneUptimeDate.getCurrentDate();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
159
|
if (
|
|
116
160
|
eventList.length === 0 ||
|
|
117
161
|
OneUptimeDate.isAfter(
|
|
@@ -188,6 +232,7 @@ export default class UptimeUtil {
|
|
|
188
232
|
|
|
189
233
|
public static getMonitorEvents(
|
|
190
234
|
items: Array<MonitorStatusTimeline>,
|
|
235
|
+
window?: UptimeWindow | undefined,
|
|
191
236
|
): Array<MonitorEvent> {
|
|
192
237
|
// get all distinct monitor ids.
|
|
193
238
|
const monitorIds: Array<ObjectID> = [];
|
|
@@ -219,6 +264,7 @@ export default class UptimeUtil {
|
|
|
219
264
|
const monitorEvents: Array<MonitorEvent> = this.getMonitorEventsForId(
|
|
220
265
|
monitorId,
|
|
221
266
|
items,
|
|
267
|
+
window,
|
|
222
268
|
);
|
|
223
269
|
eventList.push(...monitorEvents);
|
|
224
270
|
}
|
|
@@ -242,12 +288,14 @@ export default class UptimeUtil {
|
|
|
242
288
|
public static getTotalDowntimeInSeconds(
|
|
243
289
|
monitorStatusTimelines: Array<MonitorStatusTimeline>,
|
|
244
290
|
downtimeMonitorStatuses: Array<MonitorStatus>,
|
|
291
|
+
window?: UptimeWindow | undefined,
|
|
245
292
|
): {
|
|
246
293
|
totalDowntimeInSeconds: number;
|
|
247
294
|
totalSecondsInTimePeriod: number;
|
|
248
295
|
} {
|
|
249
296
|
const monitorEvents: Array<Event> = this.getNonOverlappingMonitorEvents(
|
|
250
297
|
monitorStatusTimelines,
|
|
298
|
+
window,
|
|
251
299
|
);
|
|
252
300
|
|
|
253
301
|
// sort these by start date,
|
|
@@ -263,33 +311,83 @@ export default class UptimeUtil {
|
|
|
263
311
|
return 0;
|
|
264
312
|
});
|
|
265
313
|
|
|
314
|
+
/*
|
|
315
|
+
* If a window is supplied then the time period is the window itself, and not "first event -> now".
|
|
316
|
+
* Two clamps apply to the window:
|
|
317
|
+
*
|
|
318
|
+
* - The window end is clipped to now, so a window that reaches into the future does not
|
|
319
|
+
* inflate the denominator (which is what made the reported percentage drift upwards
|
|
320
|
+
* every day).
|
|
321
|
+
*
|
|
322
|
+
* - The window start is clamped forward to the first event's start, so time from before
|
|
323
|
+
* the monitor's first recorded event does not count as uptime. Events are already
|
|
324
|
+
* clipped to the window, so this only moves the start when the monitor has NO data for
|
|
325
|
+
* the head of the window - i.e. it is younger than the window. Without this a monitor
|
|
326
|
+
* created a day ago and Offline ever since would report ~98.9% uptime over a 90 day
|
|
327
|
+
* window; with it, it reports 0% - the same answer the windowless
|
|
328
|
+
* "first event -> now" denominator always gave.
|
|
329
|
+
*
|
|
330
|
+
* When there are no events at all there is nothing to clamp to and the denominator is the
|
|
331
|
+
* full (now-clipped) window.
|
|
332
|
+
*/
|
|
333
|
+
let windowSecondsInTimePeriod: number | null = null;
|
|
334
|
+
|
|
335
|
+
if (window) {
|
|
336
|
+
const windowEndDate: Date = OneUptimeDate.getLesserDate(
|
|
337
|
+
window.endDate,
|
|
338
|
+
OneUptimeDate.getCurrentDate(),
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
const windowStartDate: Date =
|
|
342
|
+
monitorEvents.length > 0
|
|
343
|
+
? OneUptimeDate.getGreaterDate(
|
|
344
|
+
window.startDate,
|
|
345
|
+
monitorEvents[0]!.startDate,
|
|
346
|
+
)
|
|
347
|
+
: window.startDate;
|
|
348
|
+
|
|
349
|
+
windowSecondsInTimePeriod = OneUptimeDate.getSecondsBetweenDates(
|
|
350
|
+
windowStartDate,
|
|
351
|
+
windowEndDate,
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
// never let the denominator be zero or negative.
|
|
355
|
+
if (!windowSecondsInTimePeriod || windowSecondsInTimePeriod < 0) {
|
|
356
|
+
windowSecondsInTimePeriod = 1;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
266
360
|
// calculate number of seconds between start of first event to date time now.
|
|
267
361
|
let totalSecondsInTimePeriod: number = 0;
|
|
268
362
|
|
|
269
363
|
if (monitorEvents.length === 0) {
|
|
270
364
|
return {
|
|
271
365
|
totalDowntimeInSeconds: 0,
|
|
272
|
-
totalSecondsInTimePeriod: 1,
|
|
366
|
+
totalSecondsInTimePeriod: windowSecondsInTimePeriod ?? 1,
|
|
273
367
|
};
|
|
274
368
|
}
|
|
275
369
|
|
|
276
|
-
if (
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
370
|
+
if (windowSecondsInTimePeriod !== null) {
|
|
371
|
+
totalSecondsInTimePeriod = windowSecondsInTimePeriod;
|
|
372
|
+
} else {
|
|
373
|
+
if (
|
|
374
|
+
OneUptimeDate.isAfter(
|
|
375
|
+
monitorEvents[0]!.startDate,
|
|
376
|
+
OneUptimeDate.getCurrentDate(),
|
|
377
|
+
)
|
|
378
|
+
) {
|
|
379
|
+
return {
|
|
380
|
+
totalDowntimeInSeconds: 0,
|
|
381
|
+
totalSecondsInTimePeriod: 1,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
287
384
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
385
|
+
totalSecondsInTimePeriod =
|
|
386
|
+
OneUptimeDate.getSecondsBetweenDates(
|
|
387
|
+
monitorEvents[0]!.startDate,
|
|
388
|
+
OneUptimeDate.getCurrentDate(),
|
|
389
|
+
) || 1;
|
|
390
|
+
}
|
|
293
391
|
|
|
294
392
|
// get order of operational state.
|
|
295
393
|
|
|
@@ -347,6 +445,7 @@ export default class UptimeUtil {
|
|
|
347
445
|
monitorStatusTimelines: Array<MonitorStatusTimeline>,
|
|
348
446
|
precision: UptimePrecision,
|
|
349
447
|
downtimeMonitorStatuses: Array<MonitorStatus>,
|
|
448
|
+
window?: UptimeWindow | undefined,
|
|
350
449
|
): number {
|
|
351
450
|
// calculate percentage.
|
|
352
451
|
|
|
@@ -354,6 +453,7 @@ export default class UptimeUtil {
|
|
|
354
453
|
this.getTotalDowntimeInSeconds(
|
|
355
454
|
monitorStatusTimelines,
|
|
356
455
|
downtimeMonitorStatuses,
|
|
456
|
+
window,
|
|
357
457
|
);
|
|
358
458
|
|
|
359
459
|
if (totalSecondsInTimePeriod === 0) {
|
|
@@ -369,8 +469,14 @@ export default class UptimeUtil {
|
|
|
369
469
|
totalSecondsInTimePeriod) *
|
|
370
470
|
100;
|
|
371
471
|
|
|
472
|
+
/*
|
|
473
|
+
* clamp before rounding. roundToPrecision floors, so an out of range value would otherwise
|
|
474
|
+
* escape as is (for example -13.5 stays -13.5 and never becomes 0).
|
|
475
|
+
*/
|
|
476
|
+
const clampedPercentage: number = Math.min(100, Math.max(0, percentage));
|
|
477
|
+
|
|
372
478
|
return this.roundToPrecision({
|
|
373
|
-
number:
|
|
479
|
+
number: clampedPercentage,
|
|
374
480
|
precision,
|
|
375
481
|
});
|
|
376
482
|
}
|
|
@@ -264,8 +264,19 @@ export default class NetworkFlow extends AnalyticsBaseModel {
|
|
|
264
264
|
* (a retentionDate column computed at ingest, like Log/Metric) is
|
|
265
265
|
* the phase-2 follow-up. Keyed on server-assigned ingestedAt so a
|
|
266
266
|
* device with a wrong clock cannot make rows expire early.
|
|
267
|
+
*
|
|
268
|
+
* toDateTime() is NOT redundant: ingestedAt is DateTime64(9), so
|
|
269
|
+
* `ingestedAt + INTERVAL 30 DAY` stays DateTime64(9), and a TTL
|
|
270
|
+
* expression must evaluate to Date or DateTime. ClickHouse only began
|
|
271
|
+
* accepting DateTime64 there in 25.x; on 24.x it fails the CREATE with
|
|
272
|
+
* BAD_TTL_EXPRESSION, which aborts the whole boot schema-sync (it has
|
|
273
|
+
* no per-table error handling) and takes every table registered after
|
|
274
|
+
* this one down with it. The Helm chart ships `tag: latest` but tells
|
|
275
|
+
* operators to pin for production, so older servers are supported and
|
|
276
|
+
* this must stay version-portable. Narrowing to second precision is
|
|
277
|
+
* lossless for a 30-day retention window.
|
|
267
278
|
*/
|
|
268
|
-
ttlExpression: "ingestedAt + INTERVAL 30 DAY DELETE",
|
|
279
|
+
ttlExpression: "toDateTime(ingestedAt) + INTERVAL 30 DAY DELETE",
|
|
269
280
|
defaultSortColumn: "flowStartAt",
|
|
270
281
|
});
|
|
271
282
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkFlow.js","sourceRoot":"","sources":["../../../../Models/AnalyticsModels/NetworkFlow.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,MAAM,uBAAuB,CAAC;AAC1C,OAAO,oBAAoB,MAAM,oDAAoD,CAAC;AACtF,OAAO,kBAAkB,MAAM,kDAAkD,CAAC;AAClF,OAAO,oBAAoB,MAAM,2CAA2C,CAAC;AAC7E,OAAO,eAAe,MAAM,+CAA+C,CAAC;AAE5E,OAAO,UAAU,MAAM,wBAAwB,CAAC;AAEhD;;;;;;;;GAQG;AAEH,MAAM,eAAe,GAAsB;IACzC,UAAU,CAAC,YAAY;IACvB,UAAU,CAAC,YAAY;IACvB,UAAU,CAAC,aAAa;IACxB,UAAU,CAAC,MAAM;IACjB,UAAU,CAAC,aAAa;IACxB,UAAU,CAAC,cAAc;IACzB,UAAU,CAAC,cAAc;IACzB,UAAU,CAAC,iBAAiB;CAC7B,CAAC;AAEF,MAAM,iBAAiB,GAAsB;IAC3C,UAAU,CAAC,YAAY;IACvB,UAAU,CAAC,YAAY;IACvB,UAAU,CAAC,aAAa;IACxB,UAAU,CAAC,aAAa;IACxB,UAAU,CAAC,cAAc;IACzB,UAAU,CAAC,mBAAmB;CAC/B,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,kBAAkB;IACzD;QACE,MAAM,eAAe,GAAyB,IAAI,oBAAoB,CAAC;YACrE,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,YAAY;YACnB,WAAW,EAAE,eAAe;YAC5B,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,QAAQ;YAC9B,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,MAAM,qBAAqB,GACzB,IAAI,oBAAoB,CAAC;YACvB,GAAG,EAAE,iBAAiB;YACtB,KAAK,EAAE,mBAAmB;YAC1B,WAAW,EACT,6FAA6F;YAC/F,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,QAAQ;YAC9B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEL,MAAM,gBAAgB,GAAyB,IAAI,oBAAoB,CAAC;YACtE,GAAG,EAAE,YAAY;YACjB,gBAAgB,EAAE,IAAI;YACtB,KAAK,EAAE,aAAa;YACpB,WAAW,EACT,qFAAqF;YACvF,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,IAAI;YAC1B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,WAAW,GAAyB,IAAI,oBAAoB,CAAC;YACjE,GAAG,EAAE,OAAO;YACZ,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE;YAClC,KAAK,EAAE,WAAW;YAClB,WAAW,EAAE,yCAAyC;YACtD,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,IAAI;YAC1B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,WAAW,GAAyB,IAAI,oBAAoB,CAAC;YACjE,GAAG,EAAE,OAAO;YACZ,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE;YAClC,KAAK,EAAE,gBAAgB;YACvB,WAAW,EAAE,8CAA8C;YAC3D,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,IAAI;YAC1B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,aAAa,GAAyB,IAAI,oBAAoB,CAAC;YACnE,GAAG,EAAE,SAAS;YACd,KAAK,EAAE,aAAa;YACpB,WAAW,EAAE,6CAA6C;YAC1D,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,MAAM;YAC5B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,aAAa,GAAyB,IAAI,oBAAoB,CAAC;YACnE,GAAG,EAAE,SAAS;YACd,KAAK,EAAE,kBAAkB;YACzB,WAAW,EAAE,kDAAkD;YAC/D,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,MAAM;YAC5B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,cAAc,GAAyB,IAAI,oBAAoB,CAAC;YACpE,GAAG,EAAE,UAAU;YACf,KAAK,EAAE,UAAU;YACjB,WAAW,EAAE,uDAAuD;YACpE,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,MAAM;YAC5B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,YAAY,GAAyB,IAAI,oBAAoB,CAAC;YAClE,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,QAAQ;YACf,WAAW,EAAE,yBAAyB;YACtC,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,MAAM;YAC5B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,aAAa,GAAyB,IAAI,oBAAoB,CAAC;YACnE,GAAG,EAAE,SAAS;YACd,KAAK,EAAE,SAAS;YAChB,WAAW,EAAE,2BAA2B;YACxC,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,MAAM;YAC5B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,iBAAiB,GAAyB,IAAI,oBAAoB,CAAC;YACvE,GAAG,EAAE,aAAa;YAClB,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAC9D,KAAK,EAAE,YAAY;YACnB,WAAW,EAAE,kCAAkC;YAC/C,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,UAAU;YAChC,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,eAAe,GAAyB,IAAI,oBAAoB,CAAC;YACrE,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAC9D,KAAK,EAAE,UAAU;YACjB,WAAW,EAAE,gCAAgC;YAC7C,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,UAAU;YAChC,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,MAAM,gBAAgB,GAAyB,IAAI,oBAAoB,CAAC;YACtE,GAAG,EAAE,YAAY;YACjB,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAC9D,KAAK,EAAE,aAAa;YACpB,WAAW,EAAE,2CAA2C;YACxD,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,eAAe,CAAC,UAAU;YAChC,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,EAAE;aACX;SACF,CAAC,CAAC;QAEH,KAAK,CAAC;YACJ,SAAS,EAAE,kBAAkB,CAAC,WAAW;YACzC,WAAW,EAAE,oBAAoB,CAAC,SAAS;YAC3C,YAAY,EAAE,cAAc;YAC5B,aAAa,EAAE;gBACb,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE;oBACN,UAAU,CAAC,YAAY;oBACvB,UAAU,CAAC,YAAY;oBACvB,UAAU,CAAC,aAAa;oBACxB,UAAU,CAAC,aAAa;oBACxB,UAAU,CAAC,cAAc;oBACzB,UAAU,CAAC,iBAAiB;iBAC7B;gBACD,MAAM,EAAE;oBACN,UAAU,CAAC,YAAY;oBACvB,UAAU,CAAC,YAAY;oBACvB,UAAU,CAAC,aAAa;oBACxB,UAAU,CAAC,aAAa;oBACxB,UAAU,CAAC,cAAc;oBACzB,UAAU,CAAC,mBAAmB;iBAC/B;aACF;YACD,UAAU,EAAE,eAAe;YAC3B,WAAW,EAAE,IAAI,KAAK,CAAC,eAAe,CAAC;YACvC,YAAY,EAAE;gBACZ,eAAe;gBACf,qBAAqB;gBACrB,gBAAgB;gBAChB,WAAW;gBACX,WAAW;gBACX,aAAa;gBACb,aAAa;gBACb,cAAc;gBACd,YAAY;gBACZ,aAAa;gBACb,iBAAiB;gBACjB,eAAe;gBACf,gBAAgB;aACjB;YACD,WAAW,EAAE,EAAE;YACf,QAAQ,EAAE,CAAC,WAAW,EAAE,iBAAiB,EAAE,aAAa,CAAC;YACzD,WAAW,EAAE,CAAC,WAAW,EAAE,iBAAiB,EAAE,aAAa,CAAC;YAC5D,YAAY,EAAE,yBAAyB;YACvC;;;;;eAKG;YACH,WAAW,EAAE,qDAAqD;YAClE,aAAa,EAAE,6CAA6C;YAC5D
|
|
1
|
+
{"version":3,"file":"NetworkFlow.js","sourceRoot":"","sources":["../../../../Models/AnalyticsModels/NetworkFlow.ts"],"names":[],"mappings":"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"}
|
|
@@ -879,6 +879,16 @@ export default class StatusPageAPI extends BaseAPI {
|
|
|
879
879
|
endDateForMonitorTimeline: endDate,
|
|
880
880
|
});
|
|
881
881
|
const downtimeMonitorStatuses = statusPage.downtimeMonitorStatuses || [];
|
|
882
|
+
/*
|
|
883
|
+
* this endpoint reports uptime over an explicit [startDate, endDate] range, so events
|
|
884
|
+
* have to be clipped to it and the denominator has to be the range itself. Without
|
|
885
|
+
* this an open (endsAt = null) row that started before the range contributes its
|
|
886
|
+
* entire duration to the downtime total.
|
|
887
|
+
*/
|
|
888
|
+
const uptimeWindow = {
|
|
889
|
+
startDate: startDate,
|
|
890
|
+
endDate: endDate,
|
|
891
|
+
};
|
|
882
892
|
const getUptimeByStatusPageGroup = (data) => {
|
|
883
893
|
var _a, _b, _c, _d, _e;
|
|
884
894
|
const groupUptime = {
|
|
@@ -936,7 +946,7 @@ export default class StatusPageAPI extends BaseAPI {
|
|
|
936
946
|
monitorsInGroup: monitorsInGroup,
|
|
937
947
|
});
|
|
938
948
|
if (resource.showUptimePercent) {
|
|
939
|
-
const uptimePercent = UptimeUtil.calculateUptimePercentage(resourceStatusTimelines, precision, downtimeMonitorStatuses);
|
|
949
|
+
const uptimePercent = UptimeUtil.calculateUptimePercentage(resourceStatusTimelines, precision, downtimeMonitorStatuses, uptimeWindow);
|
|
940
950
|
resourceUptime.uptimePercent = uptimePercent;
|
|
941
951
|
}
|
|
942
952
|
groupUptime.statusPageResourceUptimes.push(resourceUptime);
|
|
@@ -966,7 +976,7 @@ export default class StatusPageAPI extends BaseAPI {
|
|
|
966
976
|
monitorStatusTimelines: monitorStatusTimelines,
|
|
967
977
|
monitorsInGroup: monitorsInGroup,
|
|
968
978
|
});
|
|
969
|
-
const uptimePercent = UptimeUtil.calculateUptimePercentage(resourceStatusTimelines, precision, downtimeMonitorStatuses);
|
|
979
|
+
const uptimePercent = UptimeUtil.calculateUptimePercentage(resourceStatusTimelines, precision, downtimeMonitorStatuses, uptimeWindow);
|
|
970
980
|
resourceUptime.uptimePercent = uptimePercent;
|
|
971
981
|
}
|
|
972
982
|
groupUptime.statusPageResourceUptimes.push(resourceUptime);
|