@volter/supercode-health 0.1.8 → 0.1.10
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/README.md +3 -2
- package/lib/sample.mjs +12 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,8 +51,9 @@ with the same outcome, the same expiry reason, ids and numbers taken out). A kin
|
|
|
51
51
|
`windowMin` (60) raises `supercode.failing:<kind>`; it clears when the window holds none of it.
|
|
52
52
|
|
|
53
53
|
`failures.json` in the health directory is the machine's ledger: the releases it ran, each from when it was first
|
|
54
|
-
seen running, and when each kind was first seen and under which release. The ledger's first run records
|
|
55
|
-
|
|
54
|
+
seen running, and when each kind was first seen and under which release. The ledger's first run records every
|
|
55
|
+
failure the machine's records hold (all of the slow log it keeps, every expiry), not only the window's, as seeded,
|
|
56
|
+
naming no release for it; a run that could not read them seeds at the next. A kind first seen under a release the ledger saw the machine
|
|
56
57
|
change to, after that change, is new with that release, and its alarm names that release's pull requests (the
|
|
57
58
|
release writes them into `@volter/supercode`'s `lib/release-changes.json`). With `"failures": { "sayOnChanges":
|
|
58
59
|
true }` in the config, the pack also comments such a kind once on each of those pull requests through `gh`, as the
|
package/lib/sample.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { cpus, homedir, loadavg } from 'node:os';
|
|
4
4
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
5
5
|
import { run } from './run.mjs';
|
|
6
|
+
import { daemonCall } from './mail.mjs';
|
|
6
7
|
import { rendererOrigins, originOf, localPort } from './chrome.mjs';
|
|
7
8
|
import { expiredFailures, failureSummary, keyFor, Ledger, runningRelease, sayOnChanges, slowFailures } from './failures.mjs';
|
|
8
9
|
import { healthDir } from './paths.mjs';
|
|
@@ -423,7 +424,9 @@ export class Sampler {
|
|
|
423
424
|
run(bin, ['teams', 'describe'], { timeoutMs: 15_000, env: this.env }).then((r) => ({ ...r, ms: Date.now() - t0 })),
|
|
424
425
|
run(bin, ['teams', 'launches', 'list'], { timeoutMs: 45_000, env: this.env }),
|
|
425
426
|
run(bin, ['teams', 'machines', 'list', '--json'], { timeoutMs: 20_000, env: this.env }),
|
|
426
|
-
|
|
427
|
+
// the mailbox's expiries are the daemon's own records (mail step 1): asked of it, never of the native binary
|
|
428
|
+
daemonCall('harness.v1.mail.expired', {}, { env: this.env, timeoutMs: 20_000 })
|
|
429
|
+
.then((answer) => ({ stdout: JSON.stringify(answer?.rows ?? []), error: null }), (error) => ({ stdout: '', error: error.message })),
|
|
427
430
|
]);
|
|
428
431
|
let described = null; try { described = JSON.parse(describe.stdout); } catch { /* the daemon did not answer */ }
|
|
429
432
|
let data = null; try { data = JSON.parse(status.stdout).data; } catch { /* unreadable */ }
|
|
@@ -474,6 +477,12 @@ export class Sampler {
|
|
|
474
477
|
const release = runningRelease();
|
|
475
478
|
this.ledger ??= new Ledger(join(healthDir(this.env), 'failures.json'));
|
|
476
479
|
this.ledger.running(release, now);
|
|
480
|
+
// the ledger's first run seeds from all the records the machine keeps, not the window alone: a failure that comes
|
|
481
|
+
// and goes (once a few hours) was here before anything watched, and is never named new with a later release
|
|
482
|
+
if (this.ledger.fresh && !unread.length) {
|
|
483
|
+
for (const [kind, seen] of slowFailures(this.env, 0)) this.ledger.seen(kind, seen.last, release);
|
|
484
|
+
for (const [kind, seen] of expiredFailures(expiries, 0)) this.ledger.seen(kind, seen.last, release);
|
|
485
|
+
}
|
|
477
486
|
const failing = [];
|
|
478
487
|
for (const [kind, seen] of kinds) {
|
|
479
488
|
const first = this.ledger.seen(kind, seen.last, release);
|
|
@@ -482,7 +491,8 @@ export class Sampler {
|
|
|
482
491
|
slow.observations.push({ key: keyFor(kind), family: 'supercode', def: fdef, value: seen.count, unit: `in ${fdef.windowMin} min`, summary, detail: { kind, firstRelease: first.firstRelease, seeded: first.seeded, newWithRelease: isNew, running: release?.version ?? null, prs: isNew ? first.changes?.prs ?? [] : [] } });
|
|
483
492
|
if (seen.count >= fdef.warn) failing.push({ kind, count: seen.count, first, summary });
|
|
484
493
|
}
|
|
485
|
-
|
|
494
|
+
// settled only by a cycle that read both records: one that could not read them has not seeded the ledger
|
|
495
|
+
if (!unread.length) this.ledger.settled();
|
|
486
496
|
slow.readings.supercode.failing = failing.map((f) => ({ kind: f.kind, count: f.count, firstRelease: f.first.firstRelease }));
|
|
487
497
|
await sayOnChanges({ failing, machine: this.machine, release, ledger: this.ledger, env: this.env, config: cfg });
|
|
488
498
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-health",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Optional machine pack: a cheap, deterministic probe of a machine's vitals that mails the machine's maintainer when a threshold is crossed. Each feature sits behind its own permission barrier.",
|
|
6
6
|
"license": "MIT",
|