@oneuptime/common 11.3.23 → 11.3.25

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.
@@ -497,6 +497,56 @@ export class Service extends DatabaseService<Model> {
497
497
  }
498
498
  }
499
499
  }
500
+
501
+ @CaptureSpan()
502
+ public async getExpectedHostIdentifiers(data: {
503
+ projectId: ObjectID;
504
+ seenWithinMinutes: number;
505
+ }): Promise<Array<string>> {
506
+ /*
507
+ * "Expected" hosts for per-host down-detection: non-archived hosts in
508
+ * the project that reported within the recency window. Their canonical
509
+ * hostIdentifier equals the metric's `resource.host.name` value (both
510
+ * canonicalized at ingest), so the telemetry monitor can diff this set
511
+ * against the hosts present in the current evaluation window and
512
+ * synthesize a "no data" series for any that have gone silent — a
513
+ * group-by-host query returns no row for a silent host, so absence is
514
+ * otherwise invisible. See HostAbsenceSeries and
515
+ * MonitorTelemetryMonitor.injectExpectedAbsentHostSeries.
516
+ */
517
+ const cutoff: Date = OneUptimeDate.addRemoveMinutes(
518
+ OneUptimeDate.getCurrentDate(),
519
+ -Math.abs(data.seenWithinMinutes),
520
+ );
521
+
522
+ const hosts: Array<Model> = await this.findBy({
523
+ query: {
524
+ projectId: data.projectId,
525
+ lastSeenAt: QueryHelper.greaterThanEqualTo(cutoff),
526
+ },
527
+ select: {
528
+ hostIdentifier: true,
529
+ isArchived: true,
530
+ },
531
+ limit: LIMIT_MAX,
532
+ skip: 0,
533
+ props: {
534
+ isRoot: true,
535
+ },
536
+ });
537
+
538
+ const identifiers: Array<string> = [];
539
+ for (const host of hosts) {
540
+ // isArchived is nullable; treat null/undefined as not archived.
541
+ if (host.isArchived) {
542
+ continue;
543
+ }
544
+ if (host.hostIdentifier) {
545
+ identifiers.push(canonicalizeEntityValue(host.hostIdentifier));
546
+ }
547
+ }
548
+ return identifiers;
549
+ }
500
550
  }
501
551
 
