@ddtcorex/dsh-maestro-supervisor 0.1.0 → 0.2.0
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/lib/health-poller.js +31 -7
- package/lib/supervisor.d.ts +1 -0
- package/lib/supervisor.js +15 -0
- package/package.json +1 -1
package/lib/health-poller.js
CHANGED
|
@@ -46,13 +46,30 @@ export async function pollHealth(opts = {}) {
|
|
|
46
46
|
break;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
//
|
|
50
|
-
if (fetchError
|
|
49
|
+
// Distinguish FULL (http !=200) vs DEGRADED (http 200 but log has plugin error)
|
|
50
|
+
if (fetchError) {
|
|
51
51
|
return {
|
|
52
52
|
up: false,
|
|
53
53
|
httpCode,
|
|
54
|
-
error: logError
|
|
55
|
-
degraded:
|
|
54
|
+
error: logError ? `${fetchError} + ${logError}` : fetchError,
|
|
55
|
+
degraded: false,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (logError) {
|
|
59
|
+
// http 200 but log error → DEGRADED (isolatable), not FULL
|
|
60
|
+
if (httpCode === 200) {
|
|
61
|
+
return {
|
|
62
|
+
up: true,
|
|
63
|
+
httpCode,
|
|
64
|
+
error: logError,
|
|
65
|
+
degraded: true,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
up: false,
|
|
70
|
+
httpCode,
|
|
71
|
+
error: logError,
|
|
72
|
+
degraded: false,
|
|
56
73
|
};
|
|
57
74
|
}
|
|
58
75
|
// Also check psAlive as secondary signal — if fetch ok but ps dead, still down
|
|
@@ -95,9 +112,16 @@ async function defaultLogTail() {
|
|
|
95
112
|
try {
|
|
96
113
|
const { readFileSync } = await import('node:fs');
|
|
97
114
|
const { homedir } = await import('node:os');
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
|
|
115
|
+
const candidates = [`${homedir()}/.dsh/dsh-web.log`, `${homedir()}/.dsh.log`];
|
|
116
|
+
for (const logPath of candidates) {
|
|
117
|
+
try {
|
|
118
|
+
const content = readFileSync(logPath, 'utf-8');
|
|
119
|
+
if (content)
|
|
120
|
+
return content.slice(-5000);
|
|
121
|
+
}
|
|
122
|
+
catch { }
|
|
123
|
+
}
|
|
124
|
+
return '';
|
|
101
125
|
}
|
|
102
126
|
catch {
|
|
103
127
|
return '';
|
package/lib/supervisor.d.ts
CHANGED
package/lib/supervisor.js
CHANGED
|
@@ -3,12 +3,27 @@ export class Supervisor {
|
|
|
3
3
|
lastRollback = 0;
|
|
4
4
|
rollingBack = false;
|
|
5
5
|
lastLKGWrite = 0;
|
|
6
|
+
lastDegradedNotify = 0;
|
|
6
7
|
timer = null;
|
|
7
8
|
constructor(deps) {
|
|
8
9
|
this.deps = deps;
|
|
9
10
|
}
|
|
10
11
|
async tick() {
|
|
11
12
|
const health = await this.deps.pollHealth();
|
|
13
|
+
// DEGRADED: http 200 but log has plugin error → report, notify, no rollback
|
|
14
|
+
if (health.degraded) {
|
|
15
|
+
const now = this.deps.getTime ? this.deps.getTime() : Date.now();
|
|
16
|
+
if (now - this.lastDegradedNotify < 60000)
|
|
17
|
+
return;
|
|
18
|
+
this.lastDegradedNotify = now;
|
|
19
|
+
try {
|
|
20
|
+
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
21
|
+
const reportPath = await this.deps.writeReport({ ts, health, action: `degraded — ${health.error ?? 'plugin'}` }).catch(() => '');
|
|
22
|
+
await this.deps.notify(`DEGRADED: ${health.error ?? 'plugin'} (report: ${reportPath})`).catch(() => { });
|
|
23
|
+
}
|
|
24
|
+
catch { }
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
12
27
|
if (health.up) {
|
|
13
28
|
// Throttle LKG writes to at most once per 5 minutes
|
|
14
29
|
const now = this.deps.getTime ? this.deps.getTime() : Date.now();
|