From 5deb9ec67da9d79b653d9bb2bc4c4856c9caa7c9 Mon Sep 17 00:00:00 2001 From: Zhang Yu Date: Thu, 22 Jun 2017 10:51:29 +0800 Subject: [PATCH 1/3] add MemAvailable --- meminfo.go | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/meminfo.go b/meminfo.go index 25903498..fbb3b5d4 100644 --- a/meminfo.go +++ b/meminfo.go @@ -12,28 +12,30 @@ import ( ) type Mem struct { - Buffers uint64 - Cached uint64 - MemTotal uint64 - MemFree uint64 - SwapTotal uint64 - SwapUsed uint64 - SwapFree uint64 + Buffers uint64 + Cached uint64 + MemTotal uint64 + MemFree uint64 + MemAvailable uint64 + SwapTotal uint64 + SwapUsed uint64 + SwapFree uint64 } func (this *Mem) String() string { - return fmt.Sprintf("", this.MemTotal, this.MemFree, this.Buffers, this.Cached) + return fmt.Sprintf("", this.MemTotal, this.MemFree, this.MemAvailable, this.Buffers, this.Cached) } var Multi uint64 = 1024 var WANT = map[string]struct{}{ - "Buffers:": struct{}{}, - "Cached:": struct{}{}, - "MemTotal:": struct{}{}, - "MemFree:": struct{}{}, - "SwapTotal:": struct{}{}, - "SwapFree:": struct{}{}, + "Buffers:": struct{}{}, + "Cached:": struct{}{}, + "MemTotal:": struct{}{}, + "MemFree:": struct{}{}, + "MemAvailable:": struct{}{}, + "SwapTotal:": struct{}{}, + "SwapFree:": struct{}{}, } func MemInfo() (*Mem, error) { @@ -73,6 +75,8 @@ func MemInfo() (*Mem, error) { memInfo.MemTotal = val * Multi case "MemFree:": memInfo.MemFree = val * Multi + case "MemAvailable:": + memInfo.MemAvailable = val * Multi case "SwapTotal:": memInfo.SwapTotal = val * Multi case "SwapFree:": From fc9a1b824dc15bdc26743a2bf8171ebae2f30fe6 Mon Sep 17 00:00:00 2001 From: Zhang Yu Date: Fri, 2 Nov 2018 09:28:51 +0800 Subject: [PATCH 2/3] add tmpfs overlay to fspec ignore --- dfstat.go | 2 ++ dfstat_linux.go | 36 ++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/dfstat.go b/dfstat.go index cc663a06..ff15611e 100644 --- a/dfstat.go +++ b/dfstat.go @@ -17,6 +17,8 @@ var FSTYPE_IGNORE = map[string]struct{}{ "devtmpfs": struct{}{}, "rpc_pipefs": struct{}{}, "rootfs": struct{}{}, + "overlay": struct{}{}, + "tmpfs": struct{}{}, } var FSFILE_PREFIX_IGNORE = []string{ diff --git a/dfstat_linux.go b/dfstat_linux.go index 19ff46f5..f3c77cd1 100644 --- a/dfstat_linux.go +++ b/dfstat_linux.go @@ -12,7 +12,7 @@ import ( "github.com/toolkits/file" ) -// return: [][$fs_spec, $fs_file, $fs_vfstype] +// return: [][$fsSpec, $fsFile, $fsVfstype] func ListMountPoint() ([][3]string, error) { contents, err := ioutil.ReadFile("/proc/mounts") if err != nil { @@ -33,50 +33,50 @@ func ListMountPoint() ([][3]string, error) { fields := strings.Fields(string(line)) // Docs come from the fstab(5) - // fs_spec # Mounted block special device or remote filesystem e.g. /dev/sda1 - // fs_file # Mount point e.g. /data - // fs_vfstype # File system type e.g. ext4 + // fsSpec # Mounted block special device or remote filesystem e.g. /dev/sda1 + // fsFile # Mount point e.g. /data + // fsVfstype # File system type e.g. ext4 // fs_mntops # Mount options // fs_freq # Dump(8) utility flags // fs_passno # Order in which filesystem checks are done at reboot time - fs_spec := fields[0] - fs_file := fields[1] - fs_vfstype := fields[2] + fsSpec := fields[0] + fsFile := fields[1] + fsVfstype := fields[2] - if _, exist := FSSPEC_IGNORE[fs_spec]; exist { + if _, exist := FSSPEC_IGNORE[fsSpec]; exist { continue } - if _, exist := FSTYPE_IGNORE[fs_vfstype]; exist { + if _, exist := FSTYPE_IGNORE[fsVfstype]; exist { continue } - if strings.HasPrefix(fs_vfstype, "fuse") { + if strings.HasPrefix(fsVfstype, "fuse") { continue } - if IgnoreFsFile(fs_file) { + if IgnoreFsFile(fsFile) { continue } - // keep /dev/xxx device with shorter fs_file (remove mount binds) - if strings.HasPrefix(fs_spec, "/dev") { + // keep /dev/xxx device with shorter fsFile (remove mount binds) + if strings.HasPrefix(fsSpec, "/dev") { deviceFound := false for idx := range ret { - if ret[idx][0] == fs_spec { + if ret[idx][0] == fsSpec { deviceFound = true - if len(fs_file) < len(ret[idx][1]) { - ret[idx][1] = fs_file + if len(fsFile) < len(ret[idx][1]) { + ret[idx][1] = fsFile } break } } if !deviceFound { - ret = append(ret, [3]string{fs_spec, fs_file, fs_vfstype}) + ret = append(ret, [3]string{fsSpec, fsFile, fsVfstype}) } } else { - ret = append(ret, [3]string{fs_spec, fs_file, fs_vfstype}) + ret = append(ret, [3]string{fsSpec, fsFile, fsVfstype}) } } return ret, nil From a4330261de4208818151849d971229a308ba85a8 Mon Sep 17 00:00:00 2001 From: Zhang Yu Date: Tue, 6 Nov 2018 20:14:07 +0800 Subject: [PATCH 3/3] add running and total processes --- loadavg.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/loadavg.go b/loadavg.go index 4388f6cc..b6b833f3 100644 --- a/loadavg.go +++ b/loadavg.go @@ -1,6 +1,7 @@ package nux import ( + "errors" "fmt" "github.com/toolkits/file" "strconv" @@ -8,13 +9,15 @@ import ( ) type Loadavg struct { - Avg1min float64 - Avg5min float64 - Avg15min float64 + Avg1min float64 + Avg5min float64 + Avg15min float64 + RunningProcesses int64 + TotalProcesses int64 } -func (this *Loadavg) String() string { - return fmt.Sprintf("<1min:%f, 5min:%f, 15min:%f>", this.Avg1min, this.Avg5min, this.Avg15min) +func (load *Loadavg) String() string { + return fmt.Sprintf("<1min:%f, 5min:%f, 15min:%f, processes:%d/%d>", load.Avg1min, load.Avg5min, load.Avg15min, load.RunningProcesses, load.TotalProcesses) } func LoadAvg() (*Loadavg, error) { @@ -36,6 +39,16 @@ func LoadAvg() (*Loadavg, error) { if loadAvg.Avg15min, err = strconv.ParseFloat(L[2], 64); err != nil { return nil, err } + processes := strings.SplitN(L[3], "/", 2) + if len(processes) != 2 { + return nil, errors.New("invalid loadavg " + data) + } + if loadAvg.RunningProcesses, err = strconv.ParseInt(processes[0], 10, 64); err != nil { + return nil, err + } + if loadAvg.TotalProcesses, err = strconv.ParseInt(processes[1], 10, 64); err != nil { + return nil, err + } return &loadAvg, nil }