502
552
  function fingerprintLabelIds(labelIds: Array<ObjectID>): string {
@@ -0,0 +1,170 @@
1
+ import AggregatedResult from "../../../Types/BaseDatabase/AggregatedResult";
2
+ import { JSONObject } from "../../../Types/JSON";
3
+ import MetricQueryConfigData from "../../../Types/Metrics/MetricQueryConfigData";
4
+ import {
5
+ CheckOn,
6
+ CriteriaFilter,
7
+ NoDataPolicy,
8
+ } from "../../../Types/Monitor/CriteriaFilter";
9
+ import MetricSeriesResult from "../../../Types/Monitor/MetricMonitor/MetricSeriesResult";
10
+ import MonitorCriteriaInstance from "../../../Types/Monitor/MonitorCriteriaInstance";
11
+ import MonitorStep from "../../../Types/Monitor/MonitorStep";
12
+ import MetricSeriesFingerprint from "../../../Utils/Metrics/MetricSeriesFingerprint";
13
+ import { canonicalizeEntityValue } from "../../../Utils/Telemetry/EntityKey";
14
+
15
+ /*
16
+ * Pure helpers backing per-host "went silent" detection.
17
+ *
18
+ * A group-by-host metric query only returns a series for hosts that
19
+ * emitted rows in the evaluation window — a host that stopped reporting
20
+ * simply has no row, so its absence is invisible to the criteria
21
+ * evaluator and its NoDataPolicy.Trigger check never runs. These helpers
22
+ * let the telemetry monitor reconstruct the "expected" host set (from the
23
+ * Host registry) and synthesize an empty "no data" series for every
24
+ * expected host missing from the current window, so the existing
25
+ * per-series NoDataPolicy path fires one correctly-labeled alert per down
26
+ * host. Kept pure (no DB) so the gating and series-construction logic is
27
+ * unit-testable; the worker supplies the expected-host list.
28
+ */
29
+
30
+ /**
31
+ * OTel resource attribute keys that identify a host. Metrics store
32
+ * `host.name` under the resource-prefixed key; the bare form is accepted
33
+ * defensively.
34
+ */
35
+ export const HOST_NAME_ATTRIBUTE_KEYS: Array<string> = [
36
+ "resource.host.name",
37
+ "host.name",
38
+ ];
39
+
40
+ /**
41
+ * A host that reported within this window is treated as a live member of
42
+ * the fleet and therefore "expected" to still be reporting; if it is now
43
+ * silent, that is a real outage worth alerting on. A host silent for
44
+ * longer than this ages out of down-detection so a decommissioned-but-not-
45
+ * archived host does not alert forever. Deliberately generous (a day) so a
46
+ * genuine multi-hour outage keeps alerting rather than silently resolving —
47
+ * missing a real outage is worse than a nuisance alert on a dead host.
48
+ */
49
+ export const HOST_ABSENCE_EXPECTED_WINDOW_MINUTES: number = 24 * 60;
50
+
51
+ /**
52
+ * If the monitor is grouped by exactly one host-name attribute, return
53
+ * that group-by key; otherwise null. Absent-host synthesis only makes
54
+ * sense for a pure per-host group-by — a multi-dimensional group-by
55
+ * (host + device, etc.) can't be enumerated from the host registry, and a
56
+ * non-host group-by isn't about hosts at all.
57
+ */
58
+ export function getHostAbsenceGroupByKey(
59
+ groupByAttributeKeys: Array<string>,
60
+ ): string | null {
61
+ if (!groupByAttributeKeys || groupByAttributeKeys.length !== 1) {
62
+ return null;
63
+ }
64
+ const key: string = groupByAttributeKeys[0]!;
65
+ return HOST_NAME_ATTRIBUTE_KEYS.includes(key) ? key : null;
66
+ }
67
+
68
+ /**
69
+ * True if any metric-value criteria filter on the step opts into no-data
70
+ * detection (NoDataPolicy Trigger or TreatAsZero). When no criterion cares
71
+ * about missing data, seeding absent-host series would be pointless — they
72
+ * would evaluate to "ignore" — so the caller skips the extra work.
73
+ */
74
+ export function monitorStepOptsIntoNoDataDetection(
75
+ monitorStep: MonitorStep,
76
+ ): boolean {
77
+ const instances: Array<MonitorCriteriaInstance> =
78
+ monitorStep.data?.monitorCriteria?.data?.monitorCriteriaInstanceArray || [];
79
+
80
+ for (const instance of instances) {
81
+ const filters: Array<CriteriaFilter> = instance.data?.filters || [];
82
+ for (const filter of filters) {
83
+ if (filter.checkOn !== CheckOn.MetricValue) {
84
+ continue;
85
+ }
86
+ const policy: NoDataPolicy | undefined =
87
+ filter.metricMonitorOptions?.onNoDataPolicy;
88
+ if (
89
+ policy === NoDataPolicy.Trigger ||
90
+ policy === NoDataPolicy.TreatAsZero
91
+ ) {
92
+ return true;
93
+ }
94
+ }
95
+ }
96
+ return false;
97
+ }
98
+
99
+ /**
100
+ * True if any query carries attribute equality filters. Such a filter
101
+ * scopes the query to a subset of hosts, so the project-wide expected-host
102
+ * set would over-report absences for out-of-scope hosts; the caller skips
103
+ * absent-host synthesis in that case.
104
+ */
105
+ export function queriesScopeHostSubset(
106
+ queryConfigs: Array<MetricQueryConfigData>,
107
+ ): boolean {
108
+ for (const queryConfig of queryConfigs || []) {
109
+ const attributes: JSONObject | undefined = queryConfig.metricQueryData
110
+ ?.filterData?.attributes as JSONObject | undefined;
111
+ if (attributes && Object.keys(attributes).length > 0) {
112
+ return true;
113
+ }
114
+ }
115
+ return false;
116
+ }
117
+
118
+ /**
119
+ * Build synthetic "no data" series for every expected host absent from the
120
+ * current window's series breakdown. Each synthetic series has empty
121
+ * aggregated-result slots (one per query + formula, matching how present
122
+ * series are shaped) so the criteria evaluator's NoDataPolicy path fires
123
+ * for it, and labels/fingerprint identical to what the host's present
124
+ * series would carry so the resulting alert dedupes and auto-resolves when
125
+ * the host returns. Host identity is compared case-insensitively
126
+ * (canonicalized), matching how ingest stores host.name.
127
+ */
128
+ export function buildAbsentHostSeries(input: {
129
+ presentSeries: Array<MetricSeriesResult>;
130
+ expectedHostIdentifiers: Array<string>;
131
+ hostKey: string;
132
+ slotCount: number;
133
+ }): Array<MetricSeriesResult> {
134
+ const presentHosts: Set<string> = new Set<string>();
135
+ for (const series of input.presentSeries) {
136
+ const raw: unknown = series.labels?.[input.hostKey];
137
+ if (raw === undefined || raw === null || String(raw) === "") {
138
+ continue;
139
+ }
140
+ presentHosts.add(canonicalizeEntityValue(String(raw)));
141
+ }
142
+
143
+ const slotCount: number = Math.max(input.slotCount, 1);
144
+ const seen: Set<string> = new Set<string>();
145
+ const absentSeries: Array<MetricSeriesResult> = [];
146
+
147
+ for (const identifierRaw of input.expectedHostIdentifiers) {
148
+ const identifier: string = canonicalizeEntityValue(String(identifierRaw));
149
+ if (!identifier || presentHosts.has(identifier) || seen.has(identifier)) {
150
+ continue;
151
+ }
152
+ seen.add(identifier);
153
+
154
+ const labels: JSONObject = { [input.hostKey]: identifier };
155
+ const aggregatedResults: Array<AggregatedResult> = Array.from(
156
+ { length: slotCount },
157
+ (): AggregatedResult => {
158
+ return { data: [] };
159
+ },
160
+ );
161
+
162
+ absentSeries.push({
163
+ fingerprint: MetricSeriesFingerprint.computeFingerprint(labels),
164
+ labels,
165
+ aggregatedResults,
166
+ });
167
+ }
168
+
169
+ return absentSeries;
170
+ }
@@ -0,0 +1,260 @@
1
+ import {
2
+ buildAbsentHostSeries,
3
+ getHostAbsenceGroupByKey,
4
+ monitorStepOptsIntoNoDataDetection,
5
+ queriesScopeHostSubset,
6
+ } from "../../../../Server/Utils/Monitor/HostAbsenceSeries";
7
+ import {
8
+ CheckOn,
9
+ CriteriaFilter,
10
+ FilterType,
11
+ NoDataPolicy,
12
+ } from "../../../../Types/Monitor/CriteriaFilter";
13
+ import MetricQueryConfigData from "../../../../Types/Metrics/MetricQueryConfigData";
14
+ import MetricQueryData from "../../../../Types/Metrics/MetricQueryData";
15
+ import MetricSeriesResult from "../../../../Types/Monitor/MetricMonitor/MetricSeriesResult";
16
+ import MonitorStep from "../../../../Types/Monitor/MonitorStep";
17
+ import MetricSeriesFingerprint from "../../../../Utils/Metrics/MetricSeriesFingerprint";
18
+
19
+ const HOST_KEY: string = "resource.host.name";
20
+
21
+ function presentSeries(
22
+ hostKey: string,
23
+ hostNames: Array<string>,
24
+ ): Array<MetricSeriesResult> {
25
+ return hostNames.map((name: string) => {
26
+ return {
27
+ fingerprint: MetricSeriesFingerprint.computeFingerprint({
28
+ [hostKey]: name,
29
+ }),
30
+ labels: { [hostKey]: name },
31
+ // present series carry samples; buildAbsentHostSeries only reads labels.
32
+ aggregatedResults: [],
33
+ };
34
+ });
35
+ }
36
+
37
+ function metricFilter(
38
+ policy: NoDataPolicy | undefined,
39
+ checkOn: CheckOn = CheckOn.MetricValue,
40
+ ): CriteriaFilter {
41
+ const filter: CriteriaFilter = {
42
+ checkOn,
43
+ filterType: FilterType.EqualTo,
44
+ value: "0",
45
+ };
46
+ if (policy) {
47
+ filter.metricMonitorOptions = {
48
+ metricAlias: "h0",
49
+ onNoDataPolicy: policy,
50
+ };
51
+ }
52
+ return filter;
53
+ }
54
+
55
+ function stepWithFilters(filters: Array<CriteriaFilter>): MonitorStep {
56
+ const step: MonitorStep = new MonitorStep();
57
+ step.data = {
58
+ id: "step-1",
59
+ monitorCriteria: {
60
+ data: {
61
+ monitorCriteriaInstanceArray: [{ data: { filters } }],
62
+ },
63
+ },
64
+ } as unknown as MonitorStep["data"];
65
+ return step;
66
+ }
67
+
68
+ function queryWithAttributes(
69
+ attributes: Record<string, string> | undefined,
70
+ ): MetricQueryConfigData {
71
+ return {
72
+ metricQueryData: {
73
+ filterData: {
74
+ metricName: "oneuptime.host.heartbeat",
75
+ ...(attributes ? { attributes } : {}),
76
+ },
77
+ } as unknown as MetricQueryData,
78
+ } as MetricQueryConfigData;
79
+ }
80
+
81
+ describe("HostAbsenceSeries.getHostAbsenceGroupByKey", () => {
82
+ test("returns the host key for a single resource.host.name group-by", () => {
83
+ expect(getHostAbsenceGroupByKey(["resource.host.name"])).toBe(
84
+ "resource.host.name",
85
+ );
86
+ });
87
+
88
+ test("accepts the bare host.name key", () => {
89
+ expect(getHostAbsenceGroupByKey(["host.name"])).toBe("host.name");
90
+ });
91
+
92
+ test("returns null for a multi-dimensional group-by", () => {
93
+ expect(
94
+ getHostAbsenceGroupByKey(["resource.host.name", "device"]),
95
+ ).toBeNull();
96
+ });
97
+
98
+ test("returns null for an empty group-by", () => {
99
+ expect(getHostAbsenceGroupByKey([])).toBeNull();
100
+ });
101
+
102
+ test("returns null for a non-host group-by", () => {
103
+ expect(getHostAbsenceGroupByKey(["resource.k8s.pod.name"])).toBeNull();
104
+ });
105
+ });
106
+
107
+ describe("HostAbsenceSeries.monitorStepOptsIntoNoDataDetection", () => {
108
+ test("true when a metric-value filter uses NoDataPolicy.Trigger", () => {
109
+ const step: MonitorStep = stepWithFilters([
110
+ metricFilter(NoDataPolicy.Trigger),
111
+ ]);
112
+ expect(monitorStepOptsIntoNoDataDetection(step)).toBe(true);
113
+ });
114
+
115
+ test("true when a metric-value filter uses NoDataPolicy.TreatAsZero", () => {
116
+ const step: MonitorStep = stepWithFilters([
117
+ metricFilter(NoDataPolicy.TreatAsZero),
118
+ ]);
119
+ expect(monitorStepOptsIntoNoDataDetection(step)).toBe(true);
120
+ });
121
+
122
+ test("false for NoDataPolicy.Ignore", () => {
123
+ const step: MonitorStep = stepWithFilters([
124
+ metricFilter(NoDataPolicy.Ignore),
125
+ ]);
126
+ expect(monitorStepOptsIntoNoDataDetection(step)).toBe(false);
127
+ });
128
+
129
+ test("false when no no-data policy is configured", () => {
130
+ const step: MonitorStep = stepWithFilters([metricFilter(undefined)]);
131
+ expect(monitorStepOptsIntoNoDataDetection(step)).toBe(false);
132
+ });
133
+
134
+ test("false when the Trigger filter is not a metric-value check", () => {
135
+ const step: MonitorStep = stepWithFilters([
136
+ metricFilter(NoDataPolicy.Trigger, CheckOn.ResponseTime),
137
+ ]);
138
+ expect(monitorStepOptsIntoNoDataDetection(step)).toBe(false);
139
+ });
140
+
141
+ test("false for a step with no criteria", () => {
142
+ const step: MonitorStep = new MonitorStep();
143
+ expect(monitorStepOptsIntoNoDataDetection(step)).toBe(false);
144
+ });
145
+ });
146
+
147
+ describe("HostAbsenceSeries.queriesScopeHostSubset", () => {
148
+ test("false when queries have no attribute filters", () => {
149
+ expect(queriesScopeHostSubset([queryWithAttributes(undefined)])).toBe(
150
+ false,
151
+ );
152
+ });
153
+
154
+ test("false when attributes is an empty object", () => {
155
+ expect(queriesScopeHostSubset([queryWithAttributes({})])).toBe(false);
156
+ });
157
+
158
+ test("true when any query scopes by an attribute", () => {
159
+ expect(
160
+ queriesScopeHostSubset([
161
+ queryWithAttributes(undefined),
162
+ queryWithAttributes({ "resource.deployment.environment": "prod" }),
163
+ ]),
164
+ ).toBe(true);
165
+ });
166
+ });
167
+
168
+ describe("HostAbsenceSeries.buildAbsentHostSeries", () => {
169
+ test("chsdc08 down while peers report → one correctly-labeled no-data series", () => {
170
+ const present: Array<MetricSeriesResult> = presentSeries(HOST_KEY, [
171
+ "pmtrs2app01",
172
+ "pmtrs2rds03",
173
+ ]);
174
+
175
+ const absent: Array<MetricSeriesResult> = buildAbsentHostSeries({
176
+ presentSeries: present,
177
+ expectedHostIdentifiers: ["pmtrs2app01", "pmtrs2rds03", "chsdc08"],
178
+ hostKey: HOST_KEY,
179
+ slotCount: 1,
180
+ });
181
+
182
+ expect(absent).toHaveLength(1);
183
+ expect(absent[0]!.labels).toEqual({ [HOST_KEY]: "chsdc08" });
184
+ expect(absent[0]!.aggregatedResults).toHaveLength(1);
185
+ expect(absent[0]!.aggregatedResults[0]!.data).toEqual([]);
186
+ });
187
+
188
+ test("absent-series fingerprint matches the host's present-series fingerprint (dedupe/resolution align)", () => {
189
+ const absent: Array<MetricSeriesResult> = buildAbsentHostSeries({
190
+ presentSeries: [],
191
+ expectedHostIdentifiers: ["chsdc08"],
192
+ hostKey: HOST_KEY,
193
+ slotCount: 1,
194
+ });
195
+
196
+ const presentFingerprint: string =
197
+ MetricSeriesFingerprint.computeFingerprint({ [HOST_KEY]: "chsdc08" });
198
+
199
+ expect(absent[0]!.fingerprint).toBe(presentFingerprint);
200
+ });
201
+
202
+ test("host identity is matched case-insensitively (no false down alert)", () => {
203
+ const absent: Array<MetricSeriesResult> = buildAbsentHostSeries({
204
+ presentSeries: presentSeries(HOST_KEY, ["CHSDC08"]),
205
+ expectedHostIdentifiers: ["chsdc08"],
206
+ hostKey: HOST_KEY,
207
+ slotCount: 1,
208
+ });
209
+
210
+ expect(absent).toHaveLength(0);
211
+ });
212
+
213
+ test("duplicate expected identifiers yield a single series", () => {
214
+ const absent: Array<MetricSeriesResult> = buildAbsentHostSeries({
215
+ presentSeries: [],
216
+ expectedHostIdentifiers: ["chsdc08", "chsdc08", "CHSDC08"],
217
+ hostKey: HOST_KEY,
218
+ slotCount: 1,
219
+ });
220
+
221
+ expect(absent).toHaveLength(1);
222
+ });
223
+
224
+ test("one empty slot per query + formula", () => {
225
+ const absent: Array<MetricSeriesResult> = buildAbsentHostSeries({
226
+ presentSeries: [],
227
+ expectedHostIdentifiers: ["chsdc08"],
228
+ hostKey: HOST_KEY,
229
+ slotCount: 3,
230
+ });
231
+
232
+ expect(absent[0]!.aggregatedResults).toHaveLength(3);
233
+ for (const slot of absent[0]!.aggregatedResults) {
234
+ expect(slot.data).toEqual([]);
235
+ }
236
+ });
237
+
238
+ test("no absent series when every expected host is present", () => {
239
+ const absent: Array<MetricSeriesResult> = buildAbsentHostSeries({
240
+ presentSeries: presentSeries(HOST_KEY, ["a", "b"]),
241
+ expectedHostIdentifiers: ["a", "b"],
242
+ hostKey: HOST_KEY,
243
+ slotCount: 1,
244
+ });
245
+
246
+ expect(absent).toHaveLength(0);
247
+ });
248
+
249
+ test("blank expected identifiers are ignored", () => {
250
+ const absent: Array<MetricSeriesResult> = buildAbsentHostSeries({
251
+ presentSeries: [],
252
+ expectedHostIdentifiers: ["", " ", "chsdc08"],
253
+ hostKey: HOST_KEY,
254
+ slotCount: 1,
255
+ });
256
+
257
+ expect(absent).toHaveLength(1);
258
+ expect(absent[0]!.labels).toEqual({ [HOST_KEY]: "chsdc08" });
259
+ });
260
+ });
@@ -0,0 +1,249 @@
1
+ import Monitor from "../../../../Models/DatabaseModels/Monitor";
2
+ import AggregatedModel from "../../../../Types/BaseDatabase/AggregatedModel";
3
+ import AggregatedResult from "../../../../Types/BaseDatabase/AggregatedResult";
4
+ import FilterCondition from "../../../../Types/Filter/FilterCondition";
5
+ import MetricQueryConfigData from "../../../../Types/Metrics/MetricQueryConfigData";
6
+ import MetricQueryData from "../../../../Types/Metrics/MetricQueryData";
7
+ import MetricsViewConfig from "../../../../Types/Metrics/MetricsViewConfig";
8
+ import {
9
+ CheckOn,
10
+ CriteriaFilter,
11
+ EvaluateOverTimeType,
12
+ FilterType,
13
+ NoDataPolicy,
14
+ } from "../../../../Types/Monitor/CriteriaFilter";
15
+ import MetricMonitorResponse from "../../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
16
+ import MetricSeriesResult from "../../../../Types/Monitor/MetricMonitor/MetricSeriesResult";
17
+ import MonitorCriteriaInstance from "../../../../Types/Monitor/MonitorCriteriaInstance";
18
+ import MonitorStep from "../../../../Types/Monitor/MonitorStep";
19
+ import MonitorType from "../../../../Types/Monitor/MonitorType";
20
+ import ObjectID from "../../../../Types/ObjectID";
21
+ import RollingTime from "../../../../Types/RollingTime/RollingTime";
22
+ import MetricMonitorCriteria, {
23
+ MetricSeriesEvaluationResult,
24
+ } from "../../../../Server/Utils/Monitor/Criteria/MetricMonitorCriteria";
25
+ import { buildAbsentHostSeries } from "../../../../Server/Utils/Monitor/HostAbsenceSeries";
26
+ import MonitorCriteriaEvaluator from "../../../../Server/Utils/Monitor/MonitorCriteriaEvaluator";
27
+ import MetricSeriesFingerprint from "../../../../Utils/Metrics/MetricSeriesFingerprint";
28
+
29
+ /*
30
+ * End-to-end validation of the host-absence fix using the exact shape of
31
+ * Aptean's "Host Availability" monitor: a group-by-host (resource.host.name)
32
+ * metric monitor on oneuptime.host.heartbeat with a `== 0` filter and
33
+ * onNoDataPolicy = Trigger. It proves that a synthetic absent-host series
34
+ * produced by buildAbsentHostSeries flows through the real criteria
35
+ * evaluator and yields exactly one correctly-labeled per-host trigger,
36
+ * while a present (reporting) host does not fire.
37
+ */
38
+
39
+ const HOST_KEY: string = "resource.host.name";
40
+ const HEARTBEAT_METRIC: string = "oneuptime.host.heartbeat";
41
+ const PRESENT_HOST: string = "pmtrs2app01";
42
+ const SILENT_HOST: string = "chsdc08";
43
+
44
+ function buildFixture(): {
45
+ monitorStep: MonitorStep;
46
+ criteriaFilter: CriteriaFilter;
47
+ dataToProcess: MetricMonitorResponse;
48
+ } {
49
+ const queryConfig: MetricQueryConfigData = {
50
+ metricAliasData: {
51
+ metricVariable: "h0",
52
+ title: HEARTBEAT_METRIC,
53
+ description: undefined,
54
+ legend: HEARTBEAT_METRIC,
55
+ legendUnit: undefined,
56
+ },
57
+ metricQueryData: {
58
+ filterData: {
59
+ metricName: HEARTBEAT_METRIC,
60
+ },
61
+ groupByAttributeKeys: [HOST_KEY],
62
+ } as unknown as MetricQueryData,
63
+ };
64
+
65
+ const metricViewConfig: MetricsViewConfig = {
66
+ queryConfigs: [queryConfig],
67
+ formulaConfigs: [],
68
+ };
69
+
70
+ const monitorStep: MonitorStep = new MonitorStep();
71
+ monitorStep.data = {
72
+ id: ObjectID.generate().toString(),
73
+ monitorCriteria: { data: undefined },
74
+ } as unknown as MonitorStep["data"];
75
+ monitorStep.data!.metricMonitor = {
76
+ metricViewConfig,
77
+ rollingTime: RollingTime.Past5Minutes,
78
+ };
79
+
80
+ // Mirrors the live criteria: heartbeat value Equal To 0, no-data → Trigger.
81
+ const criteriaFilter: CriteriaFilter = {
82
+ checkOn: CheckOn.MetricValue,
83
+ filterType: FilterType.EqualTo,
84
+ value: "0",
85
+ metricMonitorOptions: {
86
+ metricAlias: "h0",
87
+ onNoDataPolicy: NoDataPolicy.Trigger,
88
+ metricAggregationType: EvaluateOverTimeType.AnyValue,
89
+ },
90
+ };
91
+
92
+ /*
93
+ * A reporting host: heartbeat present (value 1) → "== 0" does not match,
94
+ * and there is data so the no-data policy is not triggered.
95
+ */
96
+ const presentSeries: MetricSeriesResult = {
97
+ fingerprint: MetricSeriesFingerprint.computeFingerprint({
98
+ [HOST_KEY]: PRESENT_HOST,
99
+ }),
100
+ labels: { [HOST_KEY]: PRESENT_HOST },
101
+ aggregatedResults: [
102
+ {
103
+ data: [
104
+ {
105
+ timestamp: new Date("2026-07-03T12:00:00.000Z"),
106
+ value: 1,
107
+ } as AggregatedModel,
108
+ ],
109
+ } as AggregatedResult,
110
+ ],
111
+ };
112
+
113
+ /*
114
+ * The silent host is materialized by the REAL injection helper, not hand-
115
+ * built, so this exercises the exact series shape the worker produces.
116
+ */
117
+ const absentSeries: Array<MetricSeriesResult> = buildAbsentHostSeries({
118
+ presentSeries: [presentSeries],
119
+ expectedHostIdentifiers: [PRESENT_HOST, SILENT_HOST],
120
+ hostKey: HOST_KEY,
121
+ slotCount: 1,
122
+ });
123
+
124
+ const dataToProcess: MetricMonitorResponse = {
125
+ projectId: ObjectID.generate(),
126
+ monitorId: ObjectID.generate(),
127
+ metricViewConfig,
128
+ metricResult: [presentSeries.aggregatedResults[0]!],
129
+ seriesBreakdown: [presentSeries, ...absentSeries],
130
+ };
131
+
132
+ return { monitorStep, criteriaFilter, dataToProcess };
133
+ }
134
+
135
+ describe("HostAbsenceSeries end-to-end (Aptean Host Availability shape)", () => {
136
+ test("injection produces exactly one absent series for the silent host", () => {
137
+ const { dataToProcess } = buildFixture();
138
+ const absent: Array<MetricSeriesResult> =
139
+ dataToProcess.seriesBreakdown!.filter((s: MetricSeriesResult) => {
140
+ return s.labels[HOST_KEY] === SILENT_HOST;
141
+ });
142
+ expect(absent).toHaveLength(1);
143
+ expect(absent[0]!.aggregatedResults).toHaveLength(1);
144
+ expect(absent[0]!.aggregatedResults[0]!.data).toEqual([]);
145
+ });
146
+
147
+ test("evaluateAllSeries: silent host fires no-data trigger, present host does not", async () => {
148
+ const { monitorStep, criteriaFilter, dataToProcess } = buildFixture();
149
+
150
+ const evaluations: Array<MetricSeriesEvaluationResult> =
151
+ await MetricMonitorCriteria.evaluateAllSeries({
152
+ dataToProcess,
153
+ criteriaFilter,
154
+ monitorStep,
155
+ });
156
+
157
+ const present: MetricSeriesEvaluationResult | undefined = evaluations.find(
158
+ (e: MetricSeriesEvaluationResult) => {
159
+ return e.labels[HOST_KEY] === PRESENT_HOST;
160
+ },
161
+ );
162
+ const silent: MetricSeriesEvaluationResult | undefined = evaluations.find(
163
+ (e: MetricSeriesEvaluationResult) => {
164
+ return e.labels[HOST_KEY] === SILENT_HOST;
165
+ },
166
+ );
167
+
168
+ expect(present).toBeDefined();
169
+ expect(present!.rootCause).toBeNull();
170
+
171
+ expect(silent).toBeDefined();
172
+ expect(silent!.rootCause).toContain("No data received");
173
+ expect(silent!.rootCause).toContain(HEARTBEAT_METRIC);
174
+ });
175
+
176
+ test("scalar entrypoint reports the criteria as met when a host is silent", async () => {
177
+ const { monitorStep, criteriaFilter, dataToProcess } = buildFixture();
178
+
179
+ const message: string | null =
180
+ await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
181
+ dataToProcess,
182
+ criteriaFilter,
183
+ monitorStep,
184
+ });
185
+
186
+ expect(message).toBeTruthy();
187
+ expect(message).toContain("No data received");
188
+ });
189
+
190
+ test("collectPerSeriesMatches: exactly one per-host match, labeled with the silent host", async () => {
191
+ const { monitorStep, criteriaFilter, dataToProcess } = buildFixture();
192
+
193
+ const monitor: Monitor = new Monitor();
194
+ monitor.monitorType = MonitorType.Metrics;
195
+
196
+ const criteriaInstance: MonitorCriteriaInstance =
197
+ new MonitorCriteriaInstance();
198
+ criteriaInstance.data = {
199
+ id: "criteria-1",
200
+ monitorStatusId: undefined,
201
+ filterCondition: FilterCondition.Any,
202
+ filters: [criteriaFilter],
203
+ incidents: [],
204
+ alerts: [],
205
+ name: "Host down",
206
+ description: "",
207
+ };
208
+
209
+ /*
210
+ * collectPerSeriesMatches is private; exercise it via the documented
211
+ * `as any` escape hatch (same pattern as SeriesAbsenceResolutionGuard).
212
+ */
213
+ const matches: Array<{
214
+ criteriaMetId: string;
215
+ fingerprint: string;
216
+ labels: Record<string, unknown>;
217
+ rootCause: string;
218
+ }> = await (
219
+ MonitorCriteriaEvaluator as unknown as {
220
+ collectPerSeriesMatches: (input: {
221
+ dataToProcess: MetricMonitorResponse;
222
+ monitor: Monitor;
223
+ monitorStep: MonitorStep;
224
+ criteriaInstance: MonitorCriteriaInstance;
225
+ }) => Promise<
226
+ Array<{
227
+ criteriaMetId: string;
228
+ fingerprint: string;
229
+ labels: Record<string, unknown>;
230
+ rootCause: string;
231
+ }>
232
+ >;
233
+ }
234
+ ).collectPerSeriesMatches({
235
+ dataToProcess,
236
+ monitor,
237
+ monitorStep,
238
+ criteriaInstance,
239
+ });
240
+
241
+ expect(matches).toHaveLength(1);
242
+ expect(matches[0]!.labels[HOST_KEY]).toBe(SILENT_HOST);
243
+ expect(matches[0]!.fingerprint).toBe(
244
+ MetricSeriesFingerprint.computeFingerprint({ [HOST_KEY]: SILENT_HOST }),
245
+ );
246
+ expect(matches[0]!.rootCause).toContain("No data received");
247
+ expect(matches[0]!.criteriaMetId).toBe("criteria-1");
248
+ });
249
+ });
@@ -393,6 +393,46 @@ export class Service extends DatabaseService {
393
393
  }
