refactor: stop sending deprecated DiskReadPs/DiskWritePs fields (#2653)

Disk I/O has been sent in bytes since 0.13.0 (DiskIO for the system,
DiskReadBytes/DiskWriteBytes per filesystem). The agent no longer
populates the old MB-based DiskReadPs/DiskWritePs fields.

The fields are kept on Stats and FsStats only so agents < 0.13.0 still
decode. The hub migrates them on ingest: system-level to DiskIO and
per-filesystem to DiskReadBytes/DiskWriteBytes, so stored records and
the UI only use the byte fields.

Remove the MaxDiskReadPs/MaxDiskWritePs fields, their records averaging,
the UI MB fallbacks and the related TS types.

---------

Co-authored-by: hank <hank@henrygd.me>
This commit is contained in:
Sven van Ginkel
2026-10-19 12:17:54 -04:00
committed by GitHub
co-authored by hank
parent afb710a526
commit 15859c1eb7
8 changed files with 54 additions and 93 deletions
-4
View File
@@ -773,8 +773,6 @@ func (a *Agent) updateDiskIo(cacheTimeMs uint16, systemStats *system.Stats) {
a.setDiskBaseline(name, prevDiskFromCounter(d, now))
stats.TotalRead = d.ReadBytes
stats.TotalWrite = d.WriteBytes
stats.DiskReadPs = readMbPerSecond
stats.DiskWritePs = writeMbPerSecond
stats.DiskReadBytes = diskIORead
stats.DiskWriteBytes = diskIOWrite
stats.DiskIoStats[0] = diskReadTime
@@ -785,8 +783,6 @@ func (a *Agent) updateDiskIo(cacheTimeMs uint16, systemStats *system.Stats) {
stats.DiskIoStats[5] = diskWeightedIO
if stats.Root {
systemStats.DiskReadPs = stats.DiskReadPs
systemStats.DiskWritePs = stats.DiskWritePs
systemStats.DiskIO[0] = diskIORead
systemStats.DiskIO[1] = diskIOWrite
systemStats.DiskIOTotal[0] = d.ReadBytes
+11 -16
View File
@@ -33,10 +33,8 @@ type Stats struct {
DiskTotal float64 `json:"d" cbor:"9,keyasint"`
DiskUsed float64 `json:"du" cbor:"10,keyasint"`
DiskPct float64 `json:"dp" cbor:"11,keyasint"`
DiskReadPs float64 `json:"dr,omitzero" cbor:"12,keyasint,omitzero"`
DiskWritePs float64 `json:"dw,omitzero" cbor:"13,keyasint,omitzero"`
MaxDiskReadPs float64 `json:"drm,omitzero" cbor:"-"`
MaxDiskWritePs float64 `json:"dwm,omitzero" cbor:"-"`
DiskReadPs float64 `json:"dr,omitzero" cbor:"12,keyasint,omitzero"` // Deprecated: sent by agents < 0.13.0. Migrated to DiskIO by the hub.
DiskWritePs float64 `json:"dw,omitzero" cbor:"13,keyasint,omitzero"` // Deprecated: sent by agents < 0.13.0. Migrated to DiskIO by the hub.
NetworkSent float64 `json:"ns,omitzero" cbor:"16,keyasint,omitzero"`
NetworkRecv float64 `json:"nr,omitzero" cbor:"17,keyasint,omitzero"`
MaxNetworkSent float64 `json:"nsm,omitzero" cbor:"-"`
@@ -119,18 +117,15 @@ type GPUData struct {
}
type FsStats struct {
Root bool `json:"-"`
Mountpoint string `json:"-"`
Name string `json:"-"`
DiskTotal float64 `json:"d" cbor:"0,keyasint"`
DiskUsed float64 `json:"du" cbor:"1,keyasint"`
TotalRead uint64 `json:"tr,omitzero" cbor:"9,keyasint,omitzero"` // cumulative device read bytes
TotalWrite uint64 `json:"tw,omitzero" cbor:"10,keyasint,omitzero"` // cumulative device write bytes
DiskReadPs float64 `json:"r" cbor:"2,keyasint"`
DiskWritePs float64 `json:"w" cbor:"3,keyasint"`
MaxDiskReadPS float64 `json:"rm,omitzero" cbor:"-"`
MaxDiskWritePS float64 `json:"wm,omitzero" cbor:"-"`
// TODO: remove DiskReadPs and DiskWritePs in future release in favor of DiskReadBytes and DiskWriteBytes
Root bool `json:"-"`
Mountpoint string `json:"-"`
Name string `json:"-"`
DiskTotal float64 `json:"d" cbor:"0,keyasint"`
DiskUsed float64 `json:"du" cbor:"1,keyasint"`
TotalRead uint64 `json:"tr,omitzero" cbor:"9,keyasint,omitzero"` // cumulative device read bytes
TotalWrite uint64 `json:"tw,omitzero" cbor:"10,keyasint,omitzero"` // cumulative device write bytes
DiskReadPs float64 `json:"r,omitzero" cbor:"2,keyasint,omitzero"` // Deprecated: sent by agents < 0.13.0. Migrated to DiskReadBytes/DiskWriteBytes by the hub.
DiskWritePs float64 `json:"w,omitzero" cbor:"3,keyasint,omitzero"` // Deprecated: sent by agents < 0.13.0. Migrated to DiskReadBytes/DiskWriteBytes by the hub.
DiskReadBytes uint64 `json:"rb" cbor:"6,keyasint,omitempty"`
DiskWriteBytes uint64 `json:"wb" cbor:"7,keyasint,omitempty"`
MaxDiskReadBytes uint64 `json:"rbm,omitzero" cbor:"-"`
+11
View File
@@ -1110,6 +1110,17 @@ func migrateDeprecatedFields(cd *system.CombinedData, createDetails bool) {
cd.Stats.DiskIO[1] = uint64(cd.Stats.DiskWritePs * 1024 * 1024)
cd.Stats.DiskReadPs, cd.Stats.DiskWritePs = 0, 0
}
// migration added 0.21.1
for _, fs := range cd.Stats.ExtraFs {
if fs == nil {
continue
}
if fs.DiskReadBytes == 0 && fs.DiskWriteBytes == 0 {
fs.DiskReadBytes = uint64(fs.DiskReadPs * 1024 * 1024)
fs.DiskWriteBytes = uint64(fs.DiskWritePs * 1024 * 1024)
}
fs.DiskReadPs, fs.DiskWritePs = 0, 0
}
// migration added 0.19.0 - Move deprecated Info fields to Details struct
if cd.Details == nil && cd.Info.Hostname != "" {
if createDetails {
+24
View File
@@ -78,6 +78,30 @@ func TestCombinedData_MigrateDeprecatedFields(t *testing.T) {
}
})
t.Run("Migrate ExtraFs DiskReadPs and DiskWritePs to DiskReadBytes and DiskWriteBytes", func(t *testing.T) {
cd := &system.CombinedData{
Stats: system.Stats{
ExtraFs: map[string]*system.FsStats{
"old": {DiskReadPs: 1.5, DiskWritePs: 2.5},
"new": {DiskReadBytes: 100, DiskWriteBytes: 200},
"nil": nil,
},
},
}
migrateDeprecatedFields(cd, true)
old := cd.Stats.ExtraFs["old"]
if old.DiskReadBytes != uint64(1.5*1024*1024) || old.DiskWriteBytes != uint64(2.5*1024*1024) {
t.Errorf("expected migrated bytes, got %d, %d", old.DiskReadBytes, old.DiskWriteBytes)
}
if old.DiskReadPs != 0 || old.DiskWritePs != 0 {
t.Errorf("expected DiskReadPs and DiskWritePs to be reset, got %f, %f", old.DiskReadPs, old.DiskWritePs)
}
if newFs := cd.Stats.ExtraFs["new"]; newFs.DiskReadBytes != 100 || newFs.DiskWriteBytes != 200 {
t.Errorf("expected existing bytes to be kept, got %d, %d", newFs.DiskReadBytes, newFs.DiskWriteBytes)
}
})
t.Run("Migrate Info fields to Details struct", func(t *testing.T) {
cd := &system.CombinedData{
Stats: system.Stats{
-12
View File
@@ -312,8 +312,6 @@ func AverageSystemStatsSlice(records []system.Stats) system.Stats {
sum.DiskTotal += stats.DiskTotal
sum.DiskUsed += stats.DiskUsed
sum.DiskPct += stats.DiskPct
sum.DiskReadPs += stats.DiskReadPs
sum.DiskWritePs += stats.DiskWritePs
sum.NetworkSent += stats.NetworkSent
sum.NetworkRecv += stats.NetworkRecv
sum.LoadAvg[0] += stats.LoadAvg[0]
@@ -351,8 +349,6 @@ func AverageSystemStatsSlice(records []system.Stats) system.Stats {
sum.MaxMem = max(sum.MaxMem, stats.MaxMem, stats.MemUsed)
sum.MaxNetworkSent = max(sum.MaxNetworkSent, stats.MaxNetworkSent, stats.NetworkSent)
sum.MaxNetworkRecv = max(sum.MaxNetworkRecv, stats.MaxNetworkRecv, stats.NetworkRecv)
sum.MaxDiskReadPs = max(sum.MaxDiskReadPs, stats.MaxDiskReadPs, stats.DiskReadPs)
sum.MaxDiskWritePs = max(sum.MaxDiskWritePs, stats.MaxDiskWritePs, stats.DiskWritePs)
sum.MaxBandwidth[0] = max(sum.MaxBandwidth[0], stats.MaxBandwidth[0], stats.Bandwidth[0])
sum.MaxBandwidth[1] = max(sum.MaxBandwidth[1], stats.MaxBandwidth[1], stats.Bandwidth[1])
sum.MaxDiskIO[0] = max(sum.MaxDiskIO[0], stats.MaxDiskIO[0], stats.DiskIO[0])
@@ -410,10 +406,6 @@ func AverageSystemStatsSlice(records []system.Stats) system.Stats {
fs := sum.ExtraFs[key]
fs.DiskTotal += value.DiskTotal
fs.DiskUsed += value.DiskUsed
fs.DiskWritePs += value.DiskWritePs
fs.DiskReadPs += value.DiskReadPs
fs.MaxDiskReadPS = max(fs.MaxDiskReadPS, value.MaxDiskReadPS, value.DiskReadPs)
fs.MaxDiskWritePS = max(fs.MaxDiskWritePS, value.MaxDiskWritePS, value.DiskWritePs)
fs.DiskReadBytes += value.DiskReadBytes
fs.DiskWriteBytes += value.DiskWriteBytes
fs.MaxDiskReadBytes = max(fs.MaxDiskReadBytes, value.MaxDiskReadBytes, value.DiskReadBytes)
@@ -505,8 +497,6 @@ func AverageSystemStatsSlice(records []system.Stats) system.Stats {
sum.DiskTotal = twoDecimals(sum.DiskTotal / count)
sum.DiskUsed = twoDecimals(sum.DiskUsed / count)
sum.DiskPct = twoDecimals(sum.DiskPct / count)
sum.DiskReadPs = twoDecimals(sum.DiskReadPs / count)
sum.DiskWritePs = twoDecimals(sum.DiskWritePs / count)
sum.DiskIO[0] = sum.DiskIO[0] / uint64(count)
sum.DiskIO[1] = sum.DiskIO[1] / uint64(count)
for i := range sum.DiskIoStats {
@@ -562,8 +552,6 @@ func AverageSystemStatsSlice(records []system.Stats) system.Stats {
fs := sum.ExtraFs[key]
fs.DiskTotal = twoDecimals(fs.DiskTotal / count)
fs.DiskUsed = twoDecimals(fs.DiskUsed / count)
fs.DiskWritePs = twoDecimals(fs.DiskWritePs / count)
fs.DiskReadPs = twoDecimals(fs.DiskReadPs / count)
fs.DiskReadBytes = fs.DiskReadBytes / uint64(count)
fs.DiskWriteBytes = fs.DiskWriteBytes / uint64(count)
for i := range fs.DiskIoStats {
@@ -35,8 +35,6 @@ func TestAverageSystemStatsSlice_SingleRecord(t *testing.T) {
DiskTotal: 500.0,
DiskUsed: 250.0,
DiskPct: 50.0,
DiskReadPs: 100.5,
DiskWritePs: 200.75,
NetworkSent: 10.5,
NetworkRecv: 20.25,
LoadAvg: [3]float64{1.5, 2.0, 3.5},
@@ -58,8 +56,6 @@ func TestAverageSystemStatsSlice_SingleRecord(t *testing.T) {
assert.Equal(t, 500.0, result.DiskTotal)
assert.Equal(t, 250.0, result.DiskUsed)
assert.Equal(t, 50.0, result.DiskPct)
assert.Equal(t, 100.5, result.DiskReadPs)
assert.Equal(t, 200.75, result.DiskWritePs)
assert.Equal(t, 10.5, result.NetworkSent)
assert.Equal(t, 20.25, result.NetworkRecv)
assert.Equal(t, [3]float64{1.5, 2.0, 3.5}, result.LoadAvg)
@@ -83,8 +79,6 @@ func TestAverageSystemStatsSlice_BasicAveraging(t *testing.T) {
DiskTotal: 500.0,
DiskUsed: 200.0,
DiskPct: 40.0,
DiskReadPs: 100.0,
DiskWritePs: 200.0,
NetworkSent: 10.0,
NetworkRecv: 20.0,
LoadAvg: [3]float64{1.0, 2.0, 3.0},
@@ -104,8 +98,6 @@ func TestAverageSystemStatsSlice_BasicAveraging(t *testing.T) {
DiskTotal: 500.0,
DiskUsed: 300.0,
DiskPct: 60.0,
DiskReadPs: 200.0,
DiskWritePs: 400.0,
NetworkSent: 30.0,
NetworkRecv: 40.0,
LoadAvg: [3]float64{3.0, 4.0, 5.0},
@@ -128,8 +120,6 @@ func TestAverageSystemStatsSlice_BasicAveraging(t *testing.T) {
assert.Equal(t, 500.0, result.DiskTotal)
assert.Equal(t, 250.0, result.DiskUsed)
assert.Equal(t, 50.0, result.DiskPct)
assert.Equal(t, 150.0, result.DiskReadPs)
assert.Equal(t, 300.0, result.DiskWritePs)
assert.Equal(t, 20.0, result.NetworkSent)
assert.Equal(t, 30.0, result.NetworkRecv)
assert.Equal(t, [3]float64{2.0, 3.0, 4.0}, result.LoadAvg)
@@ -150,10 +140,6 @@ func TestAverageSystemStatsSlice_PeakValues(t *testing.T) {
MaxNetworkSent: 15.0,
NetworkRecv: 20.0,
MaxNetworkRecv: 25.0,
DiskReadPs: 100.0,
MaxDiskReadPs: 120.0,
DiskWritePs: 200.0,
MaxDiskWritePs: 220.0,
Bandwidth: [2]uint64{1000, 2000},
MaxBandwidth: [2]uint64{1500, 2500},
DiskIO: [2]uint64{400, 600},
@@ -170,10 +156,6 @@ func TestAverageSystemStatsSlice_PeakValues(t *testing.T) {
MaxNetworkSent: 35.0,
NetworkRecv: 40.0,
MaxNetworkRecv: 45.0,
DiskReadPs: 200.0,
MaxDiskReadPs: 210.0,
DiskWritePs: 400.0,
MaxDiskWritePs: 410.0,
Bandwidth: [2]uint64{3000, 4000},
MaxBandwidth: [2]uint64{3500, 4500},
DiskIO: [2]uint64{600, 800},
@@ -189,8 +171,6 @@ func TestAverageSystemStatsSlice_PeakValues(t *testing.T) {
assert.Equal(t, 12.0, result.MaxMem)
assert.Equal(t, 35.0, result.MaxNetworkSent)
assert.Equal(t, 45.0, result.MaxNetworkRecv)
assert.Equal(t, 210.0, result.MaxDiskReadPs)
assert.Equal(t, 410.0, result.MaxDiskWritePs)
assert.Equal(t, [2]uint64{3500, 4500}, result.MaxBandwidth)
assert.Equal(t, [2]uint64{650, 850}, result.MaxDiskIO)
assert.Equal(t, [6]float64{30.0, 40.0, 50.0, 10.0, 13.0, 17.0}, result.DiskIoStats)
@@ -347,10 +327,6 @@ func TestAverageSystemStatsSlice_ExtraFs(t *testing.T) {
"/data": {
DiskTotal: 1000.0,
DiskUsed: 400.0,
DiskReadPs: 50.0,
DiskWritePs: 100.0,
MaxDiskReadPS: 60.0,
MaxDiskWritePS: 110.0,
DiskReadBytes: 5000,
DiskWriteBytes: 10000,
MaxDiskReadBytes: 6000,
@@ -366,10 +342,6 @@ func TestAverageSystemStatsSlice_ExtraFs(t *testing.T) {
"/data": {
DiskTotal: 1000.0,
DiskUsed: 600.0,
DiskReadPs: 150.0,
DiskWritePs: 200.0,
MaxDiskReadPS: 160.0,
MaxDiskWritePS: 210.0,
DiskReadBytes: 15000,
DiskWriteBytes: 20000,
MaxDiskReadBytes: 16000,
@@ -388,10 +360,6 @@ func TestAverageSystemStatsSlice_ExtraFs(t *testing.T) {
fs := result.ExtraFs["/data"]
assert.Equal(t, 1000.0, fs.DiskTotal)
assert.Equal(t, 500.0, fs.DiskUsed)
assert.Equal(t, 100.0, fs.DiskReadPs)
assert.Equal(t, 150.0, fs.DiskWritePs)
assert.Equal(t, 160.0, fs.MaxDiskReadPS)
assert.Equal(t, 210.0, fs.MaxDiskWritePS)
assert.Equal(t, uint64(10000), fs.DiskReadBytes)
assert.Equal(t, uint64(15000), fs.DiskWriteBytes)
assert.Equal(t, uint64(16000), fs.MaxDiskReadBytes)
@@ -441,8 +409,6 @@ func TestAverageSystemStatsSlice_ExtraFsPeaksFromCurrentValues(t *testing.T) {
Cpu: 10.0,
ExtraFs: map[string]*system.FsStats{
"/data": {
DiskReadPs: 500.0, // exceeds MaxDiskReadPS
MaxDiskReadPS: 100.0,
DiskReadBytes: 50000,
MaxDiskReadBytes: 10000,
},
@@ -452,8 +418,6 @@ func TestAverageSystemStatsSlice_ExtraFsPeaksFromCurrentValues(t *testing.T) {
Cpu: 20.0,
ExtraFs: map[string]*system.FsStats{
"/data": {
DiskReadPs: 50.0,
MaxDiskReadPS: 200.0,
DiskReadBytes: 5000,
MaxDiskReadBytes: 20000,
},
@@ -464,7 +428,6 @@ func TestAverageSystemStatsSlice_ExtraFsPeaksFromCurrentValues(t *testing.T) {
result := records.AverageSystemStatsSlice(input)
fs := result.ExtraFs["/data"]
assert.Equal(t, 500.0, fs.MaxDiskReadPS)
assert.Equal(t, uint64(50000), fs.MaxDiskReadBytes)
}
@@ -35,27 +35,27 @@ export const diskDataFns = {
({ stats }: SystemStatsRecord) =>
stats?.efs?.[name]?.du ?? 0,
// throughput
read: ({ stats }: SystemStatsRecord) => stats?.dio?.[0] ?? (stats?.dr ?? 0) * 1024 * 1024,
readMax: ({ stats }: SystemStatsRecord) => stats?.diom?.[0] ?? (stats?.drm ?? 0) * 1024 * 1024,
write: ({ stats }: SystemStatsRecord) => stats?.dio?.[1] ?? (stats?.dw ?? 0) * 1024 * 1024,
writeMax: ({ stats }: SystemStatsRecord) => stats?.diom?.[1] ?? (stats?.dwm ?? 0) * 1024 * 1024,
read: ({ stats }: SystemStatsRecord) => stats?.dio?.[0] ?? 0,
readMax: ({ stats }: SystemStatsRecord) => stats?.diom?.[0] ?? 0,
write: ({ stats }: SystemStatsRecord) => stats?.dio?.[1] ?? 0,
writeMax: ({ stats }: SystemStatsRecord) => stats?.diom?.[1] ?? 0,
// extra fs throughput
extraRead:
(name: string) =>
({ stats }: SystemStatsRecord) =>
stats?.efs?.[name]?.rb ?? (stats?.efs?.[name]?.r ?? 0) * 1024 * 1024,
stats?.efs?.[name]?.rb ?? 0,
extraReadMax:
(name: string) =>
({ stats }: SystemStatsRecord) =>
stats?.efs?.[name]?.rbm ?? (stats?.efs?.[name]?.rm ?? 0) * 1024 * 1024,
stats?.efs?.[name]?.rbm ?? 0,
extraWrite:
(name: string) =>
({ stats }: SystemStatsRecord) =>
stats?.efs?.[name]?.wb ?? (stats?.efs?.[name]?.w ?? 0) * 1024 * 1024,
stats?.efs?.[name]?.wb ?? 0,
extraWriteMax:
(name: string) =>
({ stats }: SystemStatsRecord) =>
stats?.efs?.[name]?.wbm ?? (stats?.efs?.[name]?.wm ?? 0) * 1024 * 1024,
stats?.efs?.[name]?.wbm ?? 0,
// cumulative totals
totalRead: ({ stats }: SystemStatsRecord) => stats?.diot?.[0] ?? 0,
totalWrite: ({ stats }: SystemStatsRecord) => stats?.diot?.[1] ?? 0,
-16
View File
@@ -126,14 +126,6 @@ export interface SystemStats {
du: number
/** disk percent */
dp: number
/** disk read (mb) */
dr: number
/** disk write (mb) */
dw: number
/** max disk read (mb) */
drm?: number
/** max disk write (mb) */
dwm?: number
/** disk I/O bytes [read, write] */
dio?: [number, number]
/** max disk I/O bytes [read, write] */
@@ -277,14 +269,6 @@ export interface ExtraFsStats {
d: number
/** disk used (gb) */
du: number
/** total read (mb) */
r: number
/** total write (mb) */
w: number
/** max read (mb) */
rm: number
/** max write (mb) */
wm: number
/** read per second (bytes) */
rb: number
/** write per second (bytes) */