Add 4 monitoring posts (EN + ZH): smartctl exit 32, Grafana no-data variable, percentage alert thresholds, one Prometheus for 3 hosts
Deploy / build (push) Successful in 28s

Backdated into the 2026-03-25 -> 2026-09-04 archive gap (pubDate 2026-04-14/05-17/06-24/07-29)
with updatedDate 2026-09-29 holding the real date, so sitemap lastmod stays honest.
Custom OG + banner per post, hire CTA, language switch verified.
This commit is contained in:
2026-09-29 01:37:23 +08:00
parent d588e9691b
commit e8c5124db1
19 changed files with 1124 additions and 0 deletions
+79
View File
@@ -787,6 +787,85 @@ BANNERS['why-chrome-forgets-its-tabs-in-a-container'] = {
],
};
BANNERS['smartctl-exit-code-32-skips-the-disks-that-matter'] = {
titlebar: 'root@unraid — disk health · textfile collector',
lines: [
{ t: 'prompt', text: '$' }, { t: 'cmd', text: 'for dev in /dev/sd?; do smartctl -A "$dev"' },
{ t: 'err', text: 'rc=32 ← "OK, but attributes were below threshold"' },
{ t: 'dim', text: 'treated as unreadable → disk skipped' },
{ t: 'err', text: '2 of 4 SSDs missing · the marginal ones' },
{ t: 'prompt', text: '$' }, { t: 'cmd', text: 'fatal=$(( rc & ~(32 | 64) )) · rc as a metric' },
{ t: 'ok', text: '→ 4/4 disks collected ✓' },
],
flow: [
{ n: '1', label: 'rc=32', err: true },
{ n: '2', label: 'skip ✗' },
{ n: '3', label: '2/4 disks' },
{ n: '4', label: 'mask bits' },
{ n: '5', label: '4/4 ✓' },
],
};
BANNERS['why-your-grafana-dashboard-shows-no-data'] = {
titlebar: 'root@grafana — 41 panels · No data',
lines: [
{ t: 'prompt', text: '$' }, { t: 'cmd', text: 'curl -s prometheus:9090/api/v1/targets' },
{ t: 'ok', text: 'all 7 targets: up' },
{ t: 'err', text: 'every panel: "No data"' },
{ t: 'dim', text: 'my check substituted the values by hand ✓ ← bug invisible' },
{ t: 'prompt', text: '$' }, { t: 'cmd', text: '$nodename = label_values(...{nodename=~"$nodename"})' },
{ t: 'err', text: '← variable filters on itself → 0 options' },
{ t: 'ok', text: '→ no self-reference + saved current · 21/25 ✓' },
],
flow: [
{ n: '1', label: 'targets up' },
{ n: '2', label: 'panels ✗' },
{ n: '3', label: 'variables' },
{ n: '4', label: 'self-ref' },
{ n: '5', label: '21/25 ✓' },
],
};
BANNERS['your-disk-full-alert-is-lying'] = {
titlebar: 'root@monitor — alert rules · 16 total',
lines: [
{ t: 'err', text: 'ALERT filesystem >90% · 500 GB still free' },
{ t: 'err', text: 'ALERT memory >90% used · 4.8 GB available' },
{ t: 'err', text: 'ALERT CPU steal >25% · host fine at 41%' },
{ t: 'dim', text: 'always true · never actionable' },
{ t: 'dim', text: 'and each one trains you to skim' },
{ t: 'prompt', text: '$' }, { t: 'cmd', text: 'alert on the consequence, not the ratio' },
{ t: 'ok', text: '→ free <25 GB · MemAvailable <512 MB ✓' },
],
flow: [
{ n: '1', label: '% full ✗', err: true },
{ n: '2', label: '% used ✗', err: true },
{ n: '3', label: 'steal ✗' },
{ n: '4', label: 'absolute' },
{ n: '5', label: 'silent ✓' },
],
};
BANNERS['one-prometheus-for-unraid-synology-and-a-vps'] = {
titlebar: 'root@unraid — prometheus · 7 targets · 25.5k series',
lines: [
{ t: 'prompt', text: '$' }, { t: 'cmd', text: 'sum(node_filesystem_size_bytes)' },
{ t: 'err', text: '64 TB "total" ← one NAS volume counted 3×' },
{ t: 'err', text: 'KVM guest: no cpufreq → 0 series' },
{ t: 'err', text: 'nodename = 9f9afcccc962 ← container ID' },
{ t: 'dim', text: 'cAdvisor: systemd slices reported as containers' },
{ t: 'prompt', text: '$' }, { t: 'cmd', text: 'dedup · textfile · hostname pin' },
{ t: 'ok', text: '→ 47 cores · 158 GHz · 142 GB · 155 containers ✓' },
],
flow: [
{ n: '1', label: '3 views', err: true },
{ n: '2', label: 'dedup ✓' },
{ n: '3', label: 'guest gap' },
{ n: '4', label: 'textfile' },
{ n: '5', label: 'one screen ✓' },
],
};
// ---------- read frontmatter ----------
const postPath = join(ROOT, 'src', 'content', 'posts', `${slug}.md`);
let category = 'devops';
+25
View File
@@ -243,6 +243,31 @@ TERMINALS['why-chrome-forgets-its-tabs-in-a-container'] = `
<div class="line"><span class="prompt">&nbsp;</span><span class="err">exit_type=Crashed ← the container kills the browser</span></div>
<div class="line"><span class="prompt">$</span><span class="cmd">tabs_keeper.py · snapshot every 60s · replay via /json/new</span><span class="fix">→ restored 2/2 tabs ✓</span></div>`;
TERMINALS['smartctl-exit-code-32-skips-the-disks-that-matter'] = `
<div class="line"><span class="prompt">$</span><span class="cmd">for dev in /dev/sd?; do smartctl -A "$dev" || continue; done</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="err">rc=32 · "disk OK, attributes were below threshold in the past"</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="err">→ 2 of 4 SSDs silently skipped · exactly the marginal ones</span></div>
<div class="line"><span class="prompt">$</span><span class="cmd">fatal=$(( rc &amp; ~(32 | 64) )) · rc exported as a metric</span><span class="fix">→ 4/4 collected ✓</span></div>`;
TERMINALS['why-your-grafana-dashboard-shows-no-data'] = `
<div class="line"><span class="prompt">$</span><span class="cmd">curl -s prometheus:9090/api/v1/targets | jq .[].health</span><span class="fix">→ all 7 up</span></div>
<div class="line"><span class="prompt">$</span><span class="cmd">curl -sG /api/v1/query --data-urlencode 'query=node_uname_info'</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="err">data is there · panel expression returns rows · dashboard: No data</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="err">$nodename = label_values(...{nodename=~"$nodename"}) ← filters on itself</span></div>
<div class="line"><span class="prompt">$</span><span class="cmd">drop the self-reference · save current values</span><span class="fix">→ 21/25 panels ✓</span></div>`;
TERMINALS['your-disk-full-alert-is-lying'] = `
<div class="line"><span class="prompt">&nbsp;</span><span class="err">ALERT filesystem above 90% · 17 TB volume · 500 GB still free</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="err">ALERT memory above 90% used · 4.8 GB actually available</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="err">ALERT CPU steal above 25% · host fine at 41%</span></div>
<div class="line"><span class="prompt">$</span><span class="cmd">alert on the consequence, not the ratio</span><span class="fix">→ silent when healthy ✓</span></div>`;
TERMINALS['one-prometheus-for-unraid-synology-and-a-vps'] = `
<div class="line"><span class="prompt">$</span><span class="cmd">sum(node_filesystem_size_bytes) → 64 TB "total"</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="err">one NAS volume counted 3×: /volume1 · /opt · CIFS re-mount</span></div>
<div class="line"><span class="prompt">&nbsp;</span><span class="err">KVM guest: no cpufreq · 0 series nodename = 9f9afcccc962</span></div>
<div class="line"><span class="prompt">$</span><span class="cmd">dedup selector · textfile collector · hostname pin</span><span class="fix">→ 7 targets ✓</span></div>`;
// ---------- read frontmatter ----------
const postPath = join(ROOT, 'src', 'content', 'posts', `${slug}.md`);
if (!existsSync(postPath)) {