Commit 5b605dc1 authored by WAKAYAMA Shirou's avatar WAKAYAMA Shirou Committed by Shirou WAKAYAMA

initial import.

parent 4c1052f0
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
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
}
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
}
// +build freebsd
package main
import (
"fmt"
)
func (c CPU) Cpu_times() map[string]string {
ret := make(map[string]string)
fmt.Println("FreeBSD")
return ret
}
// +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
}
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)
}
}
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
}
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)
}
// +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
}
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
}
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)
}
}
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
}
// +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
}
// +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
}
// +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)
}
}
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
}
// +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
}
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)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment