From 997adc19bb13b5f4d955d685e6eedd0ce4f59271 Mon Sep 17 00:00:00 2001 From: henrygd Date: Mon, 7 Sep 2026 13:13:05 -0400 Subject: [PATCH] fix: show idle GPU utilization in systems table (#2312) --- internal/hub/systems/system.go | 10 ++++- internal/hub/systems/system_gpu_test.go | 44 +++++++++++++++++++ .../systems-table/systems-table-columns.tsx | 2 +- 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 internal/hub/systems/system_gpu_test.go diff --git a/internal/hub/systems/system.go b/internal/hub/systems/system.go index 1bcdb8bf..e5650526 100644 --- a/internal/hub/systems/system.go +++ b/internal/hub/systems/system.go @@ -272,7 +272,15 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error // update system record (do this last because it triggers alerts and we need above records to be inserted first) systemRecord.Set("status", up) - systemRecord.Set("info", data.Info) + // Distinguish an idle GPU from a system without GPU data (#2312) + info := struct { + system.Info + GpuPct *float64 `json:"g,omitempty"` + }{Info: data.Info} + if len(data.Stats.GPUData) > 0 { + info.GpuPct = &data.Info.GpuPct + } + systemRecord.Set("info", info) if err := txApp.SaveNoValidate(systemRecord); err != nil { return err } diff --git a/internal/hub/systems/system_gpu_test.go b/internal/hub/systems/system_gpu_test.go new file mode 100644 index 00000000..0c61a8af --- /dev/null +++ b/internal/hub/systems/system_gpu_test.go @@ -0,0 +1,44 @@ +//go:build testing + +package systems + +import ( + "testing" + + "github.com/henrygd/beszel/internal/entities/system" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCreateRecordsGPUUtilization(t *testing.T) { + sys, app := newTestSystemWithHub(t) + for _, tc := range []struct { + name string + gpu bool + usage float64 + }{ + {"no GPU", false, 0}, + {"active GPU", true, 42.5}, + {"idle GPU", true, 0}, + {"GPU removed", false, 0}, + } { + t.Run(tc.name, func(t *testing.T) { + data := &system.CombinedData{Info: system.Info{GpuPct: tc.usage, Cpu: 12.5}} + if tc.gpu { + data.Stats.GPUData = map[string]system.GPUData{"0": {Name: "GPU", Usage: tc.usage}} + } + _, err := sys.createRecords(data) + require.NoError(t, err) + record, err := app.FindRecordById("systems", sys.Id) + require.NoError(t, err) + var info map[string]any + require.NoError(t, record.UnmarshalJSONField("info", &info)) + assert.Equal(t, 12.5, info["cpu"]) + if tc.gpu { + assert.Equal(t, tc.usage, info["g"]) + } else { + assert.NotContains(t, info, "g") + } + }) + } +} diff --git a/internal/site/src/components/systems-table/systems-table-columns.tsx b/internal/site/src/components/systems-table/systems-table-columns.tsx index 355ed53a..40d6c7d5 100644 --- a/internal/site/src/components/systems-table/systems-table-columns.tsx +++ b/internal/site/src/components/systems-table/systems-table-columns.tsx @@ -193,7 +193,7 @@ export function SystemsTableColumns(viewMode: "table" | "grid"): ColumnDef info.g || undefined, + accessorFn: ({ info }) => info.g, id: "gpu", name: () => "GPU", cell: (info) => {