@checkstack/healthcheck-ping-backend 0.3.10 → 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 CHANGED
@@ -1,5 +1,52 @@
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
+
43
+ ## 0.3.11
44
+
45
+ ### Patch Changes
46
+
47
+ - Updated dependencies [2ec8f64]
48
+ - @checkstack/backend-api@0.24.1
49
+
3
50
  ## 0.3.10
4
51
 
5
52
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/healthcheck-ping-backend",
3
- "version": "0.3.10",
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.24.0",
18
- "@checkstack/common": "0.16.0",
19
- "@checkstack/healthcheck-common": "1.7.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.2"
25
+ "@checkstack/scripts": "0.6.3"
26
26
  },
27
27
  "description": "Checkstack healthcheck-ping-backend plugin",
28
28
  "author": {
@@ -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": true,
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": true,
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": true,
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": true,
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": true,
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": true,
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": true,
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": true,
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": true,
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