mirror of https://github.com/shirou/gopsutil
initial import.
parent
4c1052f036
commit
5b605dc1a3
@ -0,0 +1,10 @@
|
|||||||
|
gopsutil: psutil for golang
|
||||||
|
==============================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- psutil: http://pythonhosted.org/psutil/
|
||||||
|
- dstat: https://github.com/dagwieers/dstat
|
||||||
|
- gosiger: https://github.com/cloudfoundry/gosigar/
|
||||||
|
- goprocinfo: https://github.com/c9s/goprocinfo
|
@ -0,0 +1,27 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Read contents from file and split by new line.
|
||||||
|
func ReadLines(filename string) ([]string, error) {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return []string{""}, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
ret := make([]string, 0)
|
||||||
|
|
||||||
|
r := bufio.NewReader(f)
|
||||||
|
line, err := r.ReadString('\n')
|
||||||
|
for err == nil {
|
||||||
|
ret = append(ret, strings.Trim(line, "\n"))
|
||||||
|
line, err = r.ReadString('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, err
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CPU struct{}
|
||||||
|
|
||||||
|
type CPU_Times struct {
|
||||||
|
Cpu string `json:"cpu"`
|
||||||
|
User uint64 `json:"user"`
|
||||||
|
System uint64 `json:"system"`
|
||||||
|
Idle uint64 `json:"idle"`
|
||||||
|
Nice uint64 `json:"nice"`
|
||||||
|
Iowait uint64 `json:"iowait"`
|
||||||
|
Irq uint64 `json:"irq"`
|
||||||
|
Softirq uint64 `json:"softirq"`
|
||||||
|
Steal uint64 `json:"steal"`
|
||||||
|
Guest uint64 `json:"guest"`
|
||||||
|
Guest_nice uint64 `json:"guest_nice"`
|
||||||
|
Stolen uint64 `json:"stolen"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCPU() CPU {
|
||||||
|
p := CPU{}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CPU) Cpu_counts() (int, error) {
|
||||||
|
return runtime.NumCPU(), nil
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
// +build freebsd
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c CPU) Cpu_times() map[string]string {
|
||||||
|
ret := make(map[string]string)
|
||||||
|
|
||||||
|
fmt.Println("FreeBSD")
|
||||||
|
return ret
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
// +build linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c CPU) Cpu_times() ([]CPU_Times, error) {
|
||||||
|
ret := make([]CPU_Times, 0)
|
||||||
|
|
||||||
|
filename := "/proc/stat"
|
||||||
|
lines, _ := ReadLines(filename)
|
||||||
|
for _, line := range lines {
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
|
||||||
|
if strings.HasPrefix(fields[0], "cpu") == false {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu := fields[0]
|
||||||
|
if cpu == "cpu" {
|
||||||
|
cpu = "cpu-total"
|
||||||
|
}
|
||||||
|
user, _ := strconv.ParseUint(fields[1], 10, 64)
|
||||||
|
nice, _ := strconv.ParseUint(fields[2], 10, 64)
|
||||||
|
system, _ := strconv.ParseUint(fields[3], 10, 64)
|
||||||
|
idle, _ := strconv.ParseUint(fields[4], 10, 64)
|
||||||
|
iowait, _ := strconv.ParseUint(fields[5], 10, 64)
|
||||||
|
irq, _ := strconv.ParseUint(fields[6], 10, 64)
|
||||||
|
softirq, _ := strconv.ParseUint(fields[7], 10, 64)
|
||||||
|
stolen, _ := strconv.ParseUint(fields[8], 10, 64)
|
||||||
|
ct := CPU_Times{
|
||||||
|
Cpu: cpu,
|
||||||
|
User: user,
|
||||||
|
Nice: nice,
|
||||||
|
System: system,
|
||||||
|
Idle: idle,
|
||||||
|
Iowait: iowait,
|
||||||
|
Irq: irq,
|
||||||
|
Softirq: softirq,
|
||||||
|
Stolen: stolen,
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = append(ret, ct)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCpu_times(t *testing.T) {
|
||||||
|
cpu := NewCPU()
|
||||||
|
|
||||||
|
v, err := cpu.Cpu_times()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
if len(v) == 0 {
|
||||||
|
t.Errorf("could not get CPUs ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, vv := range v {
|
||||||
|
if vv.User == 0 {
|
||||||
|
t.Errorf("could not get CPU User: %v", vv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCpu_counts(t *testing.T) {
|
||||||
|
cpu := NewCPU()
|
||||||
|
|
||||||
|
v, err := cpu.Cpu_counts()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
if v == 0 {
|
||||||
|
t.Errorf("could not get CPU counts: %v", v)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Disk struct{}
|
||||||
|
|
||||||
|
type Disk_usage struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
Total uint64 `json:"total"`
|
||||||
|
Free uint64 `json:"free"`
|
||||||
|
Available uint64 `json:"available"`
|
||||||
|
Used uint64 `json:"used"`
|
||||||
|
Percent float64 `json:"percent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Disk_IO_Counters struct {
|
||||||
|
ReadCount uint64 `json:"readCount"`
|
||||||
|
WriteCount uint64 `json:"writeCount"`
|
||||||
|
ReadBytes uint64 `json:"readBytes"`
|
||||||
|
WriteBytes uint64 `json:"writeBytes"`
|
||||||
|
ReadTime uint64 `json:"readTime"`
|
||||||
|
WriteTime uint64 `json:"writeTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDisk() Disk {
|
||||||
|
d := Disk{}
|
||||||
|
return d
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDisk_usage(t *testing.T) {
|
||||||
|
disk := NewDisk()
|
||||||
|
|
||||||
|
v, err := disk.Disk_usage("/")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
d, _ := json.Marshal(v)
|
||||||
|
fmt.Printf("%s\n", d)
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
// +build freebsd linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func (d Disk) Disk_usage(path string) (Disk_usage, error) {
|
||||||
|
stat := syscall.Statfs_t{}
|
||||||
|
err := syscall.Statfs(path, &stat)
|
||||||
|
if err != nil {
|
||||||
|
return Disk_usage{Path: path}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bsize := stat.Bsize / 512
|
||||||
|
|
||||||
|
ret := Disk_usage{
|
||||||
|
Path: path,
|
||||||
|
Total: (uint64(stat.Blocks) * uint64(bsize)) >> 1,
|
||||||
|
Free: (uint64(stat.Bfree) * uint64(bsize)) >> 1,
|
||||||
|
Available: (uint64(stat.Bavail) * uint64(bsize)) >> 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.Used = (ret.Total - ret.Free)
|
||||||
|
ret.Percent = (float64(ret.Used) / float64(ret.Total)) * 100.0
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Host struct{}
|
||||||
|
|
||||||
|
type HostInfo struct {
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
Uptime int64 `json:"uptime"`
|
||||||
|
Procs uint64 `json:"procs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHost() Host {
|
||||||
|
h := Host{}
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Host) HostInfo() (HostInfo, error) {
|
||||||
|
ret := HostInfo{}
|
||||||
|
sysinfo := &syscall.Sysinfo_t{}
|
||||||
|
|
||||||
|
if err := syscall.Sysinfo(sysinfo); err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret.Hostname = hostname
|
||||||
|
ret.Uptime = sysinfo.Uptime
|
||||||
|
ret.Procs = uint64(sysinfo.Procs)
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHostInfo(t *testing.T) {
|
||||||
|
host := NewHost()
|
||||||
|
|
||||||
|
v, err := host.HostInfo()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
if v.Uptime == 0 {
|
||||||
|
t.Errorf("Could not get uptime %v", v)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Load struct{}
|
||||||
|
|
||||||
|
type LoadAvg struct {
|
||||||
|
Load1 float64 `json:"load1"`
|
||||||
|
Load5 float64 `json:"load5"`
|
||||||
|
Load15 float64 `json:"load15"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLoad() Load {
|
||||||
|
l := Load{}
|
||||||
|
return l
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
// +build freebsd
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l Load) LoadAvg() (LoadAvg, error) {
|
||||||
|
out, err := exec.Command("/sbin/sysctl", "-n", "vm.loadavg").Output()
|
||||||
|
if err != nil {
|
||||||
|
return LoadAvg{}, err
|
||||||
|
}
|
||||||
|
v := strings.Replace(string(out), "{ ", "", 1)
|
||||||
|
v = strings.Replace(string(v), " }", "", 1)
|
||||||
|
values := strings.Fields(string(v))
|
||||||
|
|
||||||
|
load1, err := strconv.ParseFloat(values[0], 32)
|
||||||
|
if err != nil {
|
||||||
|
return LoadAvg{}, err
|
||||||
|
}
|
||||||
|
load5, err := strconv.ParseFloat(values[1], 32)
|
||||||
|
if err != nil {
|
||||||
|
return LoadAvg{}, err
|
||||||
|
}
|
||||||
|
load15, err := strconv.ParseFloat(values[2], 32)
|
||||||
|
if err != nil {
|
||||||
|
return LoadAvg{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := LoadAvg{
|
||||||
|
Load1: float32(load1),
|
||||||
|
Load5: float32(load5),
|
||||||
|
Load15: float32(load15),
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
// +build linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l Load) LoadAvg() (LoadAvg, error) {
|
||||||
|
filename := "/proc/loadavg"
|
||||||
|
line, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return LoadAvg{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
values := strings.Fields(string(line))
|
||||||
|
|
||||||
|
load1, err := strconv.ParseFloat(values[0], 64)
|
||||||
|
if err != nil {
|
||||||
|
return LoadAvg{}, err
|
||||||
|
}
|
||||||
|
load5, err := strconv.ParseFloat(values[1], 64)
|
||||||
|
if err != nil {
|
||||||
|
return LoadAvg{}, err
|
||||||
|
}
|
||||||
|
load15, err := strconv.ParseFloat(values[2], 64)
|
||||||
|
if err != nil {
|
||||||
|
return LoadAvg{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := LoadAvg{
|
||||||
|
Load1: load1,
|
||||||
|
Load5: load5,
|
||||||
|
Load15: load15,
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
// +build linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLoad(t *testing.T) {
|
||||||
|
load := NewLoad()
|
||||||
|
|
||||||
|
v, err := load.LoadAvg()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Load1 == 0 || v.Load5 == 0 || v.Load15 == 0 {
|
||||||
|
t.Errorf("error load: %v", v)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Mem struct{}
|
||||||
|
|
||||||
|
type Virtual_memory struct {
|
||||||
|
Total uint64 `json:"total"`
|
||||||
|
Available uint64 `json:"available"`
|
||||||
|
Used uint64 `json:"used"`
|
||||||
|
UsedPercent float64 `json:"usedPercent"`
|
||||||
|
Free uint64 `json:"free"`
|
||||||
|
Active uint64 `json:"active"`
|
||||||
|
Inactive uint64 `json:"inactive"`
|
||||||
|
Buffers uint64 `json:"buffers"`
|
||||||
|
Cached uint64 `json:"cached"`
|
||||||
|
Wired uint64 `json:"wired"`
|
||||||
|
Shared uint64 `json:"shared"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Swap_memory struct {
|
||||||
|
Total uint64 `json:"total"`
|
||||||
|
Used uint64 `json:"used"`
|
||||||
|
Free uint64 `json:"free"`
|
||||||
|
UsedPercent float64 `json:"usedPercent"`
|
||||||
|
Sin uint64 `json:"sin"`
|
||||||
|
Sout uint64 `json:"sout"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMem() Mem {
|
||||||
|
m := Mem{}
|
||||||
|
return m
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
// +build freebsd linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m Mem) Virtual_memory() (Virtual_memory, error) {
|
||||||
|
ret := Virtual_memory{}
|
||||||
|
sysinfo := &syscall.Sysinfo_t{}
|
||||||
|
|
||||||
|
if err := syscall.Sysinfo(sysinfo); err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret.Total = uint64(sysinfo.Totalram)
|
||||||
|
ret.Free = uint64(sysinfo.Freeram)
|
||||||
|
ret.Shared = uint64(sysinfo.Sharedram)
|
||||||
|
ret.Buffers = uint64(sysinfo.Bufferram)
|
||||||
|
|
||||||
|
ret.Used = ret.Total - ret.Free
|
||||||
|
|
||||||
|
// TODO: platform independent
|
||||||
|
ret.Available = ret.Free + ret.Buffers + ret.Cached
|
||||||
|
|
||||||
|
ret.Used = ret.Total - ret.Free
|
||||||
|
ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0
|
||||||
|
|
||||||
|
/*
|
||||||
|
kern := buffers + cached
|
||||||
|
ret.ActualFree = ret.Free + kern
|
||||||
|
ret.ActualUsed = ret.Used - kern
|
||||||
|
*/
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Mem) Swap_memory() (Swap_memory, error) {
|
||||||
|
ret := Swap_memory{}
|
||||||
|
sysinfo := &syscall.Sysinfo_t{}
|
||||||
|
|
||||||
|
if err := syscall.Sysinfo(sysinfo); err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret.Total = sysinfo.Totalswap
|
||||||
|
ret.Free = sysinfo.Freeswap
|
||||||
|
ret.Used = ret.Total - ret.Free
|
||||||
|
ret.UsedPercent = float64(ret.Total-ret.Free) / float64(ret.Total) * 100.0
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestVirtual_memory(t *testing.T) {
|
||||||
|
mem := NewMem()
|
||||||
|
|
||||||
|
v, err := mem.Virtual_memory()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
d, _ := json.Marshal(v)
|
||||||
|
fmt.Printf("%s\n", d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSwap_memory(t *testing.T) {
|
||||||
|
mem := NewMem()
|
||||||
|
|
||||||
|
v, err := mem.Swap_memory()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
d, _ := json.Marshal(v)
|
||||||
|
fmt.Printf("%s\n", d)
|
||||||
|
}
|
Loading…
Reference in New Issue