mirror of
https://github.com/henrygd/beszel.git
synced 2026-10-22 06:12:33 +00:00
Memory and swap were rounded to two decimal GB places before being sent to the hub, which is inaccurate on low memory systems. - agent: add MemBytes [total, used, buff/cache, zfs arc] and SwapBytes [total, used] - hub: migrate GB fields from older agents to the byte fields - records: average byte fields, converting GB values from older records - site: chart memory and swap from bytes, with fallback for older records Deprecated GB fields are still populated in agent payloads and stored records for older hubs and third-party integrations.
62 lines
2.1 KiB
Go
62 lines
2.1 KiB
Go
package agent
|
|
|
|
import (
|
|
"github.com/henrygd/beszel/agent/utils"
|
|
"github.com/henrygd/beszel/agent/zfs"
|
|
"github.com/henrygd/beszel/internal/entities/system"
|
|
"github.com/shirou/gopsutil/v4/mem"
|
|
)
|
|
|
|
// memoryMetrics holds byte counters. For cgroups, Used excludes file cache,
|
|
// while retaining shared memory/tmpfs. BuffCache is the subtracted file cache.
|
|
type memoryMetrics struct {
|
|
Total, Used, BuffCache uint64
|
|
}
|
|
|
|
var memoryVirtualMemory = mem.VirtualMemory
|
|
|
|
func (a *Agent) updateMemoryStats(stats *system.Stats) {
|
|
v, err := memoryVirtualMemory()
|
|
var hostTotal uint64
|
|
if err == nil {
|
|
hostTotal = v.Total
|
|
// Swap retains its existing /proc/meminfo source in both memory paths.
|
|
stats.SwapBytes = [2]uint64{v.SwapTotal, saturatingSub(v.SwapTotal, v.SwapFree)}
|
|
// TODO: stop populating deprecated GB fields once hubs < 0.21.1 are no longer supported
|
|
stats.Swap = utils.BytesToGigabytes(stats.SwapBytes[0])
|
|
stats.SwapUsed = utils.BytesToGigabytes(stats.SwapBytes[1])
|
|
}
|
|
|
|
var arcSize uint64
|
|
metrics, fromCgroup := containerMemoryMetrics(hostTotal, a.forceUseCgroup)
|
|
if !fromCgroup {
|
|
if err != nil {
|
|
return
|
|
}
|
|
used, cacheBuff, _ := calculateHostMemoryUsage(v, a.memCalc == "htop")
|
|
metrics = memoryMetrics{Total: v.Total, Used: used, BuffCache: cacheBuff}
|
|
// Host ARC must not be subtracted from container-scoped accounting.
|
|
if a.zfs {
|
|
if size, _ := zfs.ARCSize(); size > 0 && size < metrics.Used {
|
|
arcSize = size
|
|
metrics.Used -= arcSize
|
|
}
|
|
}
|
|
}
|
|
|
|
stats.MemBytes = [4]uint64{metrics.Total, metrics.Used, metrics.BuffCache, arcSize}
|
|
// TODO: stop populating deprecated GB fields once hubs < 0.21.1 are no longer supported
|
|
stats.Mem = utils.BytesToGigabytes(metrics.Total)
|
|
stats.MemUsed = utils.BytesToGigabytes(metrics.Used)
|
|
stats.MemBuffCache = utils.BytesToGigabytes(metrics.BuffCache)
|
|
stats.MemZfsArc = utils.BytesToGigabytes(arcSize)
|
|
if metrics.Total > 0 {
|
|
stats.MemPct = utils.TwoDecimals(float64(metrics.Used) / float64(metrics.Total) * 100)
|
|
}
|
|
if a.systemDetails.MemoryTotal != metrics.Total {
|
|
a.updateSystemDetails(func(details *system.Details) {
|
|
details.MemoryTotal = metrics.Total
|
|
})
|
|
}
|
|
}
|