process_io.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package linux
  2. import (
  3. "io/ioutil"
  4. "reflect"
  5. "strconv"
  6. "strings"
  7. )
  8. // I/O statistics for the process.
  9. type ProcessIO struct {
  10. RChar uint64 `json:"rchar" field:"rchar"` // chars read
  11. WChar uint64 `json:"wchar" field:"wchar"` // chars written
  12. Syscr uint64 `json:"syscr" field:"syscr"` // read syscalls
  13. Syscw uint64 `json:"syscw" field:"syscw"` // write syscalls
  14. ReadBytes uint64 `json:"read_bytes" field:"read_bytes"` // bytes read
  15. WriteBytes uint64 `json:"write_bytes" field:"write_bytes"` // bytes written
  16. CancelledWriteBytes uint64 `json:"cancelled_write_bytes" field:"cancelled_write_bytes"` // bytes truncated
  17. }
  18. func ReadProcessIO(path string) (*ProcessIO, error) {
  19. b, err := ioutil.ReadFile(path)
  20. if err != nil {
  21. return nil, err
  22. }
  23. // Maps a io metric to its value (i.e. rchar --> 100000)
  24. m := map[string]uint64{}
  25. io := ProcessIO{}
  26. lines := strings.Split(string(b), "\n")
  27. for _, line := range lines {
  28. if strings.Index(line, ": ") == -1 {
  29. continue
  30. }
  31. l := strings.Split(line, ": ")
  32. k := l[0]
  33. v, err := strconv.ParseUint(l[1], 10, 64)
  34. if err != nil {
  35. return nil, err
  36. }
  37. m[k] = v
  38. }
  39. e := reflect.ValueOf(&io).Elem()
  40. t := e.Type()
  41. for i := 0; i < e.NumField(); i++ {
  42. k := t.Field(i).Tag.Get("field")
  43. v, ok := m[k]
  44. if ok {
  45. e.Field(i).SetUint(v)
  46. }
  47. }
  48. return &io, nil
  49. }