@checkstack/healthcheck-ping-backend 0.3.11 → 0.3.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/CHANGELOG.md +40 -0
- package/package.json +5 -5
- package/src/ping-collector.ts +30 -16
- package/src/strategy.ts +39 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @checkstack/healthcheck-ping-backend
|
|
2
2
|
|
|
3
|
+
## 0.3.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8cad340: Retune anomaly-detection defaults across every health-check strategy and the
|
|
8
|
+
hardware collector for a low-noise, problem-focused out-of-the-box experience.
|
|
9
|
+
|
|
10
|
+
The detection engine already learns a per-metric baseline, debounces with a
|
|
11
|
+
confirmation window, and applies practical-significance floors. This pass tunes
|
|
12
|
+
the per-metric **defaults** so a fresh install alerts only on genuine,
|
|
13
|
+
statistically-significant, problem-mapping deviations instead of flooding on
|
|
14
|
+
every metric that wiggles. 264 metrics were reviewed:
|
|
15
|
+
|
|
16
|
+
- **Default-disabled** the high-noise and un-baselineable classes that were
|
|
17
|
+
alerting for no good reason: raw identifiers and counts (status codes, error
|
|
18
|
+
and row counts, build counts, player and executor counts), config echoes and
|
|
19
|
+
near-constants (probe packet counts, CPU core count, total/swap memory),
|
|
20
|
+
payload-size and other run-to-run-volatile values, and deterministic values
|
|
21
|
+
like certificate days-remaining (governed by the check's own static-threshold
|
|
22
|
+
health logic, not statistics). These stay chartable and can be re-enabled per
|
|
23
|
+
field.
|
|
24
|
+
- **Hardened** the signals that should alert - latency/response/execution time
|
|
25
|
+
and availability/success/saturation percentages - with confirmation windows
|
|
26
|
+
and absolute + relative floors so brief spikes and sub-threshold jitter no
|
|
27
|
+
longer flap, and prefer percentage metrics over their absolute twins.
|
|
28
|
+
|
|
29
|
+
No detection-engine or schema changes; only per-metric `x-anomaly-*` defaults.
|
|
30
|
+
Users who had opted into any now-disabled metric keep their explicit override.
|
|
31
|
+
|
|
32
|
+
- Updated dependencies [8cad340]
|
|
33
|
+
- Updated dependencies [8cad340]
|
|
34
|
+
- Updated dependencies [8cad340]
|
|
35
|
+
- Updated dependencies [8cad340]
|
|
36
|
+
- Updated dependencies [8cad340]
|
|
37
|
+
- Updated dependencies [8cad340]
|
|
38
|
+
- Updated dependencies [8cad340]
|
|
39
|
+
- @checkstack/backend-api@0.25.0
|
|
40
|
+
- @checkstack/healthcheck-common@1.8.0
|
|
41
|
+
- @checkstack/common@0.17.0
|
|
42
|
+
|
|
3
43
|
## 0.3.11
|
|
4
44
|
|
|
5
45
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/healthcheck-ping-backend",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"checkstack": {
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
"pack": "bunx @checkstack/scripts plugin-pack"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@checkstack/backend-api": "0.
|
|
18
|
-
"@checkstack/common": "0.
|
|
19
|
-
"@checkstack/healthcheck-common": "1.
|
|
17
|
+
"@checkstack/backend-api": "0.25.0",
|
|
18
|
+
"@checkstack/common": "0.17.0",
|
|
19
|
+
"@checkstack/healthcheck-common": "1.8.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/bun": "^1.0.0",
|
|
23
23
|
"typescript": "^5.0.0",
|
|
24
24
|
"@checkstack/tsconfig": "0.0.7",
|
|
25
|
-
"@checkstack/scripts": "0.6.
|
|
25
|
+
"@checkstack/scripts": "0.6.3"
|
|
26
26
|
},
|
|
27
27
|
"description": "Checkstack healthcheck-ping-backend plugin",
|
|
28
28
|
"author": {
|
package/src/ping-collector.ts
CHANGED
|
@@ -43,56 +43,63 @@ export type PingConfig = z.infer<typeof pingConfigSchema>;
|
|
|
43
43
|
// ============================================================================
|
|
44
44
|
|
|
45
45
|
const pingResultSchema = healthResultSchema({
|
|
46
|
+
// Echo of the configured probe count (`count`). A baseline over a near
|
|
47
|
+
// constant is meaningless, so anomaly detection is off by default. Still
|
|
48
|
+
// chartable; opt in if a probe count genuinely varies.
|
|
46
49
|
packetsSent: healthResultNumber({
|
|
47
50
|
"x-chart-type": "counter",
|
|
48
51
|
"x-chart-label": "Packets Sent",
|
|
49
|
-
"x-anomaly-enabled":
|
|
50
|
-
"x-anomaly-direction": "deviation",
|
|
51
|
-
"x-anomaly-min-absolute-delta": 1,
|
|
52
|
-
"x-anomaly-min-relative-delta": 0.25,
|
|
52
|
+
"x-anomaly-enabled": false,
|
|
53
53
|
}),
|
|
54
|
+
// Absolute twin of packetLoss. The percent form (packetLoss) is the better
|
|
55
|
+
// signal because it is config independent, so this absolute count is off by
|
|
56
|
+
// default to avoid duplicate, drift-prone alerts.
|
|
54
57
|
packetsReceived: healthResultNumber({
|
|
55
58
|
"x-chart-type": "counter",
|
|
56
59
|
"x-chart-label": "Packets Received",
|
|
57
|
-
"x-anomaly-enabled":
|
|
58
|
-
"x-anomaly-direction": "higher-is-better",
|
|
59
|
-
"x-anomaly-min-absolute-delta": 1,
|
|
60
|
-
"x-anomaly-min-relative-delta": 0.25,
|
|
60
|
+
"x-anomaly-enabled": false,
|
|
61
61
|
}),
|
|
62
|
+
// Primary saturation signal: packet loss as a percent. Confirmation window
|
|
63
|
+
// debounces single-sample blips; a few-percent absolute floor keeps tiny
|
|
64
|
+
// jitter from alerting.
|
|
62
65
|
packetLoss: healthResultNumber({
|
|
63
66
|
"x-chart-type": "gauge",
|
|
64
67
|
"x-chart-label": "Packet Loss",
|
|
65
68
|
"x-chart-unit": "%",
|
|
66
69
|
"x-anomaly-enabled": true,
|
|
67
70
|
"x-anomaly-direction": "lower-is-better",
|
|
71
|
+
"x-anomaly-sensitivity": 1.5,
|
|
72
|
+
"x-anomaly-confirmation-window": 3,
|
|
68
73
|
"x-anomaly-min-absolute-delta": 5,
|
|
69
74
|
}),
|
|
75
|
+
// Min latency barely moves and is the least operationally meaningful of the
|
|
76
|
+
// three latency stats, so it is off by default. avgLatency is the kept signal.
|
|
70
77
|
minLatency: healthResultNumber({
|
|
71
78
|
"x-chart-type": "line",
|
|
72
79
|
"x-chart-label": "Min Latency",
|
|
73
80
|
"x-chart-unit": "ms",
|
|
74
|
-
"x-anomaly-enabled":
|
|
75
|
-
"x-anomaly-direction": "lower-is-better",
|
|
76
|
-
"x-anomaly-min-absolute-delta": 50,
|
|
77
|
-
"x-anomaly-min-relative-delta": 0.5,
|
|
81
|
+
"x-anomaly-enabled": false,
|
|
78
82
|
}).optional(),
|
|
83
|
+
// Representative latency signal. Wider band plus a confirmation window and
|
|
84
|
+
// both floors so fast endpoints do not alert on small jitter.
|
|
79
85
|
avgLatency: healthResultNumber({
|
|
80
86
|
"x-chart-type": "line",
|
|
81
87
|
"x-chart-label": "Avg Latency",
|
|
82
88
|
"x-chart-unit": "ms",
|
|
83
89
|
"x-anomaly-enabled": true,
|
|
84
90
|
"x-anomaly-direction": "lower-is-better",
|
|
91
|
+
"x-anomaly-sensitivity": 1.5,
|
|
92
|
+
"x-anomaly-confirmation-window": 3,
|
|
85
93
|
"x-anomaly-min-absolute-delta": 50,
|
|
86
94
|
"x-anomaly-min-relative-delta": 0.5,
|
|
87
95
|
}).optional(),
|
|
96
|
+
// Max latency is the spikiest of the three stats (single slow packet drives
|
|
97
|
+
// it) and is a frequent false-positive source, so it is off by default.
|
|
88
98
|
maxLatency: healthResultNumber({
|
|
89
99
|
"x-chart-type": "line",
|
|
90
100
|
"x-chart-label": "Max Latency",
|
|
91
101
|
"x-chart-unit": "ms",
|
|
92
|
-
"x-anomaly-enabled":
|
|
93
|
-
"x-anomaly-direction": "lower-is-better",
|
|
94
|
-
"x-anomaly-min-absolute-delta": 50,
|
|
95
|
-
"x-anomaly-min-relative-delta": 0.5,
|
|
102
|
+
"x-anomaly-enabled": false,
|
|
96
103
|
}).optional(),
|
|
97
104
|
});
|
|
98
105
|
|
|
@@ -106,6 +113,9 @@ const pingAggregatedFields = {
|
|
|
106
113
|
"x-chart-unit": "%",
|
|
107
114
|
"x-anomaly-enabled": true,
|
|
108
115
|
"x-anomaly-direction": "lower-is-better",
|
|
116
|
+
"x-anomaly-sensitivity": 1.5,
|
|
117
|
+
"x-anomaly-confirmation-window": 3,
|
|
118
|
+
"x-anomaly-min-absolute-delta": 5,
|
|
109
119
|
}),
|
|
110
120
|
avgLatency: aggregatedAverage({
|
|
111
121
|
"x-chart-type": "line",
|
|
@@ -113,6 +123,10 @@ const pingAggregatedFields = {
|
|
|
113
123
|
"x-chart-unit": "ms",
|
|
114
124
|
"x-anomaly-enabled": true,
|
|
115
125
|
"x-anomaly-direction": "lower-is-better",
|
|
126
|
+
"x-anomaly-sensitivity": 1.5,
|
|
127
|
+
"x-anomaly-confirmation-window": 3,
|
|
128
|
+
"x-anomaly-min-absolute-delta": 50,
|
|
129
|
+
"x-anomaly-min-relative-delta": 0.5,
|
|
116
130
|
}),
|
|
117
131
|
};
|
|
118
132
|
|
package/src/strategy.ts
CHANGED
|
@@ -58,56 +58,63 @@ function readTimeout(data: unknown): number | undefined {
|
|
|
58
58
|
* Per-run result metadata.
|
|
59
59
|
*/
|
|
60
60
|
const pingResultSchema = healthResultSchema({
|
|
61
|
+
// Echo of the configured probe count (`count`). A baseline over a near
|
|
62
|
+
// constant is meaningless, so anomaly detection is off by default. Still
|
|
63
|
+
// chartable; opt in if a probe count genuinely varies.
|
|
61
64
|
packetsSent: healthResultNumber({
|
|
62
65
|
"x-chart-type": "counter",
|
|
63
66
|
"x-chart-label": "Packets Sent",
|
|
64
|
-
"x-anomaly-enabled":
|
|
65
|
-
"x-anomaly-direction": "deviation",
|
|
66
|
-
"x-anomaly-min-absolute-delta": 1,
|
|
67
|
-
"x-anomaly-min-relative-delta": 0.25,
|
|
67
|
+
"x-anomaly-enabled": false,
|
|
68
68
|
}),
|
|
69
|
+
// Absolute twin of packetLoss. The percent form (packetLoss) is the better
|
|
70
|
+
// signal because it is config independent, so this absolute count is off by
|
|
71
|
+
// default to avoid duplicate, drift-prone alerts.
|
|
69
72
|
packetsReceived: healthResultNumber({
|
|
70
73
|
"x-chart-type": "counter",
|
|
71
74
|
"x-chart-label": "Packets Received",
|
|
72
|
-
"x-anomaly-enabled":
|
|
73
|
-
"x-anomaly-direction": "higher-is-better",
|
|
74
|
-
"x-anomaly-min-absolute-delta": 1,
|
|
75
|
-
"x-anomaly-min-relative-delta": 0.25,
|
|
75
|
+
"x-anomaly-enabled": false,
|
|
76
76
|
}),
|
|
77
|
+
// Primary saturation signal: packet loss as a percent. Confirmation window
|
|
78
|
+
// debounces single-sample blips; a few-percent absolute floor keeps tiny
|
|
79
|
+
// jitter from alerting.
|
|
77
80
|
packetLoss: healthResultNumber({
|
|
78
81
|
"x-chart-type": "gauge",
|
|
79
82
|
"x-chart-label": "Packet Loss",
|
|
80
83
|
"x-chart-unit": "%",
|
|
81
84
|
"x-anomaly-enabled": true,
|
|
82
85
|
"x-anomaly-direction": "lower-is-better",
|
|
86
|
+
"x-anomaly-sensitivity": 1.5,
|
|
87
|
+
"x-anomaly-confirmation-window": 3,
|
|
83
88
|
"x-anomaly-min-absolute-delta": 5,
|
|
84
89
|
}),
|
|
90
|
+
// Min latency barely moves and is the least operationally meaningful of the
|
|
91
|
+
// three latency stats, so it is off by default. avgLatency is the kept signal.
|
|
85
92
|
minLatency: healthResultNumber({
|
|
86
93
|
"x-chart-type": "line",
|
|
87
94
|
"x-chart-label": "Min Latency",
|
|
88
95
|
"x-chart-unit": "ms",
|
|
89
|
-
"x-anomaly-enabled":
|
|
90
|
-
"x-anomaly-direction": "lower-is-better",
|
|
91
|
-
"x-anomaly-min-absolute-delta": 50,
|
|
92
|
-
"x-anomaly-min-relative-delta": 0.5,
|
|
96
|
+
"x-anomaly-enabled": false,
|
|
93
97
|
}).optional(),
|
|
98
|
+
// Representative latency signal. Wider band plus a confirmation window and
|
|
99
|
+
// both floors so fast endpoints do not alert on small jitter.
|
|
94
100
|
avgLatency: healthResultNumber({
|
|
95
101
|
"x-chart-type": "line",
|
|
96
102
|
"x-chart-label": "Avg Latency",
|
|
97
103
|
"x-chart-unit": "ms",
|
|
98
104
|
"x-anomaly-enabled": true,
|
|
99
105
|
"x-anomaly-direction": "lower-is-better",
|
|
106
|
+
"x-anomaly-sensitivity": 1.5,
|
|
107
|
+
"x-anomaly-confirmation-window": 3,
|
|
100
108
|
"x-anomaly-min-absolute-delta": 50,
|
|
101
109
|
"x-anomaly-min-relative-delta": 0.5,
|
|
102
110
|
}).optional(),
|
|
111
|
+
// Max latency is the spikiest of the three stats (single slow packet drives
|
|
112
|
+
// it) and is a frequent false-positive source, so it is off by default.
|
|
103
113
|
maxLatency: healthResultNumber({
|
|
104
114
|
"x-chart-type": "line",
|
|
105
115
|
"x-chart-label": "Max Latency",
|
|
106
116
|
"x-chart-unit": "ms",
|
|
107
|
-
"x-anomaly-enabled":
|
|
108
|
-
"x-anomaly-direction": "lower-is-better",
|
|
109
|
-
"x-anomaly-min-absolute-delta": 50,
|
|
110
|
-
"x-anomaly-min-relative-delta": 0.5,
|
|
117
|
+
"x-anomaly-enabled": false,
|
|
111
118
|
}).optional(),
|
|
112
119
|
error: healthResultString({
|
|
113
120
|
"x-chart-type": "status",
|
|
@@ -126,6 +133,9 @@ const pingAggregatedFields = {
|
|
|
126
133
|
"x-chart-unit": "%",
|
|
127
134
|
"x-anomaly-enabled": true,
|
|
128
135
|
"x-anomaly-direction": "lower-is-better",
|
|
136
|
+
"x-anomaly-sensitivity": 1.5,
|
|
137
|
+
"x-anomaly-confirmation-window": 3,
|
|
138
|
+
"x-anomaly-min-absolute-delta": 5,
|
|
129
139
|
}),
|
|
130
140
|
avgLatency: aggregatedAverage({
|
|
131
141
|
"x-chart-type": "line",
|
|
@@ -133,19 +143,30 @@ const pingAggregatedFields = {
|
|
|
133
143
|
"x-chart-unit": "ms",
|
|
134
144
|
"x-anomaly-enabled": true,
|
|
135
145
|
"x-anomaly-direction": "lower-is-better",
|
|
146
|
+
"x-anomaly-sensitivity": 1.5,
|
|
147
|
+
"x-anomaly-confirmation-window": 3,
|
|
148
|
+
"x-anomaly-min-absolute-delta": 50,
|
|
149
|
+
"x-anomaly-min-relative-delta": 0.5,
|
|
136
150
|
}),
|
|
151
|
+
// Bucket max of per-run max latency: doubly spiky (max of maxes), so it is
|
|
152
|
+
// off by default to avoid alert fatigue. Still chartable.
|
|
137
153
|
maxLatency: aggregatedMinMax({
|
|
138
154
|
"x-chart-type": "line",
|
|
139
155
|
"x-chart-label": "Max Latency",
|
|
140
156
|
"x-chart-unit": "ms",
|
|
141
|
-
"x-anomaly-enabled":
|
|
142
|
-
"x-anomaly-direction": "lower-is-better",
|
|
157
|
+
"x-anomaly-enabled": false,
|
|
143
158
|
}),
|
|
159
|
+
// Count of runs in the bucket that errored. Clear direction and a meaningful
|
|
160
|
+
// distribution, kept enabled with a confirmation window and a small absolute
|
|
161
|
+
// floor so a single transient error does not alert.
|
|
144
162
|
errorCount: aggregatedCounter({
|
|
145
163
|
"x-chart-type": "counter",
|
|
146
164
|
"x-chart-label": "Errors",
|
|
147
165
|
"x-anomaly-enabled": true,
|
|
148
166
|
"x-anomaly-direction": "lower-is-better",
|
|
167
|
+
"x-anomaly-sensitivity": 1.5,
|
|
168
|
+
"x-anomaly-confirmation-window": 3,
|
|
169
|
+
"x-anomaly-min-absolute-delta": 1,
|
|
149
170
|
}),
|
|
150
171
|
};
|
|
151
172
|
|