mirror of
https://github.com/weaveworks/scope.git
synced 2026-02-14 18:09:59 +00:00
Use Utsname from golang.org/x/sys/unix which contains byte array instead of int8/uint8 array members. This allows to simplify the string conversions of these members and the marshal.FromUtsname functions are no longer needed.
111 lines
2.9 KiB
Go
111 lines
2.9 KiB
Go
package host
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
linuxproc "github.com/c9s/goprocinfo/linux"
|
|
|
|
"github.com/weaveworks/scope/report"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
const kb = 1024
|
|
|
|
// Uname is swappable for mocking in tests.
|
|
var Uname = unix.Uname
|
|
|
|
// GetKernelReleaseAndVersion returns the kernel version as reported by uname.
|
|
var GetKernelReleaseAndVersion = func() (string, string, error) {
|
|
var utsname unix.Utsname
|
|
if err := Uname(&utsname); err != nil {
|
|
return "unknown", "unknown", err
|
|
}
|
|
release := utsname.Release[:bytes.IndexByte(utsname.Release[:], 0)]
|
|
version := utsname.Version[:bytes.IndexByte(utsname.Version[:], 0)]
|
|
return string(release), string(version), nil
|
|
}
|
|
|
|
// GetLoad returns the current load averages as metrics.
|
|
var GetLoad = func(now time.Time) report.Metrics {
|
|
buf, err := ioutil.ReadFile("/proc/loadavg")
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
toks := strings.Fields(string(buf))
|
|
if len(toks) < 3 {
|
|
return nil
|
|
}
|
|
one, err := strconv.ParseFloat(toks[0], 64)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return report.Metrics{
|
|
Load1: report.MakeSingletonMetric(now, one),
|
|
}
|
|
}
|
|
|
|
// GetUptime returns the uptime of the host.
|
|
var GetUptime = func() (time.Duration, error) {
|
|
buf, err := ioutil.ReadFile("/proc/uptime")
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
fields := strings.Fields(string(buf))
|
|
if len(fields) != 2 {
|
|
return 0, fmt.Errorf("invalid format: %s", string(buf))
|
|
}
|
|
|
|
uptime, err := strconv.ParseFloat(fields[0], 64)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return time.Duration(uptime) * time.Second, nil
|
|
}
|
|
|
|
var previousStat = linuxproc.CPUStat{}
|
|
|
|
// GetCPUUsagePercent returns the percent cpu usage and max (i.e. 100% or 0 if unavailable)
|
|
var GetCPUUsagePercent = func() (float64, float64) {
|
|
stat, err := linuxproc.ReadStat(ProcStat)
|
|
if err != nil {
|
|
return 0.0, 0.0
|
|
}
|
|
|
|
// From http://stackoverflow.com/questions/23367857/accurate-calculation-of-cpu-usage-given-in-percentage-in-linux
|
|
var (
|
|
currentStat = stat.CPUStatAll
|
|
prevIdle = previousStat.Idle + previousStat.IOWait
|
|
idle = currentStat.Idle + currentStat.IOWait
|
|
prevNonIdle = (previousStat.User + previousStat.Nice + previousStat.System +
|
|
previousStat.IRQ + previousStat.SoftIRQ + previousStat.Steal)
|
|
nonIdle = (currentStat.User + currentStat.Nice + currentStat.System +
|
|
currentStat.IRQ + currentStat.SoftIRQ + currentStat.Steal)
|
|
prevTotal = prevIdle + prevNonIdle
|
|
total = idle + nonIdle
|
|
// differentiate: actual value minus the previous one
|
|
totald = total - prevTotal
|
|
idled = idle - prevIdle
|
|
)
|
|
previousStat = currentStat
|
|
return float64(totald-idled) * 100. / float64(totald), 100.
|
|
}
|
|
|
|
// GetMemoryUsageBytes returns the bytes memory usage and max
|
|
var GetMemoryUsageBytes = func() (float64, float64) {
|
|
meminfo, err := linuxproc.ReadMemInfo(ProcMemInfo)
|
|
if err != nil {
|
|
return 0.0, 0.0
|
|
}
|
|
|
|
used := meminfo.MemTotal - meminfo.MemFree - meminfo.Buffers - meminfo.Cached
|
|
return float64(used * kb), float64(meminfo.MemTotal * kb)
|
|
}
|