394
394
  }
395
395
  }
396
+ async getExpectedHostIdentifiers(data) {
397
+ /*
398
+ * "Expected" hosts for per-host down-detection: non-archived hosts in
399
+ * the project that reported within the recency window. Their canonical
400
+ * hostIdentifier equals the metric's `resource.host.name` value (both
401
+ * canonicalized at ingest), so the telemetry monitor can diff this set
402
+ * against the hosts present in the current evaluation window and
403
+ * synthesize a "no data" series for any that have gone silent — a
404
+ * group-by-host query returns no row for a silent host, so absence is
405
+ * otherwise invisible. See HostAbsenceSeries and
406
+ * MonitorTelemetryMonitor.injectExpectedAbsentHostSeries.
407
+ */
408
+ const cutoff = OneUptimeDate.addRemoveMinutes(OneUptimeDate.getCurrentDate(), -Math.abs(data.seenWithinMinutes));
409
+ const hosts = await this.findBy({
410
+ query: {
411
+ projectId: data.projectId,
412
+ lastSeenAt: QueryHelper.greaterThanEqualTo(cutoff),
413
+ },
414
+ select: {
415
+ hostIdentifier: true,
416
+ isArchived: true,
417
+ },
418
+ limit: LIMIT_MAX,
419
+ skip: 0,
420
+ props: {
421
+ isRoot: true,
422
+ },
423
+ });
424
+ const identifiers = [];
425
+ for (const host of hosts) {
426
+ // isArchived is nullable; treat null/undefined as not archived.
427
+ if (host.isArchived) {
428
+ continue;
429
+ }
430
+ if (host.hostIdentifier) {
431
+ identifiers.push(canonicalizeEntityValue(host.hostIdentifier));
432
+ }
433
+ }
434
+ return identifiers;
435
+ }
396
436
  }
