From 534a478fcd19695256cdc83c3c3bdbc348f9d669 Mon Sep 17 00:00:00 2001 From: "Saro G." Date: Wed, 19 Jun 2024 12:23:59 -0400 Subject: [PATCH 1/4] TestBootTime() compare with system uptime binary output --- providers/freebsd/sysctl_freebsd_test.go | 39 +++++++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/providers/freebsd/sysctl_freebsd_test.go b/providers/freebsd/sysctl_freebsd_test.go index 613371e..f2ba62b 100644 --- a/providers/freebsd/sysctl_freebsd_test.go +++ b/providers/freebsd/sysctl_freebsd_test.go @@ -20,11 +20,12 @@ package freebsd import ( - "testing" - "time" - + "encoding/json" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "os/exec" + "testing" + "time" ) func TestArchitecture(t *testing.T) { @@ -42,8 +43,36 @@ func TestBootTime(t *testing.T) { t.Fatal(err) } - // Apply a sanity check. This assumes the host has rebooted in the last year. - assert.WithinDuration(t, time.Now().UTC(), bootTime, 365*24*time.Hour) + bootDiff := time.Since(bootTime) + // t.Logf("bootTime in seconds: %#v", int64(bootDiff.Seconds())) + + cmd := exec.Command("/usr/bin/uptime", "--libxo=json") + upcmd, err := cmd.Output() + + if err != nil { + t.Fatal(err) + } + + t.Logf(string(upcmd)) + + type UptimeOutput struct { + UptimeInformation struct { + Uptime int64 `json:"uptime"` + } `json:"uptime-information"` + } + + var upInfo UptimeOutput + err = json.Unmarshal(upcmd, &upInfo) + + if err != nil { + t.Fatal(err) + } + + upsec := upInfo.UptimeInformation.Uptime + uptime := time.Duration(upsec * int64(time.Second)) + // t.Logf("uptime in seconds: %#v", int64(uptime.Seconds())) + + assert.InDelta(t, uptime, bootDiff, float64(5*time.Second)) } func TestCPUStateTimes(t *testing.T) { From f9fda7545352e82a561e566d82d9b7b48480b162 Mon Sep 17 00:00:00 2001 From: "Saro G." Date: Wed, 19 Jun 2024 13:16:13 -0400 Subject: [PATCH 2/4] Moved sysctl value casts into helper methods --- providers/freebsd/host_freebsd_cgo.go | 19 +++++++++---------- providers/freebsd/process_freebsd_cgo.go | 2 +- providers/freebsd/sysctl_freebsd.go | 24 ++++++++++++------------ 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/providers/freebsd/host_freebsd_cgo.go b/providers/freebsd/host_freebsd_cgo.go index 4862908..15fc9ae 100644 --- a/providers/freebsd/host_freebsd_cgo.go +++ b/providers/freebsd/host_freebsd_cgo.go @@ -128,11 +128,10 @@ func (r *reader) memInfo(m *types.HostMemoryInfo) { // free = free // available = buffers + inactive + cache + free - ps, err := pageSizeBytes() + pageSize, err := pageSizeBytes() if r.addErr(err) { return } - pageSize := uint64(ps) m.Total, err = totalPhysicalMem() if r.addErr(err) { @@ -144,31 +143,31 @@ func (r *reader) memInfo(m *types.HostMemoryInfo) { return } m.Metrics = make(map[string]uint64, 6) - m.Metrics["active_bytes"] = uint64(activePages) * pageSize + m.Metrics["active_bytes"] = activePages * pageSize wirePages, err := wirePageCount() if r.addErr(err) { return } - m.Metrics["wired_bytes"] = uint64(wirePages) * pageSize + m.Metrics["wired_bytes"] = wirePages * pageSize inactivePages, err := inactivePageCount() if r.addErr(err) { return } - m.Metrics["inactive_bytes"] = uint64(inactivePages) * pageSize + m.Metrics["inactive_bytes"] = inactivePages * pageSize cachePages, err := cachePageCount() if r.addErr(err) { return } - m.Metrics["cache_bytes"] = uint64(cachePages) * pageSize + m.Metrics["cache_bytes"] = cachePages * pageSize freePages, err := freePageCount() if r.addErr(err) { return } - m.Metrics["free_bytes"] = uint64(freePages) * pageSize + m.Metrics["free_bytes"] = freePages * pageSize buffers, err := buffersUsedBytes() if r.addErr(err) { @@ -176,9 +175,9 @@ func (r *reader) memInfo(m *types.HostMemoryInfo) { } m.Metrics["buffer_bytes"] = buffers - m.Used = uint64(activePages+wirePages) * pageSize - m.Free = uint64(freePages) * pageSize - m.Available = uint64(inactivePages+cachePages+freePages)*pageSize + buffers + m.Used = (activePages + wirePages) * pageSize + m.Free = freePages * pageSize + m.Available = (inactivePages+cachePages+freePages)*pageSize + buffers // Virtual (swap) Memory swap, err := kvmGetSwapInfo() diff --git a/providers/freebsd/process_freebsd_cgo.go b/providers/freebsd/process_freebsd_cgo.go index 83cbf12..ab6b506 100644 --- a/providers/freebsd/process_freebsd_cgo.go +++ b/providers/freebsd/process_freebsd_cgo.go @@ -285,7 +285,7 @@ func (p *process) Memory() (types.MemoryInfo, error) { p.kinfo = procs[0].kinfo return types.MemoryInfo{ - Resident: uint64(p.kinfo.ki_rssize) * uint64(pageSize), + Resident: uint64(p.kinfo.ki_rssize) * pageSize, Virtual: uint64(p.kinfo.ki_size), }, nil } diff --git a/providers/freebsd/sysctl_freebsd.go b/providers/freebsd/sysctl_freebsd.go index acb20e4..60c9120 100644 --- a/providers/freebsd/sysctl_freebsd.go +++ b/providers/freebsd/sysctl_freebsd.go @@ -42,7 +42,7 @@ var tickDuration = sync.OnceValues(func() (time.Duration, error) { return time.Duration(c.Tick) * time.Microsecond, nil }) -var pageSizeBytes = sync.OnceValues(func() (uint32, error) { +var pageSizeBytes = sync.OnceValues(func() (uint64, error) { const mib = "vm.stats.vm.v_page_size" v, err := unix.SysctlUint32(mib) @@ -50,17 +50,17 @@ var pageSizeBytes = sync.OnceValues(func() (uint32, error) { return 0, fmt.Errorf("failed to get %s: %w", mib, err) } - return v, nil + return uint64(v), nil }) -func activePageCount() (uint32, error) { +func activePageCount() (uint64, error) { const mib = "vm.stats.vm.v_active_count" v, err := unix.SysctlUint32(mib) if err != nil { return 0, fmt.Errorf("failed to get %s: %w", mib, err) } - return v, nil + return uint64(v), nil } func architecture() (string, error) { @@ -98,7 +98,7 @@ func buffersUsedBytes() (uint64, error) { return v, nil } -func cachePageCount() (uint32, error) { +func cachePageCount() (uint64, error) { const mib = "vm.stats.vm.v_cache_count" v, err := unix.SysctlUint32(mib) @@ -106,7 +106,7 @@ func cachePageCount() (uint32, error) { return 0, fmt.Errorf("failed to get %s: %w", mib, err) } - return v, nil + return uint64(v), nil } const sizeOfUint64 = int(unsafe.Sizeof(uint64(0))) @@ -143,7 +143,7 @@ func cpuStateTimes() (*types.CPUTimes, error) { }, nil } -func freePageCount() (uint32, error) { +func freePageCount() (uint64, error) { const mib = "vm.stats.vm.v_free_count" v, err := unix.SysctlUint32(mib) @@ -151,10 +151,10 @@ func freePageCount() (uint32, error) { return 0, fmt.Errorf("failed to get %s: %w", mib, err) } - return v, nil + return uint64(v), nil } -func inactivePageCount() (uint32, error) { +func inactivePageCount() (uint64, error) { const mib = "vm.stats.vm.v_inactive_count" v, err := unix.SysctlUint32(mib) @@ -162,7 +162,7 @@ func inactivePageCount() (uint32, error) { return 0, fmt.Errorf("failed to get %s: %w", mib, err) } - return v, nil + return uint64(v), nil } func kernelVersion() (string, error) { @@ -237,12 +237,12 @@ func totalPhysicalMem() (uint64, error) { return v, nil } -func wirePageCount() (uint32, error) { +func wirePageCount() (uint64, error) { const mib = "vm.stats.vm.v_wire_count" v, err := unix.SysctlUint32(mib) if err != nil { return 0, fmt.Errorf("failed to get %s: %w", mib, err) } - return v, nil + return uint64(v), nil } From d3d45dfe19a278a4d801c991f9a6068046fe4c15 Mon Sep 17 00:00:00 2001 From: "Saro G." Date: Wed, 19 Jun 2024 13:17:54 -0400 Subject: [PATCH 3/4] Use mib const in sysctlRaw() --- providers/freebsd/sysctl_freebsd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/freebsd/sysctl_freebsd.go b/providers/freebsd/sysctl_freebsd.go index 60c9120..52a51df 100644 --- a/providers/freebsd/sysctl_freebsd.go +++ b/providers/freebsd/sysctl_freebsd.go @@ -120,7 +120,7 @@ func cpuStateTimes() (*types.CPUTimes, error) { } const mib = "kern.cp_time" - buf, err := unix.SysctlRaw("kern.cp_time") + buf, err := unix.SysctlRaw(mib) if err != nil { return nil, fmt.Errorf("failed to get %s: %w", mib, err) } From bbb75c4687b7190303dcbfeff01cdfab1320069e Mon Sep 17 00:00:00 2001 From: "Saro G." Date: Wed, 19 Jun 2024 15:22:18 -0400 Subject: [PATCH 4/4] memInfo(): be less optimistic --- providers/freebsd/host_freebsd_cgo.go | 35 ++++------------- providers/freebsd/sysctl_freebsd.go | 56 +++++++++++++-------------- 2 files changed, 35 insertions(+), 56 deletions(-) diff --git a/providers/freebsd/host_freebsd_cgo.go b/providers/freebsd/host_freebsd_cgo.go index 15fc9ae..3b09fe3 100644 --- a/providers/freebsd/host_freebsd_cgo.go +++ b/providers/freebsd/host_freebsd_cgo.go @@ -133,46 +133,25 @@ func (r *reader) memInfo(m *types.HostMemoryInfo) { return } - m.Total, err = totalPhysicalMem() - if r.addErr(err) { - return - } + m.Total = totalPhysicalMem(r) + activePages := activePageCount(r) - activePages, err := activePageCount() - if r.addErr(err) { - return - } m.Metrics = make(map[string]uint64, 6) m.Metrics["active_bytes"] = activePages * pageSize - wirePages, err := wirePageCount() - if r.addErr(err) { - return - } + wirePages := wirePageCount(r) m.Metrics["wired_bytes"] = wirePages * pageSize - inactivePages, err := inactivePageCount() - if r.addErr(err) { - return - } + inactivePages := inactivePageCount(r) m.Metrics["inactive_bytes"] = inactivePages * pageSize - cachePages, err := cachePageCount() - if r.addErr(err) { - return - } + cachePages := cachePageCount(r) m.Metrics["cache_bytes"] = cachePages * pageSize - freePages, err := freePageCount() - if r.addErr(err) { - return - } + freePages := freePageCount(r) m.Metrics["free_bytes"] = freePages * pageSize - buffers, err := buffersUsedBytes() - if r.addErr(err) { - return - } + buffers := buffersUsedBytes(r) m.Metrics["buffer_bytes"] = buffers m.Used = (activePages + wirePages) * pageSize diff --git a/providers/freebsd/sysctl_freebsd.go b/providers/freebsd/sysctl_freebsd.go index 52a51df..0e3e15a 100644 --- a/providers/freebsd/sysctl_freebsd.go +++ b/providers/freebsd/sysctl_freebsd.go @@ -53,14 +53,14 @@ var pageSizeBytes = sync.OnceValues(func() (uint64, error) { return uint64(v), nil }) -func activePageCount() (uint64, error) { +func activePageCount(r *reader) uint64 { const mib = "vm.stats.vm.v_active_count" v, err := unix.SysctlUint32(mib) - if err != nil { - return 0, fmt.Errorf("failed to get %s: %w", mib, err) + if r.addErr(err) { + return 0 } - return uint64(v), nil + return uint64(v) } func architecture() (string, error) { @@ -87,26 +87,26 @@ func bootTime() (time.Time, error) { } // buffersUsedBytes returns the number memory bytes used as disk cache. -func buffersUsedBytes() (uint64, error) { +func buffersUsedBytes(r *reader) uint64 { const mib = "vfs.bufspace" v, err := unix.SysctlUint64(mib) - if err != nil { - return 0, fmt.Errorf("failed to get %s: %w", mib, err) + if r.addErr(err) { + return 0 } - return v, nil + return v } -func cachePageCount() (uint64, error) { +func cachePageCount(r *reader) uint64 { const mib = "vm.stats.vm.v_cache_count" v, err := unix.SysctlUint32(mib) - if err != nil { - return 0, fmt.Errorf("failed to get %s: %w", mib, err) + if r.addErr(err) { + return 0 } - return uint64(v), nil + return uint64(v) } const sizeOfUint64 = int(unsafe.Sizeof(uint64(0))) @@ -143,26 +143,26 @@ func cpuStateTimes() (*types.CPUTimes, error) { }, nil } -func freePageCount() (uint64, error) { +func freePageCount(r *reader) uint64 { const mib = "vm.stats.vm.v_free_count" v, err := unix.SysctlUint32(mib) - if err != nil { - return 0, fmt.Errorf("failed to get %s: %w", mib, err) + if r.addErr(err) { + return 0 } - return uint64(v), nil + return uint64(v) } -func inactivePageCount() (uint64, error) { +func inactivePageCount(r *reader) uint64 { const mib = "vm.stats.vm.v_inactive_count" v, err := unix.SysctlUint32(mib) - if err != nil { - return 0, fmt.Errorf("failed to get %s: %w", mib, err) + if r.addErr(err) { + return 0 } - return uint64(v), nil + return uint64(v) } func kernelVersion() (string, error) { @@ -227,22 +227,22 @@ func operatingSystem() (*types.OSInfo, error) { return info, nil } -func totalPhysicalMem() (uint64, error) { +func totalPhysicalMem(r *reader) uint64 { const mib = "hw.physmem" v, err := unix.SysctlUint64(mib) - if err != nil { - return 0, fmt.Errorf("failed to get %s: %w", mib, err) + if r.addErr(err) { + return 0 } - return v, nil + return v } -func wirePageCount() (uint64, error) { +func wirePageCount(r *reader) uint64 { const mib = "vm.stats.vm.v_wire_count" v, err := unix.SysctlUint32(mib) - if err != nil { - return 0, fmt.Errorf("failed to get %s: %w", mib, err) + if r.addErr(err) { + return 0 } - return uint64(v), nil + return uint64(v) }