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