diff --git a/README.rst b/README.rst index 23b780a..5b763a6 100644 --- a/README.rst +++ b/README.rst @@ -66,6 +66,7 @@ Current Status - virtual_memory (linux, windows) - swap_memory (linux) - disk_partitions (linux, freebsd, windows) + - disk_io_counters (linux) - disk_usage (linux, freebsd, windows) - net_io_counters (linux) - boot_time (linux, freebsd, windows(but little broken)) @@ -103,7 +104,6 @@ Current Status - cpu_percent - cpu_times_percent - - disk_io_counters - net_connections - Process class diff --git a/common.go b/common.go index b1748df..6ebb21c 100644 --- a/common.go +++ b/common.go @@ -68,3 +68,13 @@ func parseUint64(val string) uint64 { vv, _ := strconv.ParseInt(val, 10, 64) return uint64(vv) } + +// Check the target string slice containes src or not +func stringContains(target []string, src string) bool { + for _, t := range target { + if t == src { + return true + } + } + return false +} diff --git a/disk.go b/disk.go index c840923..9bc80ef 100644 --- a/disk.go +++ b/disk.go @@ -22,4 +22,5 @@ type Disk_IO_CountersStat struct { WriteBytes uint64 `json:"writeBytes"` ReadTime uint64 `json:"readTime"` WriteTime uint64 `json:"writeTime"` + Name string `json:"name"` } diff --git a/disk_freebsd.go b/disk_freebsd.go index 366bacb..bcf7ed3 100644 --- a/disk_freebsd.go +++ b/disk_freebsd.go @@ -3,6 +3,7 @@ package gopsutil import ( + "errors" "syscall" "unsafe" ) @@ -81,6 +82,11 @@ func Disk_partitions(all bool) ([]Disk_partitionStat, error) { return ret, nil } +func Disk_io_counters() (map[string]Disk_IO_CountersStat, error) { + ret := make(map[string]Disk_IO_CountersStat, 0) + return ret, errors.New("Not implemented yet") +} + // This is borrowed from pkg/syscall/syscall_freebsd.go // change Statfs_t to Statfs in order to get more information func Getfsstat(buf []Statfs, flags int) (n int, err error) { diff --git a/disk_linux.go b/disk_linux.go index c245bea..8720c46 100644 --- a/disk_linux.go +++ b/disk_linux.go @@ -4,10 +4,11 @@ package gopsutil import ( "strings" + "unicode" ) -const( - MNT_WAIT = 1 +const ( + SECTOR_SIZE = 512 ) // Get disk partitions. @@ -17,11 +18,11 @@ func Disk_partitions(all bool) ([]Disk_partitionStat, error) { filename := "/etc/mtab" lines, err := ReadLines(filename) - if err != nil{ + if err != nil { return ret, err } - for _, line := range lines{ + for _, line := range lines { fields := strings.Fields(line) d := Disk_partitionStat{ Mountpoint: fields[1], @@ -33,3 +34,60 @@ func Disk_partitions(all bool) ([]Disk_partitionStat, error) { return ret, nil } + +func Disk_io_counters() (map[string]Disk_IO_CountersStat, error) { + ret := make(map[string]Disk_IO_CountersStat, 0) + + // determine partitions we want to look for + filename := "/proc/partitions" + lines, err := ReadLines(filename) + if err != nil { + return ret, err + } + partitions := make([]string, 0) + + for _, line := range lines[2:] { + fields := strings.Fields(line) + name := []rune(fields[3]) + + if unicode.IsDigit(name[len(name)-1]) { + partitions = append(partitions, fields[3]) + } else { + // http://code.google.com/p/psutil/issues/detail?id=338 + lenpart := len(partitions) + if lenpart == 0 || strings.HasPrefix(partitions[lenpart-1], fields[3]) { + partitions = append(partitions, fields[3]) + } + } + } + + filename = "/proc/diskstats" + lines, err = ReadLines(filename) + if err != nil { + return ret, err + } + for _, line := range lines { + fields := strings.Fields(line) + name := fields[2] + reads := parseUint64(fields[3]) + rbytes := parseUint64(fields[5]) + rtime := parseUint64(fields[6]) + writes := parseUint64(fields[7]) + wbytes := parseUint64(fields[9]) + wtime := parseUint64(fields[10]) + if stringContains(partitions, name) { + d := Disk_IO_CountersStat{ + Name: name, + ReadBytes: rbytes * SECTOR_SIZE, + WriteBytes: wbytes * SECTOR_SIZE, + ReadCount: reads, + WriteCount: writes, + ReadTime: rtime, + WriteTime: wtime, + } + ret[name] = d + + } + } + return ret, nil +} diff --git a/disk_test.go b/disk_test.go index a372720..8368f76 100644 --- a/disk_test.go +++ b/disk_test.go @@ -1,6 +1,7 @@ package gopsutil import ( + // "fmt" "runtime" "testing" ) @@ -14,8 +15,8 @@ func TestDisk_usage(t *testing.T) { if err != nil { t.Errorf("error %v", err) } -// d, _ := json.Marshal(v) -// fmt.Printf("%s\n", d) + // d, _ := json.Marshal(v) + // fmt.Printf("%s\n", d) } func TestDisk_partitions(t *testing.T) { @@ -24,3 +25,15 @@ func TestDisk_partitions(t *testing.T) { t.Errorf("error %v", err) } } + +func TestDisk_io_counters(t *testing.T) { + ret, err := Disk_io_counters() + if err != nil { + t.Errorf("error %v", err) + } + for _, io := range ret { + if io.Name == "" { + t.Errorf("io_counter error %v", io) + } + } +} diff --git a/disk_windows.go b/disk_windows.go index 8547155..f44f7a2 100644 --- a/disk_windows.go +++ b/disk_windows.go @@ -4,6 +4,7 @@ package gopsutil import ( "bytes" + "errors" "syscall" "unsafe" ) @@ -105,3 +106,8 @@ func Disk_partitions(all bool) ([]Disk_partitionStat, error) { } return ret, nil } + +func Disk_io_counters() (map[string]Disk_IO_CountersStat, error) { + ret := make(map[string]Disk_IO_CountersStat, 0) + return ret, errors.New("Not implemented yet") +} diff --git a/net_linux.go b/net_linux.go index 5faed61..577a462 100644 --- a/net_linux.go +++ b/net_linux.go @@ -9,7 +9,7 @@ import ( func Net_io_counters() ([]Net_io_countersStat, error) { filename := "/proc/net/dev" lines, err := ReadLines(filename) - if err != nil{ + if err != nil { return make([]Net_io_countersStat, 0), err } @@ -19,7 +19,7 @@ func Net_io_counters() ([]Net_io_countersStat, error) { for _, line := range lines[2:] { fields := strings.Fields(line) - if fields[0] == ""{ + if fields[0] == "" { continue } nic := Net_io_countersStat{ diff --git a/process.go b/process.go index a053a6b..e084a89 100644 --- a/process.go +++ b/process.go @@ -1,7 +1,7 @@ package gopsutil type Process struct { - Pid int32 `json:"pid"` + Pid int32 `json:"pid"` } type Open_filesStat struct {