ZFS tab: Writes — the RAM write buffer, each pool's write rate, and a landing tier with its mover

Live from arcstats (dirty), dmu_tx (throttled writes), each pool's txgs (bytes synced to disk)
and objset kstats (bytes from programs). A landing tier — a mergerfs pool whose first branch is
fast storage and whose last is a ZFS dataset — is detected from mergerfs's branch xattr; a mover
status file in /run/landing-mover/ adds its queue, the file in flight and totals. Sensors
zfs.write.*, zfs.<pool>.write_bps|logical_bps and zfs.<pool>.landing.* carry the history.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-10-25 22:28:40 -07:00
co-authored by Claude Opus 5.5
parent 1a9b31ea0a
commit 86cfcd2bad
9 changed files with 754 additions and 9 deletions
+26
View File
@@ -203,6 +203,32 @@ func flatten(s Sample, want func(id string) bool) []sensors.Sensor {
}
}
if w := s.ZFSWrite; w != nil {
f.add("zfs.write.dirty", "ZFS write buffer", "bytes", "B", float64(w.Dirty), t, upTo(float64(w.Limit)))
f.add("zfs.write.limit", "ZFS write buffer limit", "bytes", "B", float64(w.Limit), t, none)
f.add("zfs.write.delayed", "ZFS writes throttled", "rate", "/s", w.DelayedPerSec, t, none)
for _, p := range w.Pools {
pp := "zfs." + sensors.Seg(p.Pool) + "."
f.add(pp+"write_bps", p.Pool+" writes to disk", "rate", "B/s", p.WriteBps, t, none, "pool", p.Pool)
f.add(pp+"logical_bps", p.Pool+" writes by programs", "rate", "B/s", p.LogicalBps, t, none, "pool", p.Pool)
if l := p.Landing; l != nil {
lp := pp + "landing."
lbl := []string{"pool", p.Pool, "branch", l.Branch}
f.add(lp+"pending_bytes", p.Pool+" landing: waiting", "bytes", "B", float64(l.PendingBytes), t, upTo(float64(l.Size)), lbl...)
f.add(lp+"pending_files", p.Pool+" landing: files waiting", "count", "", float64(l.PendingFiles), t, none, lbl...)
if l.Size > 0 {
f.add(lp+"used_pct", p.Pool+" landing: used", "usage", "%", round1(float64(l.Used)/float64(l.Size)*100), t, pct, lbl...)
}
f.add(lp+"in_bps", p.Pool+" landing: arriving", "rate", "B/s", l.InBps, t, none, lbl...)
f.add(lp+"drain_bps", p.Pool+" landing: moving to the pool", "rate", "B/s", l.DrainBps, t, none, lbl...)
if m := l.Mover; m != nil {
f.add(lp+"mover", p.Pool+" landing: mover", "state", "", m.State, t, none, lbl...)
f.add(lp+"queue", p.Pool+" landing: mover queue", "count", "", float64(m.Queue), t, none, lbl...)
}
}
}
}
if u := s.UPS; u != nil {
ut := s.upsT
f.add("ups.battery", "UPS battery", "usage", "%", u.BatteryPct, ut, pct, "model", u.Model)