@glassmkr/crucible 0.10.3 → 0.10.4
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/collect/__tests__/c1-c6.test.d.ts +1 -0
- package/dist/collect/__tests__/c1-c6.test.js +160 -0
- package/dist/collect/__tests__/c1-c6.test.js.map +1 -0
- package/dist/collect/edac.d.ts +2 -0
- package/dist/collect/edac.js +104 -0
- package/dist/collect/edac.js.map +1 -0
- package/dist/collect/hardware-raid.d.ts +2 -0
- package/dist/collect/hardware-raid.js +152 -0
- package/dist/collect/hardware-raid.js.map +1 -0
- package/dist/collect/psi.d.ts +20 -0
- package/dist/collect/psi.js +90 -0
- package/dist/collect/psi.js.map +1 -0
- package/dist/collect/reboot-evidence.d.ts +2 -0
- package/dist/collect/reboot-evidence.js +109 -0
- package/dist/collect/reboot-evidence.js.map +1 -0
- package/dist/collect/vmstat.d.ts +22 -0
- package/dist/collect/vmstat.js +94 -0
- package/dist/collect/vmstat.js.map +1 -0
- package/dist/collect/zfs.js +94 -0
- package/dist/collect/zfs.js.map +1 -1
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/types.d.ts +117 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Tests for C1-C6 collectors (v0.10.4, 2026-05-19).
|
|
2
|
+
//
|
|
3
|
+
// Most collectors hit real filesystem paths (/sys/devices/system/edac/,
|
|
4
|
+
// /proc/pressure/, /proc/vmstat, /var/crash/, etc.) so we can't fully
|
|
5
|
+
// integration-test them outside a Linux host with the expected
|
|
6
|
+
// capabilities. These tests cover the pure parser functions and the
|
|
7
|
+
// capability-gate behavior (collectors return null on hosts where the
|
|
8
|
+
// surface is absent).
|
|
9
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
10
|
+
import { __test_only as psiTest } from "../psi.js";
|
|
11
|
+
import { __test_only as vmstatTest, collectVmstat } from "../vmstat.js";
|
|
12
|
+
import { parseZpoolStatus } from "../zfs.js";
|
|
13
|
+
describe("C2 PSI: parsePsiLine", () => {
|
|
14
|
+
it("parses a complete PSI line", () => {
|
|
15
|
+
const r = psiTest.parsePsiLine("some avg10=0.06 avg60=0.04 avg300=0.05 total=12345");
|
|
16
|
+
expect(r).toEqual({ avg10: 0.06, avg60: 0.04, avg300: 0.05, total: 12345 });
|
|
17
|
+
});
|
|
18
|
+
it("returns null on malformed input", () => {
|
|
19
|
+
expect(psiTest.parsePsiLine("some avg10=0.06")).toBeNull();
|
|
20
|
+
expect(psiTest.parsePsiLine("garbage")).toBeNull();
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe("C2 PSI: parsePsiFile", () => {
|
|
24
|
+
it("captures both some and full lines (memory/io shape)", () => {
|
|
25
|
+
const out = psiTest.parsePsiFile("some avg10=1.0 avg60=2.0 avg300=3.0 total=100\nfull avg10=0.5 avg60=1.0 avg300=1.5 total=50\n");
|
|
26
|
+
expect(out?.some.avg10).toBe(1.0);
|
|
27
|
+
expect(out?.full?.avg60).toBe(1.0);
|
|
28
|
+
});
|
|
29
|
+
it("works when only 'some' is present (cpu shape)", () => {
|
|
30
|
+
const out = psiTest.parsePsiFile("some avg10=0.0 avg60=0.0 avg300=0.0 total=0\n");
|
|
31
|
+
expect(out?.some.avg10).toBe(0.0);
|
|
32
|
+
expect(out?.full).toBeUndefined();
|
|
33
|
+
});
|
|
34
|
+
it("returns null on empty input", () => {
|
|
35
|
+
expect(psiTest.parsePsiFile("")).toBeNull();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
describe("C3 vmstat: collectVmstat delta tracking", () => {
|
|
39
|
+
// Note: vmstat reads real /proc/vmstat on the test runner; on a
|
|
40
|
+
// dev macOS host the file doesn't exist so collectVmstat returns
|
|
41
|
+
// null cleanly. This is sufficient evidence for the capability
|
|
42
|
+
// gate; behavioral delta tests live in the e2e tier.
|
|
43
|
+
beforeEach(() => {
|
|
44
|
+
vmstatTest.resetForTests();
|
|
45
|
+
});
|
|
46
|
+
it("returns null on a host without /proc/vmstat", () => {
|
|
47
|
+
// On macOS / non-Linux, readProcFile returns null and the
|
|
48
|
+
// collector returns null cleanly.
|
|
49
|
+
const r = collectVmstat();
|
|
50
|
+
// We accept either: null (non-Linux) or a snapshot with null
|
|
51
|
+
// rates (Linux but first call). Both prove the capability gate
|
|
52
|
+
// shape.
|
|
53
|
+
if (r !== null) {
|
|
54
|
+
expect(r.pswpin_rate).toBeNull();
|
|
55
|
+
expect(r.pswpout_rate).toBeNull();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("C6 ZFS: parseZpoolStatus extended vdev fields", () => {
|
|
60
|
+
it("parses a raidz2 pool with a mirrored SLOG and L2ARC", () => {
|
|
61
|
+
const status = [
|
|
62
|
+
" pool: tank",
|
|
63
|
+
" state: ONLINE",
|
|
64
|
+
" scan: scrub repaired 0B in 00:00:30 with 0 errors on Sun Oct 1 02:30:00 2026",
|
|
65
|
+
"config:",
|
|
66
|
+
"",
|
|
67
|
+
"\tNAME STATE READ WRITE CKSUM",
|
|
68
|
+
"\ttank ONLINE 0 0 0",
|
|
69
|
+
"\t raidz2-0 ONLINE 0 0 0",
|
|
70
|
+
"\t sda ONLINE 0 0 0",
|
|
71
|
+
"\t sdb ONLINE 0 0 0",
|
|
72
|
+
"\t sdc ONLINE 0 0 0",
|
|
73
|
+
"\t sdd ONLINE 0 0 0",
|
|
74
|
+
"logs",
|
|
75
|
+
"\t mirror-1 ONLINE 0 0 0",
|
|
76
|
+
"\t nvme0n1p2 ONLINE 0 0 0",
|
|
77
|
+
"\t nvme1n1p2 ONLINE 0 0 0",
|
|
78
|
+
"cache",
|
|
79
|
+
"\t nvme0n1p3 ONLINE 0 0 0",
|
|
80
|
+
"",
|
|
81
|
+
"errors: No known data errors",
|
|
82
|
+
].join("\n");
|
|
83
|
+
const pools = parseZpoolStatus(status);
|
|
84
|
+
expect(pools).toHaveLength(1);
|
|
85
|
+
const p = pools[0];
|
|
86
|
+
expect(p.name).toBe("tank");
|
|
87
|
+
expect(p.state).toBe("ONLINE");
|
|
88
|
+
expect(p.vdevs).toHaveLength(1);
|
|
89
|
+
expect(p.vdevs[0].name).toBe("raidz2-0");
|
|
90
|
+
expect(p.vdevs[0].redundancy_class).toBe("raidz2");
|
|
91
|
+
expect(p.vdevs[0].degraded_disks_count).toBe(0);
|
|
92
|
+
expect(p.slog_vdevs).toHaveLength(1);
|
|
93
|
+
expect(p.slog_vdevs[0].name).toBe("mirror-1");
|
|
94
|
+
expect(p.l2arc_vdevs).toHaveLength(1);
|
|
95
|
+
expect(p.l2arc_vdevs[0].name).toBe("nvme0n1p3");
|
|
96
|
+
});
|
|
97
|
+
it("classifies raidz1 / raidz3 / mirror correctly", () => {
|
|
98
|
+
const status = [
|
|
99
|
+
" pool: a",
|
|
100
|
+
" state: ONLINE",
|
|
101
|
+
"config:",
|
|
102
|
+
"\tNAME STATE",
|
|
103
|
+
"\ta ONLINE",
|
|
104
|
+
"\t raidz1-0 ONLINE",
|
|
105
|
+
"\t s1 ONLINE",
|
|
106
|
+
"\t s2 ONLINE",
|
|
107
|
+
" pool: b",
|
|
108
|
+
" state: ONLINE",
|
|
109
|
+
"config:",
|
|
110
|
+
"\tNAME STATE",
|
|
111
|
+
"\tb ONLINE",
|
|
112
|
+
"\t raidz3-0 ONLINE",
|
|
113
|
+
"\t s1 ONLINE",
|
|
114
|
+
" pool: c",
|
|
115
|
+
" state: ONLINE",
|
|
116
|
+
"config:",
|
|
117
|
+
"\tNAME STATE",
|
|
118
|
+
"\tc ONLINE",
|
|
119
|
+
"\t mirror-0 ONLINE",
|
|
120
|
+
"\t s1 ONLINE",
|
|
121
|
+
].join("\n");
|
|
122
|
+
const pools = parseZpoolStatus(status);
|
|
123
|
+
expect(pools.map((p) => p.vdevs[0]?.redundancy_class)).toEqual([
|
|
124
|
+
"raidz1",
|
|
125
|
+
"raidz3",
|
|
126
|
+
"mirror",
|
|
127
|
+
]);
|
|
128
|
+
});
|
|
129
|
+
it("counts degraded child devices on a DEGRADED vdev", () => {
|
|
130
|
+
const status = [
|
|
131
|
+
" pool: tank",
|
|
132
|
+
" state: DEGRADED",
|
|
133
|
+
"config:",
|
|
134
|
+
"\tNAME STATE",
|
|
135
|
+
"\ttank DEGRADED",
|
|
136
|
+
"\t raidz2-0 DEGRADED",
|
|
137
|
+
"\t sda ONLINE",
|
|
138
|
+
"\t sdb FAULTED",
|
|
139
|
+
"\t sdc ONLINE",
|
|
140
|
+
"\t sdd ONLINE",
|
|
141
|
+
"",
|
|
142
|
+
"errors: No known data errors",
|
|
143
|
+
].join("\n");
|
|
144
|
+
const pools = parseZpoolStatus(status);
|
|
145
|
+
expect(pools[0].vdevs[0].degraded_disks_count).toBe(1);
|
|
146
|
+
});
|
|
147
|
+
it("treats a single-device top-level vdev as stripe (no redundancy)", () => {
|
|
148
|
+
const status = [
|
|
149
|
+
" pool: scratch",
|
|
150
|
+
" state: ONLINE",
|
|
151
|
+
"config:",
|
|
152
|
+
"\tNAME STATE",
|
|
153
|
+
"\tscratch ONLINE",
|
|
154
|
+
"\t sda ONLINE",
|
|
155
|
+
].join("\n");
|
|
156
|
+
const pools = parseZpoolStatus(status);
|
|
157
|
+
expect(pools[0].vdevs[0].redundancy_class).toBe("stripe");
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
//# sourceMappingURL=c1-c6.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c1-c6.test.js","sourceRoot":"","sources":["../../../src/collect/__tests__/c1-c6.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// EDAC (Error Detection and Correction) counter collection.
|
|
2
|
+
//
|
|
3
|
+
// Per CC_SPEC_FORGE_FOLLOWUP_C1_C6_ACTIVATION_2026-05-19.md (C1).
|
|
4
|
+
//
|
|
5
|
+
// Kernel surface: /sys/devices/system/edac/mc/mcN/{ce_count,ue_count}
|
|
6
|
+
// ce_count = correctable errors (memory controller saw and fixed)
|
|
7
|
+
// ue_count = uncorrectable errors (memory error couldn't be fixed;
|
|
8
|
+
// kernel may have killed the process or panicked)
|
|
9
|
+
//
|
|
10
|
+
// Per-DIMM granularity: /sys/devices/system/edac/mc/mcN/dimmM/
|
|
11
|
+
// dimm_ce_count, dimm_ue_count, dimm_label, dimm_location, size
|
|
12
|
+
//
|
|
13
|
+
// Capability gate: if no `mcN` directories exist under
|
|
14
|
+
// /sys/devices/system/edac/mc/, EDAC is not loaded (no memory
|
|
15
|
+
// controller driver compiled in or no DIMMs reporting) and this
|
|
16
|
+
// collector returns null. The dashboard ecc_errors evaluator falls
|
|
17
|
+
// back to its IPMI-SEL path.
|
|
18
|
+
//
|
|
19
|
+
// On hosts where EDAC is loaded but counters stay at zero, this
|
|
20
|
+
// collector emits zero counters — that's the correct baseline.
|
|
21
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
22
|
+
import { join } from "node:path";
|
|
23
|
+
const EDAC_ROOT = "/sys/devices/system/edac/mc";
|
|
24
|
+
function readUint(path) {
|
|
25
|
+
try {
|
|
26
|
+
const s = readFileSync(path, "utf8").trim();
|
|
27
|
+
if (!/^\d+$/.test(s))
|
|
28
|
+
return null;
|
|
29
|
+
return parseInt(s, 10);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function readString(path) {
|
|
36
|
+
try {
|
|
37
|
+
return readFileSync(path, "utf8").trim();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function listMcDirs() {
|
|
44
|
+
try {
|
|
45
|
+
return readdirSync(EDAC_ROOT)
|
|
46
|
+
.filter((n) => /^mc\d+$/.test(n))
|
|
47
|
+
.map((n) => join(EDAC_ROOT, n));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function listDimmDirs(mcPath) {
|
|
54
|
+
try {
|
|
55
|
+
return readdirSync(mcPath)
|
|
56
|
+
.filter((n) => /^dimm\d+$/.test(n) || /^rank\d+$/.test(n))
|
|
57
|
+
.map((n) => join(mcPath, n));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function collectDimm(dimmPath) {
|
|
64
|
+
const ce = readUint(join(dimmPath, "dimm_ce_count"));
|
|
65
|
+
const ue = readUint(join(dimmPath, "dimm_ue_count"));
|
|
66
|
+
if (ce === null && ue === null)
|
|
67
|
+
return null;
|
|
68
|
+
const label = readString(join(dimmPath, "dimm_label"));
|
|
69
|
+
const location = readString(join(dimmPath, "dimm_location"));
|
|
70
|
+
const sizeStr = readString(join(dimmPath, "size"));
|
|
71
|
+
const sizeMb = sizeStr && /^\d+$/.test(sizeStr) ? parseInt(sizeStr, 10) : null;
|
|
72
|
+
return {
|
|
73
|
+
label: label ?? "",
|
|
74
|
+
location: location ?? "",
|
|
75
|
+
size_mb: sizeMb,
|
|
76
|
+
ce_count: ce ?? 0,
|
|
77
|
+
ue_count: ue ?? 0,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export function collectEdac() {
|
|
81
|
+
const mcDirs = listMcDirs();
|
|
82
|
+
if (mcDirs.length === 0)
|
|
83
|
+
return null;
|
|
84
|
+
let totalCe = 0;
|
|
85
|
+
let totalUe = 0;
|
|
86
|
+
const dimms = [];
|
|
87
|
+
for (const mc of mcDirs) {
|
|
88
|
+
const ce = readUint(join(mc, "ce_count")) ?? 0;
|
|
89
|
+
const ue = readUint(join(mc, "ue_count")) ?? 0;
|
|
90
|
+
totalCe += ce;
|
|
91
|
+
totalUe += ue;
|
|
92
|
+
for (const dimm of listDimmDirs(mc)) {
|
|
93
|
+
const d = collectDimm(dimm);
|
|
94
|
+
if (d)
|
|
95
|
+
dimms.push(d);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
edac_corrected_total: totalCe,
|
|
100
|
+
edac_uncorrected_total: totalUe,
|
|
101
|
+
dimms,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=edac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edac.js","sourceRoot":"","sources":["../../src/collect/edac.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// Hardware RAID controller scraping.
|
|
2
|
+
//
|
|
3
|
+
// Per CC_SPEC_FORGE_FOLLOWUP_C1_C6_ACTIVATION_2026-05-19.md (C5).
|
|
4
|
+
//
|
|
5
|
+
// Detects four vendor CLIs:
|
|
6
|
+
// - perccli (Dell PERC)
|
|
7
|
+
// - ssacli (HPE Smart Array)
|
|
8
|
+
// - storcli (LSI / Broadcom MegaRAID)
|
|
9
|
+
// - arcconf (Adaptec)
|
|
10
|
+
//
|
|
11
|
+
// For each installed CLI, queries the controller state and returns
|
|
12
|
+
// a normalized HardwareRaidController. The vendor-specific output
|
|
13
|
+
// formats vary considerably; this module's parsers are intentionally
|
|
14
|
+
// conservative — they extract a state string ("Optimal", "Degraded",
|
|
15
|
+
// etc.) plus an optional degraded_disks counter when the vendor output
|
|
16
|
+
// makes it easy to find. The dashboard's raid_degraded evaluator pages
|
|
17
|
+
// on any state != "Optimal"; that's the contract.
|
|
18
|
+
//
|
|
19
|
+
// Implementation scope (2026-05-19): perccli + storcli parsers are
|
|
20
|
+
// best-effort because the validation fleet has no hardware RAID
|
|
21
|
+
// controllers to verify against. Real parsing precision lands in
|
|
22
|
+
// follow-up PRs as customers with each vendor surface. The framework
|
|
23
|
+
// here ensures:
|
|
24
|
+
// - empty controllers[] on hosts without any vendor CLI (capability
|
|
25
|
+
// gate; dashboard rule no-ops),
|
|
26
|
+
// - empty controllers[] on hosts with the CLI but no controllers
|
|
27
|
+
// present (rare configurations).
|
|
28
|
+
//
|
|
29
|
+
// The dashboard's mdadm path is unaffected by this module.
|
|
30
|
+
import { run } from "../lib/exec.js";
|
|
31
|
+
async function hasCli(name) {
|
|
32
|
+
const out = await run("which", [name], 2000);
|
|
33
|
+
return !!(out && out.trim());
|
|
34
|
+
}
|
|
35
|
+
async function scrapePerccli() {
|
|
36
|
+
// perccli /c0 show all J — JSON output for controller 0.
|
|
37
|
+
// Multi-controller hosts are rare; query c0 only and let follow-ups
|
|
38
|
+
// expand if a customer surfaces multi-controller hardware.
|
|
39
|
+
const raw = await run("perccli", ["/c0", "show", "all", "J"], 10000);
|
|
40
|
+
if (!raw)
|
|
41
|
+
return [];
|
|
42
|
+
try {
|
|
43
|
+
const obj = JSON.parse(raw);
|
|
44
|
+
const ctrlList = obj?.Controllers ?? [];
|
|
45
|
+
return ctrlList.map((c) => ({
|
|
46
|
+
vendor: "dell",
|
|
47
|
+
controller_id: String(c?.["Command Status"]?.Controller ?? "0"),
|
|
48
|
+
state: String(c?.["Response Data"]?.["Status"]?.["Controller Status"] ?? "Unknown"),
|
|
49
|
+
degraded_disks: null,
|
|
50
|
+
raw_summary: null,
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Output wasn't JSON (older perccli, or controller missing).
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function scrapeStorcli() {
|
|
59
|
+
const raw = await run("storcli", ["/call", "show", "all", "J"], 10000);
|
|
60
|
+
if (!raw)
|
|
61
|
+
return [];
|
|
62
|
+
try {
|
|
63
|
+
const obj = JSON.parse(raw);
|
|
64
|
+
const ctrlList = obj?.Controllers ?? [];
|
|
65
|
+
return ctrlList.map((c) => ({
|
|
66
|
+
vendor: "lsi",
|
|
67
|
+
controller_id: String(c?.["Command Status"]?.Controller ?? "?"),
|
|
68
|
+
state: String(c?.["Response Data"]?.["Status"]?.["Controller Status"] ?? "Unknown"),
|
|
69
|
+
degraded_disks: null,
|
|
70
|
+
raw_summary: null,
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function scrapeSsacli() {
|
|
78
|
+
// ssacli ctrl all show — text format. Conservative: extract one
|
|
79
|
+
// line per "in slot X" entry; status reported on a "Controller Status"
|
|
80
|
+
// line. Real parsing lands when an HPE customer surfaces.
|
|
81
|
+
const raw = await run("ssacli", ["ctrl", "all", "show", "status"], 10000);
|
|
82
|
+
if (!raw)
|
|
83
|
+
return [];
|
|
84
|
+
const lines = raw.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
85
|
+
const controllers = [];
|
|
86
|
+
let pending = null;
|
|
87
|
+
for (const line of lines) {
|
|
88
|
+
const slotMatch = line.match(/in Slot (\S+)/);
|
|
89
|
+
if (slotMatch) {
|
|
90
|
+
if (pending)
|
|
91
|
+
controllers.push(pendingToController(pending));
|
|
92
|
+
pending = { slot: slotMatch[1], status: "Unknown" };
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const statusMatch = line.match(/Controller Status:\s*(.+)/);
|
|
96
|
+
if (statusMatch && pending)
|
|
97
|
+
pending.status = statusMatch[1].trim();
|
|
98
|
+
}
|
|
99
|
+
if (pending)
|
|
100
|
+
controllers.push(pendingToController(pending));
|
|
101
|
+
return controllers;
|
|
102
|
+
}
|
|
103
|
+
function pendingToController(p) {
|
|
104
|
+
return {
|
|
105
|
+
vendor: "hpe",
|
|
106
|
+
controller_id: p.slot,
|
|
107
|
+
state: p.status,
|
|
108
|
+
degraded_disks: null,
|
|
109
|
+
raw_summary: null,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
async function scrapeArcconf() {
|
|
113
|
+
// arcconf has no JSON mode. Best-effort: detect controllers via
|
|
114
|
+
// `arcconf list` and surface a placeholder state. Real parser
|
|
115
|
+
// for Adaptec lands when a customer surfaces.
|
|
116
|
+
const raw = await run("arcconf", ["list"], 10000);
|
|
117
|
+
if (!raw)
|
|
118
|
+
return [];
|
|
119
|
+
const controllers = [];
|
|
120
|
+
for (const line of raw.split("\n")) {
|
|
121
|
+
const m = line.match(/Controller (\d+):/i);
|
|
122
|
+
if (m) {
|
|
123
|
+
controllers.push({
|
|
124
|
+
vendor: "adaptec",
|
|
125
|
+
controller_id: m[1],
|
|
126
|
+
state: "Unknown",
|
|
127
|
+
degraded_disks: null,
|
|
128
|
+
raw_summary: "arcconf parsing pending — surface a customer with Adaptec hardware",
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return controllers;
|
|
133
|
+
}
|
|
134
|
+
export async function collectHardwareRaid() {
|
|
135
|
+
const hasPerccli = await hasCli("perccli");
|
|
136
|
+
const hasStorcli = await hasCli("storcli");
|
|
137
|
+
const hasSsacli = await hasCli("ssacli");
|
|
138
|
+
const hasArcconf = await hasCli("arcconf");
|
|
139
|
+
if (!hasPerccli && !hasStorcli && !hasSsacli && !hasArcconf)
|
|
140
|
+
return null;
|
|
141
|
+
const controllers = [];
|
|
142
|
+
if (hasPerccli)
|
|
143
|
+
controllers.push(...(await scrapePerccli()));
|
|
144
|
+
if (hasStorcli)
|
|
145
|
+
controllers.push(...(await scrapeStorcli()));
|
|
146
|
+
if (hasSsacli)
|
|
147
|
+
controllers.push(...(await scrapeSsacli()));
|
|
148
|
+
if (hasArcconf)
|
|
149
|
+
controllers.push(...(await scrapeArcconf()));
|
|
150
|
+
return { controllers };
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=hardware-raid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardware-raid.js","sourceRoot":"","sources":["../../src/collect/hardware-raid.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PsiResource, PsiSnapshot } from "../lib/types.js";
|
|
2
|
+
declare function parsePsiLine(line: string): PsiResource | null;
|
|
3
|
+
interface PsiFile {
|
|
4
|
+
some: PsiResource;
|
|
5
|
+
/** Only present for memory + io; cpu has no "full" line in current kernels. */
|
|
6
|
+
full?: PsiResource;
|
|
7
|
+
}
|
|
8
|
+
declare function parsePsiFile(contents: string): PsiFile | null;
|
|
9
|
+
/**
|
|
10
|
+
* Collect PSI for all three resources. Returns null if /proc/pressure/
|
|
11
|
+
* is unavailable (older kernel or PSI disabled). Per resource: returns
|
|
12
|
+
* undefined if that specific file is unreadable (rare; usually all
|
|
13
|
+
* three present or none).
|
|
14
|
+
*/
|
|
15
|
+
export declare function collectPsi(): PsiSnapshot | null;
|
|
16
|
+
export declare const __test_only: {
|
|
17
|
+
parsePsiLine: typeof parsePsiLine;
|
|
18
|
+
parsePsiFile: typeof parsePsiFile;
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// PSI (Pressure Stall Information) collection.
|
|
2
|
+
//
|
|
3
|
+
// Reads /proc/pressure/{cpu,memory,io}. The kernel exposes this on
|
|
4
|
+
// 4.20+ when PSI is compiled in (most modern distros). Older kernels
|
|
5
|
+
// or those built without `CONFIG_PSI=y` return an empty result; the
|
|
6
|
+
// snapshot then omits the `psi` field entirely, and the dashboard
|
|
7
|
+
// alert evaluator's capability gates treat that as `available: false`.
|
|
8
|
+
//
|
|
9
|
+
// Per CC_SPEC_FORGE_FOLLOWUP_C1_C6_ACTIVATION_2026-05-19.md (C2).
|
|
10
|
+
//
|
|
11
|
+
// File format (all three resources share the same shape):
|
|
12
|
+
//
|
|
13
|
+
// some avg10=0.06 avg60=0.04 avg300=0.05 total=12345
|
|
14
|
+
// full avg10=0.00 avg60=0.00 avg300=0.00 total=678
|
|
15
|
+
//
|
|
16
|
+
// "some" = % of time at least one task was stalled on the resource.
|
|
17
|
+
// "full" = % of time ALL non-idle tasks were stalled (only present
|
|
18
|
+
// for memory and io; cpu has only "some" per kernel docs).
|
|
19
|
+
// "total" = cumulative microseconds since boot.
|
|
20
|
+
import { readProcFile } from "../lib/parse.js";
|
|
21
|
+
function parsePsiLine(line) {
|
|
22
|
+
// Expect: "some avg10=N avg60=N avg300=N total=N"
|
|
23
|
+
const parts = line.trim().split(/\s+/);
|
|
24
|
+
if (parts.length < 5)
|
|
25
|
+
return null;
|
|
26
|
+
const out = {};
|
|
27
|
+
for (const part of parts.slice(1)) {
|
|
28
|
+
const [k, v] = part.split("=");
|
|
29
|
+
if (k === "avg10")
|
|
30
|
+
out.avg10 = parseFloat(v);
|
|
31
|
+
else if (k === "avg60")
|
|
32
|
+
out.avg60 = parseFloat(v);
|
|
33
|
+
else if (k === "avg300")
|
|
34
|
+
out.avg300 = parseFloat(v);
|
|
35
|
+
else if (k === "total")
|
|
36
|
+
out.total = parseInt(v, 10);
|
|
37
|
+
}
|
|
38
|
+
if (out.avg10 === undefined ||
|
|
39
|
+
out.avg60 === undefined ||
|
|
40
|
+
out.avg300 === undefined ||
|
|
41
|
+
out.total === undefined) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
function parsePsiFile(contents) {
|
|
47
|
+
let some = null;
|
|
48
|
+
let full = null;
|
|
49
|
+
for (const line of contents.split("\n")) {
|
|
50
|
+
if (line.startsWith("some "))
|
|
51
|
+
some = parsePsiLine(line);
|
|
52
|
+
else if (line.startsWith("full "))
|
|
53
|
+
full = parsePsiLine(line);
|
|
54
|
+
}
|
|
55
|
+
if (!some)
|
|
56
|
+
return null;
|
|
57
|
+
return full ? { some, full } : { some };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Collect PSI for all three resources. Returns null if /proc/pressure/
|
|
61
|
+
* is unavailable (older kernel or PSI disabled). Per resource: returns
|
|
62
|
+
* undefined if that specific file is unreadable (rare; usually all
|
|
63
|
+
* three present or none).
|
|
64
|
+
*/
|
|
65
|
+
export function collectPsi() {
|
|
66
|
+
const cpu = readProcFile("/proc/pressure/cpu");
|
|
67
|
+
const memory = readProcFile("/proc/pressure/memory");
|
|
68
|
+
const io = readProcFile("/proc/pressure/io");
|
|
69
|
+
if (!cpu && !memory && !io)
|
|
70
|
+
return null;
|
|
71
|
+
const out = {};
|
|
72
|
+
if (cpu) {
|
|
73
|
+
const parsed = parsePsiFile(cpu);
|
|
74
|
+
if (parsed)
|
|
75
|
+
out.cpu = parsed;
|
|
76
|
+
}
|
|
77
|
+
if (memory) {
|
|
78
|
+
const parsed = parsePsiFile(memory);
|
|
79
|
+
if (parsed)
|
|
80
|
+
out.memory = parsed;
|
|
81
|
+
}
|
|
82
|
+
if (io) {
|
|
83
|
+
const parsed = parsePsiFile(io);
|
|
84
|
+
if (parsed)
|
|
85
|
+
out.io = parsed;
|
|
86
|
+
}
|
|
87
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
88
|
+
}
|
|
89
|
+
export const __test_only = { parsePsiLine, parsePsiFile };
|
|
90
|
+
//# sourceMappingURL=psi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"psi.js","sourceRoot":"","sources":["../../src/collect/psi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Reboot-evidence collection: pstore + kdump + wtmp.
|
|
2
|
+
//
|
|
3
|
+
// Per CC_SPEC_FORGE_FOLLOWUP_C1_C6_ACTIVATION_2026-05-19.md (C4).
|
|
4
|
+
//
|
|
5
|
+
// Three independent signals corroborate a reboot:
|
|
6
|
+
//
|
|
7
|
+
// - /sys/fs/pstore/ — persistent storage records the kernel
|
|
8
|
+
// wrote during the previous shutdown / panic. Presence of
|
|
9
|
+
// dmesg-* records indicates the prior kernel left a forensic
|
|
10
|
+
// trail before halting.
|
|
11
|
+
//
|
|
12
|
+
// - /var/crash/ — kdump's vmcore dump from the prior
|
|
13
|
+
// kernel panic. Path varies by distro; check the standard
|
|
14
|
+
// location plus the systemd default.
|
|
15
|
+
//
|
|
16
|
+
// - wtmp — accounting log. `last reboot -F` shows
|
|
17
|
+
// `reboot system boot ...` events plus optional `shutdown`
|
|
18
|
+
// events that preceded them. A clean shutdown (poweroff/halt)
|
|
19
|
+
// produces a `shutdown` record; a hard reset or power loss
|
|
20
|
+
// leaves only the boot record with no prior shutdown.
|
|
21
|
+
//
|
|
22
|
+
// The dashboard's unexpected_reboot rule consumes this to enrich
|
|
23
|
+
// the alert's evidence; the kernel_panic_detected rule (C4
|
|
24
|
+
// follow-up) consumes pstore_present + vmcore_present to fire its
|
|
25
|
+
// own P0 alert.
|
|
26
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
27
|
+
import { run } from "../lib/exec.js";
|
|
28
|
+
const PSTORE_PATH = "/sys/fs/pstore";
|
|
29
|
+
const VAR_CRASH_PATH = "/var/crash";
|
|
30
|
+
function pstoreRecords() {
|
|
31
|
+
try {
|
|
32
|
+
const entries = readdirSync(PSTORE_PATH);
|
|
33
|
+
return entries.filter((n) => n.startsWith("dmesg-") || n.startsWith("console-") || n.startsWith("ftrace-"));
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function vmcorePresent() {
|
|
40
|
+
try {
|
|
41
|
+
if (!existsSync(VAR_CRASH_PATH))
|
|
42
|
+
return false;
|
|
43
|
+
// /var/crash typically contains dated subdirectories per crash
|
|
44
|
+
// (e.g. /var/crash/2026-05-13-04:22:54/vmcore). Recursive check
|
|
45
|
+
// would be expensive; we just check if any subdirectory contains
|
|
46
|
+
// a file named `vmcore` or `vmcore.flat`.
|
|
47
|
+
const top = readdirSync(VAR_CRASH_PATH);
|
|
48
|
+
for (const sub of top) {
|
|
49
|
+
try {
|
|
50
|
+
const subPath = `${VAR_CRASH_PATH}/${sub}`;
|
|
51
|
+
const st = statSync(subPath);
|
|
52
|
+
if (!st.isDirectory())
|
|
53
|
+
continue;
|
|
54
|
+
const children = readdirSync(subPath);
|
|
55
|
+
if (children.some((c) => c === "vmcore" || c === "vmcore.flat" || c.startsWith("vmcore."))) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Skip unreadable subdirs.
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function readWtmp() {
|
|
70
|
+
const output = await run("last", ["reboot", "-F"], 5000);
|
|
71
|
+
if (!output) {
|
|
72
|
+
return { last_reboot_raw: null, prior_shutdown_clean: false };
|
|
73
|
+
}
|
|
74
|
+
const lines = output.split("\n").filter((l) => l.trim().length > 0);
|
|
75
|
+
// The first non-empty line is the most recent reboot record.
|
|
76
|
+
const lastReboot = lines[0] ?? null;
|
|
77
|
+
// Look for a `shutdown` record between the most recent reboot and
|
|
78
|
+
// the second-most-recent reboot. `last -F` interleaves shutdown
|
|
79
|
+
// records when present; on a clean shutdown they sit immediately
|
|
80
|
+
// before the boot record.
|
|
81
|
+
const shutdownOutput = await run("last", ["shutdown", "-F"], 5000);
|
|
82
|
+
let priorShutdownClean = false;
|
|
83
|
+
if (shutdownOutput && lastReboot) {
|
|
84
|
+
// Extract a date marker from the lastReboot line; if any shutdown
|
|
85
|
+
// record predates this reboot by <= 5 minutes, treat as clean.
|
|
86
|
+
// Conservative: if any shutdown record exists in the wtmp at all,
|
|
87
|
+
// assume the most recent one was clean. Defensive against parsing
|
|
88
|
+
// glitches; refined by the dashboard evaluator.
|
|
89
|
+
const sLines = shutdownOutput.split("\n").filter((l) => l.trim().length > 0 && l.startsWith("shutdown"));
|
|
90
|
+
priorShutdownClean = sLines.length > 0;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
last_reboot_raw: lastReboot,
|
|
94
|
+
prior_shutdown_clean: priorShutdownClean,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export async function collectRebootEvidence() {
|
|
98
|
+
const records = pstoreRecords();
|
|
99
|
+
const vmcore = vmcorePresent();
|
|
100
|
+
const wtmp = await readWtmp();
|
|
101
|
+
return {
|
|
102
|
+
pstore_present: records.length > 0,
|
|
103
|
+
pstore_record_count: records.length,
|
|
104
|
+
vmcore_present: vmcore,
|
|
105
|
+
wtmp_reboot_record: wtmp.last_reboot_raw,
|
|
106
|
+
prior_shutdown_clean: wtmp.prior_shutdown_clean,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=reboot-evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reboot-evidence.js","sourceRoot":"","sources":["../../src/collect/reboot-evidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { VmstatSnapshot } from "../lib/types.js";
|
|
2
|
+
interface VmstatCounters {
|
|
3
|
+
pswpin: number;
|
|
4
|
+
pswpout: number;
|
|
5
|
+
capturedAtMs: number;
|
|
6
|
+
}
|
|
7
|
+
declare function parseVmstat(): VmstatCounters | null;
|
|
8
|
+
/**
|
|
9
|
+
* Collect swap-in/swap-out rates. First-snapshot returns null rates
|
|
10
|
+
* (no prior counter to delta against); subsequent calls compute
|
|
11
|
+
* deltas per second across the elapsed snapshot interval.
|
|
12
|
+
*
|
|
13
|
+
* Counter resets (host reboot, /proc/vmstat counter rollover) are
|
|
14
|
+
* detected when current < previous; in that case we treat the
|
|
15
|
+
* current call as a fresh baseline and return null rates.
|
|
16
|
+
*/
|
|
17
|
+
export declare function collectVmstat(): VmstatSnapshot | null;
|
|
18
|
+
export declare const __test_only: {
|
|
19
|
+
parseVmstat: typeof parseVmstat;
|
|
20
|
+
resetForTests: () => void;
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// /proc/vmstat collection for swap-in/swap-out rates.
|
|
2
|
+
//
|
|
3
|
+
// Per CC_SPEC_FORGE_FOLLOWUP_C1_C6_ACTIVATION_2026-05-19.md (C3).
|
|
4
|
+
//
|
|
5
|
+
// Output: per-second rates derived from cumulative counter deltas
|
|
6
|
+
// across snapshot intervals. The first snapshot returns null rates
|
|
7
|
+
// because there's no prior counter to delta against.
|
|
8
|
+
//
|
|
9
|
+
// Delta pattern matches src/collect/io-latency.ts: a module-level Map
|
|
10
|
+
// holds the previous cumulative counter. On each call we compute
|
|
11
|
+
// (current - previous) / elapsed_seconds. Stale entries (host that
|
|
12
|
+
// rebooted, counter went backwards) are detected and discarded.
|
|
13
|
+
import { readProcFile } from "../lib/parse.js";
|
|
14
|
+
let previous = null;
|
|
15
|
+
function parseVmstat() {
|
|
16
|
+
const raw = readProcFile("/proc/vmstat");
|
|
17
|
+
if (!raw)
|
|
18
|
+
return null;
|
|
19
|
+
let pswpin;
|
|
20
|
+
let pswpout;
|
|
21
|
+
for (const line of raw.split("\n")) {
|
|
22
|
+
const [k, v] = line.trim().split(/\s+/);
|
|
23
|
+
if (k === "pswpin")
|
|
24
|
+
pswpin = Number(v);
|
|
25
|
+
else if (k === "pswpout")
|
|
26
|
+
pswpout = Number(v);
|
|
27
|
+
if (pswpin !== undefined && pswpout !== undefined)
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
if (pswpin === undefined || pswpout === undefined)
|
|
31
|
+
return null;
|
|
32
|
+
return { pswpin, pswpout, capturedAtMs: Date.now() };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Collect swap-in/swap-out rates. First-snapshot returns null rates
|
|
36
|
+
* (no prior counter to delta against); subsequent calls compute
|
|
37
|
+
* deltas per second across the elapsed snapshot interval.
|
|
38
|
+
*
|
|
39
|
+
* Counter resets (host reboot, /proc/vmstat counter rollover) are
|
|
40
|
+
* detected when current < previous; in that case we treat the
|
|
41
|
+
* current call as a fresh baseline and return null rates.
|
|
42
|
+
*/
|
|
43
|
+
export function collectVmstat() {
|
|
44
|
+
const current = parseVmstat();
|
|
45
|
+
if (!current)
|
|
46
|
+
return null;
|
|
47
|
+
if (!previous) {
|
|
48
|
+
previous = current;
|
|
49
|
+
return {
|
|
50
|
+
pswpin_total: current.pswpin,
|
|
51
|
+
pswpout_total: current.pswpout,
|
|
52
|
+
pswpin_rate: null,
|
|
53
|
+
pswpout_rate: null,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const elapsedSeconds = (current.capturedAtMs - previous.capturedAtMs) / 1000;
|
|
57
|
+
if (elapsedSeconds <= 0) {
|
|
58
|
+
return {
|
|
59
|
+
pswpin_total: current.pswpin,
|
|
60
|
+
pswpout_total: current.pswpout,
|
|
61
|
+
pswpin_rate: null,
|
|
62
|
+
pswpout_rate: null,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const inDelta = current.pswpin - previous.pswpin;
|
|
66
|
+
const outDelta = current.pswpout - previous.pswpout;
|
|
67
|
+
// Counter went backward = host rebooted (or the counter rolled). Treat
|
|
68
|
+
// this snapshot as a new baseline and return null rates.
|
|
69
|
+
if (inDelta < 0 || outDelta < 0) {
|
|
70
|
+
previous = current;
|
|
71
|
+
return {
|
|
72
|
+
pswpin_total: current.pswpin,
|
|
73
|
+
pswpout_total: current.pswpout,
|
|
74
|
+
pswpin_rate: null,
|
|
75
|
+
pswpout_rate: null,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const inRate = inDelta / elapsedSeconds;
|
|
79
|
+
const outRate = outDelta / elapsedSeconds;
|
|
80
|
+
previous = current;
|
|
81
|
+
return {
|
|
82
|
+
pswpin_total: current.pswpin,
|
|
83
|
+
pswpout_total: current.pswpout,
|
|
84
|
+
pswpin_rate: inRate,
|
|
85
|
+
pswpout_rate: outRate,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export const __test_only = {
|
|
89
|
+
parseVmstat,
|
|
90
|
+
resetForTests: () => {
|
|
91
|
+
previous = null;
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=vmstat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vmstat.js","sourceRoot":"","sources":["../../src/collect/vmstat.ts"],"names":[],"mappings":"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"}
|
package/dist/collect/zfs.js
CHANGED
|
@@ -12,9 +12,28 @@ export async function collectZfs() {
|
|
|
12
12
|
return null;
|
|
13
13
|
return { pools };
|
|
14
14
|
}
|
|
15
|
+
function classifyVdevType(vdevName) {
|
|
16
|
+
if (vdevName.startsWith("mirror"))
|
|
17
|
+
return "mirror";
|
|
18
|
+
if (vdevName.startsWith("raidz3"))
|
|
19
|
+
return "raidz3";
|
|
20
|
+
if (vdevName.startsWith("raidz2"))
|
|
21
|
+
return "raidz2";
|
|
22
|
+
if (vdevName.startsWith("raidz1"))
|
|
23
|
+
return "raidz1";
|
|
24
|
+
if (vdevName.startsWith("raidz"))
|
|
25
|
+
return "raidz1"; // bare "raidz" alias
|
|
26
|
+
if (vdevName.startsWith("dRAID"))
|
|
27
|
+
return "draid";
|
|
28
|
+
// Anything else at the top level is a single-device "stripe" vdev:
|
|
29
|
+
// no redundancy. The pattern library treats stripe failure as P0
|
|
30
|
+
// because there's nothing left to recover from.
|
|
31
|
+
return "stripe";
|
|
32
|
+
}
|
|
15
33
|
export function parseZpoolStatus(zpoolStatus) {
|
|
16
34
|
const pools = [];
|
|
17
35
|
let current = null;
|
|
36
|
+
let section = "none";
|
|
18
37
|
for (const line of zpoolStatus.split("\n")) {
|
|
19
38
|
const poolMatch = line.match(/^\s*pool:\s*(.+)/);
|
|
20
39
|
if (poolMatch) {
|
|
@@ -22,8 +41,12 @@ export function parseZpoolStatus(zpoolStatus) {
|
|
|
22
41
|
name: poolMatch[1].trim(),
|
|
23
42
|
state: "UNKNOWN",
|
|
24
43
|
errors_text: "",
|
|
44
|
+
vdevs: [],
|
|
45
|
+
slog_vdevs: [],
|
|
46
|
+
l2arc_vdevs: [],
|
|
25
47
|
};
|
|
26
48
|
pools.push(current);
|
|
49
|
+
section = "none";
|
|
27
50
|
continue;
|
|
28
51
|
}
|
|
29
52
|
if (!current)
|
|
@@ -55,6 +78,77 @@ export function parseZpoolStatus(zpoolStatus) {
|
|
|
55
78
|
}
|
|
56
79
|
}
|
|
57
80
|
}
|
|
81
|
+
// Section switching. `config:` opens the vdev tree; `logs`,
|
|
82
|
+
// `cache`, `spares` appear as bare lines (no colon, no leading
|
|
83
|
+
// tab) within the config block as section markers per zpool(8).
|
|
84
|
+
if (line.startsWith("config:")) {
|
|
85
|
+
section = "config";
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
// Section headers in the config block ('logs', 'cache', 'spares')
|
|
89
|
+
// appear unindented (no tab prefix) per the `zpool status` format.
|
|
90
|
+
if (/^logs\s*$/.test(line)) {
|
|
91
|
+
section = "logs";
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (/^cache\s*$/.test(line)) {
|
|
95
|
+
section = "cache";
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (/^spares\s*$/.test(line)) {
|
|
99
|
+
section = "spares";
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
// Top-level vdev lines start with a tab + 2 spaces of indentation
|
|
103
|
+
// (per zpool's format). Child disks within a vdev have deeper
|
|
104
|
+
// indentation. We only care about top-level vdevs here; child
|
|
105
|
+
// device counts feed degraded_disks_count.
|
|
106
|
+
if (section === "config" || section === "logs" || section === "cache") {
|
|
107
|
+
const topVdevMatch = line.match(/^\t {2}(\S+)\s+(\S+)/);
|
|
108
|
+
if (topVdevMatch) {
|
|
109
|
+
const name = topVdevMatch[1];
|
|
110
|
+
const state = topVdevMatch[2];
|
|
111
|
+
// Skip the pool-name line itself (matches the same indent
|
|
112
|
+
// pattern as a vdev line). The pool name was already captured
|
|
113
|
+
// from the `pool:` line above; ignore the duplicate row here.
|
|
114
|
+
if (name === current.name)
|
|
115
|
+
continue;
|
|
116
|
+
const vdev = {
|
|
117
|
+
name,
|
|
118
|
+
state,
|
|
119
|
+
redundancy_class: section === "config" ? classifyVdevType(name) : "stripe",
|
|
120
|
+
degraded_disks_count: 0,
|
|
121
|
+
};
|
|
122
|
+
if (section === "config")
|
|
123
|
+
current.vdevs.push(vdev);
|
|
124
|
+
else if (section === "logs")
|
|
125
|
+
current.slog_vdevs.push(vdev);
|
|
126
|
+
else if (section === "cache")
|
|
127
|
+
current.l2arc_vdevs.push(vdev);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
// Child device under the previously-pushed vdev. Increment its
|
|
131
|
+
// degraded counter if the child's state isn't ONLINE.
|
|
132
|
+
const childMatch = line.match(/^\t {4,}(\S+)\s+(\S+)/);
|
|
133
|
+
if (childMatch) {
|
|
134
|
+
const childState = childMatch[2];
|
|
135
|
+
const lastVdev = (() => {
|
|
136
|
+
if (section === "config" && current.vdevs.length > 0) {
|
|
137
|
+
return current.vdevs[current.vdevs.length - 1];
|
|
138
|
+
}
|
|
139
|
+
if (section === "logs" && current.slog_vdevs.length > 0) {
|
|
140
|
+
return current.slog_vdevs[current.slog_vdevs.length - 1];
|
|
141
|
+
}
|
|
142
|
+
if (section === "cache" && current.l2arc_vdevs.length > 0) {
|
|
143
|
+
return current.l2arc_vdevs[current.l2arc_vdevs.length - 1];
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
})();
|
|
147
|
+
if (lastVdev && childState !== "ONLINE") {
|
|
148
|
+
lastVdev.degraded_disks_count += 1;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
58
152
|
}
|
|
59
153
|
return pools;
|
|
60
154
|
}
|
package/dist/collect/zfs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zfs.js","sourceRoot":"","sources":["../../src/collect/zfs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAGrC,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,8BAA8B;IAC9B,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IAEjD,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;IAC1D,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IAErD,MAAM,KAAK,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAmB,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"zfs.js","sourceRoot":"","sources":["../../src/collect/zfs.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -84,6 +84,11 @@ import { sendEmail } from "./notify/email.js";
|
|
|
84
84
|
import { pushToDashboard, initDashboardAgent } from "./push/dashboard.js";
|
|
85
85
|
import { collectSecurity } from "./collect/security.js";
|
|
86
86
|
import { collectZfs } from "./collect/zfs.js";
|
|
87
|
+
import { collectEdac } from "./collect/edac.js";
|
|
88
|
+
import { collectPsi } from "./collect/psi.js";
|
|
89
|
+
import { collectVmstat } from "./collect/vmstat.js";
|
|
90
|
+
import { collectRebootEvidence } from "./collect/reboot-evidence.js";
|
|
91
|
+
import { collectHardwareRaid } from "./collect/hardware-raid.js";
|
|
87
92
|
import { collectIoErrors } from "./collect/io-errors.js";
|
|
88
93
|
import { collectIoLatency } from "./collect/io-latency.js";
|
|
89
94
|
import { collectConntrack } from "./collect/conntrack.js";
|
|
@@ -261,6 +266,30 @@ async function collect() {
|
|
|
261
266
|
snapshot.file_descriptors = collectFileDescriptors();
|
|
262
267
|
}
|
|
263
268
|
catch { /* skip on error */ }
|
|
269
|
+
// C1-C6 collectors (v0.10.4, 2026-05-19). Each capability-gates by
|
|
270
|
+
// detecting whether the underlying kernel/CLI surface exists; absent
|
|
271
|
+
// → field omitted → dashboard rules degrade gracefully per the
|
|
272
|
+
// activation PR's capability gates.
|
|
273
|
+
try {
|
|
274
|
+
snapshot.ecc_edac = collectEdac() ?? undefined;
|
|
275
|
+
}
|
|
276
|
+
catch { /* skip on error */ }
|
|
277
|
+
try {
|
|
278
|
+
snapshot.psi = collectPsi() ?? undefined;
|
|
279
|
+
}
|
|
280
|
+
catch { /* skip on error */ }
|
|
281
|
+
try {
|
|
282
|
+
snapshot.vmstat = collectVmstat() ?? undefined;
|
|
283
|
+
}
|
|
284
|
+
catch { /* skip on error */ }
|
|
285
|
+
try {
|
|
286
|
+
snapshot.reboot_evidence = await collectRebootEvidence();
|
|
287
|
+
}
|
|
288
|
+
catch { /* skip on error */ }
|
|
289
|
+
try {
|
|
290
|
+
snapshot.hardware_raid = await collectHardwareRaid() ?? undefined;
|
|
291
|
+
}
|
|
292
|
+
catch { /* skip on error */ }
|
|
264
293
|
// Update Prometheus metrics
|
|
265
294
|
updateMetrics(snapshot);
|
|
266
295
|
// Evaluate alerts
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -31,6 +31,100 @@ export interface Snapshot {
|
|
|
31
31
|
file_descriptors?: FileDescriptorData;
|
|
32
32
|
expected_reboot?: boolean;
|
|
33
33
|
expected_reboot_reason?: string;
|
|
34
|
+
/** EDAC memory-error counters per memory controller + DIMM. */
|
|
35
|
+
ecc_edac?: EdacSnapshot;
|
|
36
|
+
/** PSI pressure-stall counters per resource (cpu, memory, io). */
|
|
37
|
+
psi?: PsiSnapshot;
|
|
38
|
+
/** /proc/vmstat swap-in/out rates. */
|
|
39
|
+
vmstat?: VmstatSnapshot;
|
|
40
|
+
/** pstore / kdump / wtmp signals corroborating a reboot. */
|
|
41
|
+
reboot_evidence?: RebootEvidence;
|
|
42
|
+
/** Hardware RAID controllers scraped via vendor CLIs. */
|
|
43
|
+
hardware_raid?: HardwareRaidSnapshot;
|
|
44
|
+
}
|
|
45
|
+
export interface EdacDimm {
|
|
46
|
+
/** dimm_label (vendor-defined string, e.g. "CPU1_DIMM_A1"). */
|
|
47
|
+
label: string;
|
|
48
|
+
/** dimm_location (slot number / chip-channel ordering). */
|
|
49
|
+
location: string;
|
|
50
|
+
/** DIMM size in MB; null if /sys did not report. */
|
|
51
|
+
size_mb: number | null;
|
|
52
|
+
ce_count: number;
|
|
53
|
+
ue_count: number;
|
|
54
|
+
}
|
|
55
|
+
export interface EdacSnapshot {
|
|
56
|
+
/** Sum of ce_count across all memory controllers. */
|
|
57
|
+
edac_corrected_total: number;
|
|
58
|
+
/** Sum of ue_count across all memory controllers. */
|
|
59
|
+
edac_uncorrected_total: number;
|
|
60
|
+
/** Per-DIMM detail. Empty array on hosts where dimm metadata
|
|
61
|
+
* isn't exposed (older EDAC drivers). */
|
|
62
|
+
dimms: EdacDimm[];
|
|
63
|
+
}
|
|
64
|
+
export interface PsiResource {
|
|
65
|
+
/** Rolling average % over the last 10 / 60 / 300 seconds. */
|
|
66
|
+
avg10: number;
|
|
67
|
+
avg60: number;
|
|
68
|
+
avg300: number;
|
|
69
|
+
/** Cumulative microseconds stalled since boot. */
|
|
70
|
+
total: number;
|
|
71
|
+
}
|
|
72
|
+
export interface PsiSnapshot {
|
|
73
|
+
cpu?: {
|
|
74
|
+
some: PsiResource;
|
|
75
|
+
full?: PsiResource;
|
|
76
|
+
};
|
|
77
|
+
memory?: {
|
|
78
|
+
some: PsiResource;
|
|
79
|
+
full?: PsiResource;
|
|
80
|
+
};
|
|
81
|
+
io?: {
|
|
82
|
+
some: PsiResource;
|
|
83
|
+
full?: PsiResource;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export interface VmstatSnapshot {
|
|
87
|
+
/** Cumulative pswpin since boot. */
|
|
88
|
+
pswpin_total: number;
|
|
89
|
+
pswpout_total: number;
|
|
90
|
+
/** Per-second swap-in rate over the most recent interval; null on
|
|
91
|
+
* the first snapshot (no baseline) or after a counter reset (host
|
|
92
|
+
* reboot mid-session). */
|
|
93
|
+
pswpin_rate: number | null;
|
|
94
|
+
pswpout_rate: number | null;
|
|
95
|
+
}
|
|
96
|
+
export interface RebootEvidence {
|
|
97
|
+
/** True if /sys/fs/pstore/ contains any dmesg-* / console-* records
|
|
98
|
+
* from the prior kernel. */
|
|
99
|
+
pstore_present: boolean;
|
|
100
|
+
/** Number of pstore records found (zero when pstore_present=false). */
|
|
101
|
+
pstore_record_count: number;
|
|
102
|
+
/** True if /var/crash/ contains a kdump vmcore. */
|
|
103
|
+
vmcore_present: boolean;
|
|
104
|
+
/** Most recent `last reboot -F` output line, verbatim. Null if
|
|
105
|
+
* `last` is unavailable or wtmp is empty. */
|
|
106
|
+
wtmp_reboot_record: string | null;
|
|
107
|
+
/** Heuristic: true when wtmp shows a `shutdown` record before the
|
|
108
|
+
* most recent reboot (suggests a clean shutdown). false when only
|
|
109
|
+
* the boot record is present (suggests hard reset or power loss). */
|
|
110
|
+
prior_shutdown_clean: boolean;
|
|
111
|
+
}
|
|
112
|
+
export interface HardwareRaidController {
|
|
113
|
+
vendor: "dell" | "hpe" | "lsi" | "adaptec";
|
|
114
|
+
controller_id: string;
|
|
115
|
+
/** Vendor-reported overall state, e.g. "Optimal", "Degraded",
|
|
116
|
+
* "Critical", "Failed", or "Unknown". The dashboard's
|
|
117
|
+
* raid_degraded evaluator pages on any state != "Optimal". */
|
|
118
|
+
state: string;
|
|
119
|
+
/** Count of physical disks the controller flagged as failed /
|
|
120
|
+
* degraded; null when the parser couldn't extract this. */
|
|
121
|
+
degraded_disks: number | null;
|
|
122
|
+
/** Optional vendor-text excerpt the dashboard can surface in
|
|
123
|
+
* evidence; null when not captured. */
|
|
124
|
+
raw_summary: string | null;
|
|
125
|
+
}
|
|
126
|
+
export interface HardwareRaidSnapshot {
|
|
127
|
+
controllers: HardwareRaidController[];
|
|
34
128
|
}
|
|
35
129
|
export interface ConntrackData {
|
|
36
130
|
available: boolean;
|
|
@@ -58,6 +152,21 @@ export interface FileDescriptorData {
|
|
|
58
152
|
max: number;
|
|
59
153
|
percent: number;
|
|
60
154
|
}
|
|
155
|
+
export interface ZfsVdev {
|
|
156
|
+
/** Vdev name, e.g. "raidz2-0", "mirror-0", or a raw device for
|
|
157
|
+
* single-device top-level stripes. */
|
|
158
|
+
name: string;
|
|
159
|
+
/** Vdev state from `zpool status` (ONLINE, DEGRADED, FAULTED,
|
|
160
|
+
* REMOVED, SUSPENDED, UNAVAIL). */
|
|
161
|
+
state: string;
|
|
162
|
+
/** Redundancy class. C6 addition (2026-05-19): scaled vdev severity
|
|
163
|
+
* matrix on the dashboard side depends on this so a DEGRADED
|
|
164
|
+
* raidz1 (zero remaining tolerance) pages differently from a
|
|
165
|
+
* DEGRADED raidz2 (one disk-fault budget left). */
|
|
166
|
+
redundancy_class: "mirror" | "raidz1" | "raidz2" | "raidz3" | "draid" | "stripe";
|
|
167
|
+
/** Number of child devices under this vdev in a non-ONLINE state. */
|
|
168
|
+
degraded_disks_count: number;
|
|
169
|
+
}
|
|
61
170
|
export interface ZfsPool {
|
|
62
171
|
name: string;
|
|
63
172
|
state: string;
|
|
@@ -66,6 +175,14 @@ export interface ZfsPool {
|
|
|
66
175
|
scrub_repaired?: string;
|
|
67
176
|
last_scrub_date?: string;
|
|
68
177
|
scrub_never_run?: boolean;
|
|
178
|
+
/** Top-level data vdevs. Always present from collector v0.10.4+.
|
|
179
|
+
* Dashboard tolerates absent (older agents) via capability gates. */
|
|
180
|
+
vdevs: ZfsVdev[];
|
|
181
|
+
/** Separate log (SLOG / ZIL) vdevs. Empty array on pools without
|
|
182
|
+
* a SLOG configured. */
|
|
183
|
+
slog_vdevs: ZfsVdev[];
|
|
184
|
+
/** Cache (L2ARC) vdevs. Empty array on pools without L2ARC. */
|
|
185
|
+
l2arc_vdevs: ZfsVdev[];
|
|
69
186
|
}
|
|
70
187
|
export interface ZfsData {
|
|
71
188
|
pools: ZfsPool[];
|