sockstat.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package linux
  2. import (
  3. "io/ioutil"
  4. "reflect"
  5. "strconv"
  6. "strings"
  7. )
  8. type SockStat struct {
  9. // sockets:
  10. SocketsUsed uint64 `json:"sockets_used" field:"sockets.used"`
  11. // TCP:
  12. TCPInUse uint64 `json:"tcp_in_use" field:"TCP.inuse"`
  13. TCPOrphan uint64 `json:"tcp_orphan" field:"TCP.orphan"`
  14. TCPTimeWait uint64 `json:"tcp_time_wait" field:"TCP.tw"`
  15. TCPAllocated uint64 `json:"tcp_allocated" field:"TCP.alloc"`
  16. TCPMemory uint64 `json:"tcp_memory" field:"TCP.mem"`
  17. // UDP:
  18. UDPInUse uint64 `json:"udp_in_use" field:"UDP.inuse"`
  19. UDPMemory uint64 `json:"udp_memory" field:"UDP.mem"`
  20. // UDPLITE:
  21. UDPLITEInUse uint64 `json:"udplite_in_use" field:"UDPLITE.inuse"`
  22. // RAW:
  23. RAWInUse uint64 `json:"raw_in_use" field:"RAW.inuse"`
  24. // FRAG:
  25. FRAGInUse uint64 `json:"frag_in_use" field:"FRAG.inuse"`
  26. FRAGMemory uint64 `json:"frag_memory" field:"FRAG.memory"`
  27. }
  28. func ReadSockStat(path string) (*SockStat, error) {
  29. data, err := ioutil.ReadFile(path)
  30. if err != nil {
  31. return nil, err
  32. }
  33. lines := strings.Split(string(data), "\n")
  34. // Maps a meminfo metric to its value (i.e. MemTotal --> 100000)
  35. statMap := map[string]uint64{}
  36. var sockStat SockStat = SockStat{}
  37. for _, line := range lines {
  38. if strings.Index(line, ":") == -1 {
  39. continue
  40. }
  41. statType := line[0:strings.Index(line, ":")] + "."
  42. // The fields have this pattern: inuse 27 orphan 1 tw 23 alloc 31 mem 3
  43. // The stats are grouped into pairs and need to be parsed and placed into the stat map.
  44. key := ""
  45. for k, v := range strings.Fields(line[strings.Index(line, ":")+1:]) {
  46. // Every second field is a value.
  47. if (k+1)%2 != 0 {
  48. key = v
  49. continue
  50. }
  51. val, _ := strconv.ParseUint(v, 10, 64)
  52. statMap[statType+key] = val
  53. }
  54. }
  55. elem := reflect.ValueOf(&sockStat).Elem()
  56. typeOfElem := elem.Type()
  57. for i := 0; i < elem.NumField(); i++ {
  58. val, ok := statMap[typeOfElem.Field(i).Tag.Get("field")]
  59. if ok {
  60. elem.Field(i).SetUint(val)
  61. }
  62. }
  63. return &sockStat, nil
  64. }