397
437
  __decorate([
398
438
  CaptureSpan(),
@@ -424,6 +464,12 @@ __decorate([
424
464
  __metadata("design:paramtypes", []),
425
465
  __metadata("design:returntype", Promise)
426
466
  ], Service.prototype, "markDisconnectedHosts", null);
467
+ __decorate([
468
+ CaptureSpan(),
469
+ __metadata("design:type", Function),
470
+ __metadata("design:paramtypes", [Object]),
471
+ __metadata("design:returntype", Promise)
472
+ ], Service.prototype, "getExpectedHostIdentifiers", null);
427
473
  function fingerprintLabelIds(labelIds) {
428
474
  const sorted = labelIds
429
475
  .map((id) => {
@@ -1 +1 @@
1
- {"version":3,"file":"HostService.js","sourceRoot":"","sources":["../../../../Server/Services/HostService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HostService.js","sourceRoot":"","sources":["../../../../Server/Services/HostService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ import { CheckOn, NoDataPolicy, } from "../../../Types/Monitor/CriteriaFilter";
2
+ import MetricSeriesFingerprint from "../../../Utils/Metrics/MetricSeriesFingerprint";
3
+ import { canonicalizeEntityValue } from "../../../Utils/Telemetry/EntityKey";
4
+ /*
5
+ * Pure helpers backing per-host "went silent" detection.
6
+ *
7
+ * A group-by-host metric query only returns a series for hosts that
8
+ * emitted rows in the evaluation window — a host that stopped reporting
9
+ * simply has no row, so its absence is invisible to the criteria
10
+ * evaluator and its NoDataPolicy.Trigger check never runs. These helpers
11
+ * let the telemetry monitor reconstruct the "expected" host set (from the
12
+ * Host registry) and synthesize an empty "no data" series for every
13
+ * expected host missing from the current window, so the existing
14
+ * per-series NoDataPolicy path fires one correctly-labeled alert per down
15
+ * host. Kept pure (no DB) so the gating and series-construction logic is
16
+ * unit-testable; the worker supplies the expected-host list.
17
+ */
18
+ /**
19
+ * OTel resource attribute keys that identify a host. Metrics store
20
+ * `host.name` under the resource-prefixed key; the bare form is accepted
21
+ * defensively.
22
+ */
23
+ export const HOST_NAME_ATTRIBUTE_KEYS = [
24
+ "resource.host.name",
25
+ "host.name",
26
+ ];
27
+ /**
28
+ * A host that reported within this window is treated as a live member of
29
+ * the fleet and therefore "expected" to still be reporting; if it is now
30
+ * silent, that is a real outage worth alerting on. A host silent for
31
+ * longer than this ages out of down-detection so a decommissioned-but-not-
32
+ * archived host does not alert forever. Deliberately generous (a day) so a
33
+ * genuine multi-hour outage keeps alerting rather than silently resolving —
34
+ * missing a real outage is worse than a nuisance alert on a dead host.
35
+ */
36
+ export const HOST_ABSENCE_EXPECTED_WINDOW_MINUTES = 24 * 60;
37
+ /**
38
+ * If the monitor is grouped by exactly one host-name attribute, return
39
+ * that group-by key; otherwise null. Absent-host synthesis only makes
40
+ * sense for a pure per-host group-by — a multi-dimensional group-by
41
+ * (host + device, etc.) can't be enumerated from the host registry, and a
42
+ * non-host group-by isn't about hosts at all.
43
+ */
44
+ export function getHostAbsenceGroupByKey(groupByAttributeKeys) {
45
+ if (!groupByAttributeKeys || groupByAttributeKeys.length !== 1) {
46
+ return null;
47
+ }
48
+ const key = groupByAttributeKeys[0];
49
+ return HOST_NAME_ATTRIBUTE_KEYS.includes(key) ? key : null;
50
+ }
51
+ /**
52
+ * True if any metric-value criteria filter on the step opts into no-data
53
+ * detection (NoDataPolicy Trigger or TreatAsZero). When no criterion cares
54
+ * about missing data, seeding absent-host series would be pointless — they
55
+ * would evaluate to "ignore" — so the caller skips the extra work.
56
+ */
57
+ export function monitorStepOptsIntoNoDataDetection(monitorStep) {
58
+ var _a, _b, _c, _d, _e;
59
+ const instances = ((_c = (_b = (_a = monitorStep.data) === null || _a === void 0 ? void 0 : _a.monitorCriteria) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.monitorCriteriaInstanceArray) || [];
60
+ for (const instance of instances) {
61
+ const filters = ((_d = instance.data) === null || _d === void 0 ? void 0 : _d.filters) || [];
62
+ for (const filter of filters) {
63
+ if (filter.checkOn !== CheckOn.MetricValue) {
64
+ continue;
65
+ }
66
+ const policy = (_e = filter.metricMonitorOptions) === null || _e === void 0 ? void 0 : _e.onNoDataPolicy;
67
+ if (policy === NoDataPolicy.Trigger ||
68
+ policy === NoDataPolicy.TreatAsZero) {
69
+ return true;
70
+ }
71
+ }
72
+ }
73
+ return false;
74
+ }
75
+ /**
76
+ * True if any query carries attribute equality filters. Such a filter
77
+ * scopes the query to a subset of hosts, so the project-wide expected-host
78
+ * set would over-report absences for out-of-scope hosts; the caller skips
79
+ * absent-host synthesis in that case.
80
+ */
81
+ export function queriesScopeHostSubset(queryConfigs) {
82
+ var _a, _b;
83
+ for (const queryConfig of queryConfigs || []) {
84
+ const attributes = (_b = (_a = queryConfig.metricQueryData) === null || _a === void 0 ? void 0 : _a.filterData) === null || _b === void 0 ? void 0 : _b.attributes;
85
+ if (attributes && Object.keys(attributes).length > 0) {
86
+ return true;
87
+ }
88
+ }
89
+ return false;
90
+ }
91
+ /**
92
+ * Build synthetic "no data" series for every expected host absent from the
93
+ * current window's series breakdown. Each synthetic series has empty
94
+ * aggregated-result slots (one per query + formula, matching how present
95
+ * series are shaped) so the criteria evaluator's NoDataPolicy path fires
96
+ * for it, and labels/fingerprint identical to what the host's present
97
+ * series would carry so the resulting alert dedupes and auto-resolves when
98
+ * the host returns. Host identity is compared case-insensitively
99
+ * (canonicalized), matching how ingest stores host.name.
100
+ */
101
+ export function buildAbsentHostSeries(input) {
102
+ var _a;
103
+ const presentHosts = new Set();
104
+ for (const series of input.presentSeries) {
105
+ const raw = (_a = series.labels) === null || _a === void 0 ? void 0 : _a[input.hostKey];
106
+ if (raw === undefined || raw === null || String(raw) === "") {
107
+ continue;
108
+ }
109
+ presentHosts.add(canonicalizeEntityValue(String(raw)));
110
+ }
111
+ const slotCount = Math.max(input.slotCount, 1);
112
+ const seen = new Set();
113
+ const absentSeries = [];
114
+ for (const identifierRaw of input.expectedHostIdentifiers) {
115
+ const identifier = canonicalizeEntityValue(String(identifierRaw));
116
+ if (!identifier || presentHosts.has(identifier) || seen.has(identifier)) {
117
+ continue;
118
+ }
119
+ seen.add(identifier);
120
+ const labels = { [input.hostKey]: identifier };
121
+ const aggregatedResults = Array.from({ length: slotCount }, () => {
122
+ return { data: [] };
123
+ });
124
+ absentSeries.push({
125
+ fingerprint: MetricSeriesFingerprint.computeFingerprint(labels),
126
+ labels,
127
+ aggregatedResults,
128
+ });
129
+ }
130
+ return absentSeries;
131
+ }
132
+ //# sourceMappingURL=HostAbsenceSeries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HostAbsenceSeries.js","sourceRoot":"","sources":["../../../../../Server/Utils/Monitor/HostAbsenceSeries.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneuptime/common",
3
- "version": "11.3.23",
3
+ "version": "11.3.25",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",