next-observer 0.3.0 → 0.3.1
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/dist/debug/detector.d.ts +6 -0
- package/dist/debug/detector.js +12 -12
- package/dist/debug/detector.js.map +1 -1
- package/package.json +1 -1
package/dist/debug/detector.d.ts
CHANGED
|
@@ -27,7 +27,13 @@ export interface Anomaly {
|
|
|
27
27
|
}[];
|
|
28
28
|
}
|
|
29
29
|
export interface DetectorOptions {
|
|
30
|
+
/** Window for the app-wide rule. */
|
|
30
31
|
windowMs?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Window for the per-operation rule. Longer than the app-wide one: an operation is a fraction of the traffic, and in
|
|
34
|
+
* 10 s a checkout at ~0.6 requests/s gets 3–5 samples — under minSamples, so a ×7 slowdown went unnoticed.
|
|
35
|
+
*/
|
|
36
|
+
operationWindowMs?: number;
|
|
31
37
|
/** Error share of server requests in the window. */
|
|
32
38
|
errorRate?: number;
|
|
33
39
|
/** A request slower than this counts as slow. */
|
package/dist/debug/detector.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const DEFAULTS = { windowMs: 10_000, errorRate: 0.2, slowMs: 1000, slowRate: 0.3, noTrafficMs: 120_000, minSamples: 5, cooldownMs: 300_000 };
|
|
1
|
+
const DEFAULTS = { windowMs: 10_000, operationWindowMs: 30_000, errorRate: 0.2, slowMs: 1000, slowRate: 0.3, noTrafficMs: 120_000, minSamples: 5, cooldownMs: 300_000 };
|
|
2
2
|
// Only server entry spans count: Next emits ~7 internal spans per request, which would dilute a 30% error rate below
|
|
3
3
|
// any threshold. Browser and internal spans are ignored.
|
|
4
4
|
const isServerRequest = (s) => s.kind === 'server';
|
|
@@ -28,10 +28,10 @@ export class AnomalyDetector {
|
|
|
28
28
|
check() {
|
|
29
29
|
const now = this.now();
|
|
30
30
|
const o = this.options;
|
|
31
|
-
this.window = this.window.filter((w) => now - w.atMs <= o.windowMs);
|
|
32
|
-
const
|
|
31
|
+
this.window = this.window.filter((w) => now - w.atMs <= Math.max(o.windowMs, o.operationWindowMs));
|
|
32
|
+
const within = (ms) => this.window.filter((w) => now - w.atMs <= ms).map((w) => w.span);
|
|
33
33
|
const found = [];
|
|
34
|
-
const judge = (list, subject) => {
|
|
34
|
+
const judge = (list, windowMs, subject) => {
|
|
35
35
|
if (list.length < o.minSamples)
|
|
36
36
|
return;
|
|
37
37
|
const errorRate = list.filter((s) => s.status === 'error').length / list.length;
|
|
@@ -39,24 +39,24 @@ export class AnomalyDetector {
|
|
|
39
39
|
// An operation-level anomaly would only repeat an app-wide one of the same type.
|
|
40
40
|
const covered = (type) => subject && found.some((a) => a.type === type && a.scope === 'all');
|
|
41
41
|
if (errorRate > o.errorRate && !covered('high_error_rate')) {
|
|
42
|
-
found.push(this.anomaly('high_error_rate', errorRate, o.errorRate, list, now, errorRate >= 2 * o.errorRate, subject));
|
|
42
|
+
found.push(this.anomaly('high_error_rate', errorRate, o.errorRate, list, now, errorRate >= 2 * o.errorRate, windowMs, subject));
|
|
43
43
|
}
|
|
44
44
|
if (slowRate > o.slowRate && !covered('high_latency')) {
|
|
45
|
-
found.push(this.anomaly('high_latency', slowRate, o.slowRate, list, now, slowRate >= 2 * o.slowRate, subject));
|
|
45
|
+
found.push(this.anomaly('high_latency', slowRate, o.slowRate, list, now, slowRate >= 2 * o.slowRate, windowMs, subject));
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
|
-
judge(
|
|
48
|
+
judge(within(o.windowMs), o.windowMs);
|
|
49
49
|
// Per operation: on a realistic route mix one broken endpoint (30% errors) is only ~10% of all requests —
|
|
50
50
|
// below the app-wide threshold, yet clearly an incident.
|
|
51
51
|
const byOperation = new Map();
|
|
52
|
-
for (const s of
|
|
52
|
+
for (const s of within(o.operationWindowMs)) {
|
|
53
53
|
const key = `${s.service}\u0000${s.name}`;
|
|
54
54
|
byOperation.set(key, [...(byOperation.get(key) ?? []), s]);
|
|
55
55
|
}
|
|
56
56
|
for (const list of byOperation.values())
|
|
57
|
-
judge(list, { service: list[0].service, operation: list[0].name });
|
|
57
|
+
judge(list, o.operationWindowMs, { service: list[0].service, operation: list[0].name });
|
|
58
58
|
if (this.lastSeenMs !== null && now - this.lastSeenMs > o.noTrafficMs) {
|
|
59
|
-
found.push(this.anomaly('no_traffic', Math.round((now - this.lastSeenMs) / 1000), o.noTrafficMs / 1000, [], now, true));
|
|
59
|
+
found.push(this.anomaly('no_traffic', Math.round((now - this.lastSeenMs) / 1000), o.noTrafficMs / 1000, [], now, true, o.windowMs));
|
|
60
60
|
}
|
|
61
61
|
return found.filter((a) => {
|
|
62
62
|
const key = a.subject ? `${a.type}\u0000${a.subject.service}\u0000${a.subject.operation}` : a.type;
|
|
@@ -67,7 +67,7 @@ export class AnomalyDetector {
|
|
|
67
67
|
return true;
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
|
-
anomaly(type, value, threshold, requests, now, critical, subject) {
|
|
70
|
+
anomaly(type, value, threshold, requests, now, critical, windowMs, subject) {
|
|
71
71
|
const byOperation = new Map();
|
|
72
72
|
for (const s of requests) {
|
|
73
73
|
const key = `${s.service}\u0000${s.name}`;
|
|
@@ -94,7 +94,7 @@ export class AnomalyDetector {
|
|
|
94
94
|
value: Math.round(value * 1000) / 1000,
|
|
95
95
|
threshold,
|
|
96
96
|
sampleSize: requests.length,
|
|
97
|
-
windowMs
|
|
97
|
+
windowMs,
|
|
98
98
|
operations,
|
|
99
99
|
};
|
|
100
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/debug/detector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/debug/detector.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-observer",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "The observer for next-observe: OTLP collector, trace UI, anomaly detector and AI agents that investigate your Next.js app. Run with npx next-observer dev.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nextjs",
|