process_stat.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. package linux
  2. import (
  3. "io/ioutil"
  4. "regexp"
  5. "strconv"
  6. "strings"
  7. )
  8. // Status information about the process.
  9. type ProcessStat struct {
  10. Pid uint64 `json:"pid"`
  11. Comm string `json:"comm"`
  12. State string `json:"state"`
  13. Ppid int64 `json:"ppid"`
  14. Pgrp int64 `json:"pgrp"`
  15. Session int64 `json:"session"`
  16. TtyNr int64 `json:"tty_nr"`
  17. Tpgid int64 `json:"tpgid"`
  18. Flags uint64 `json:"flags"`
  19. Minflt uint64 `json:"minflt"`
  20. Cminflt uint64 `json:"cminflt"`
  21. Majflt uint64 `json:"majflt"`
  22. Cmajflt uint64 `json:"cmajflt"`
  23. Utime uint64 `json:"utime"`
  24. Stime uint64 `json:"stime"`
  25. Cutime int64 `json:"cutime"`
  26. Cstime int64 `json:"cstime"`
  27. Priority int64 `json:"priority"`
  28. Nice int64 `json:"nice"`
  29. NumThreads int64 `json:"num_threads"`
  30. Itrealvalue int64 `json:"itrealvalue"`
  31. Starttime uint64 `json:"starttime"`
  32. Vsize uint64 `json:"vsize"`
  33. Rss int64 `json:"rss"`
  34. Rsslim uint64 `json:"rsslim"`
  35. Startcode uint64 `json:"startcode"`
  36. Endcode uint64 `json:"endcode"`
  37. Startstack uint64 `json:"startstack"`
  38. Kstkesp uint64 `json:"kstkesp"`
  39. Kstkeip uint64 `json:"kstkeip"`
  40. Signal uint64 `json:"signal"`
  41. Blocked uint64 `json:"blocked"`
  42. Sigignore uint64 `json:"sigignore"`
  43. Sigcatch uint64 `json:"sigcatch"`
  44. Wchan uint64 `json:"wchan"`
  45. Nswap uint64 `json:"nswap"`
  46. Cnswap uint64 `json:"cnswap"`
  47. ExitSignal int64 `json:"exit_signal"`
  48. Processor int64 `json:"processor"`
  49. RtPriority uint64 `json:"rt_priority"`
  50. Policy uint64 `json:"policy"`
  51. DelayacctBlkioTicks uint64 `json:"delayacct_blkio_ticks"`
  52. GuestTime uint64 `json:"guest_time"`
  53. CguestTime int64 `json:"cguest_time"`
  54. StartData uint64 `json:"start_data"`
  55. EndData uint64 `json:"end_data"`
  56. StartBrk uint64 `json:"start_brk"`
  57. ArgStart uint64 `json:"arg_start"`
  58. ArgEnd uint64 `json:"arg_end"`
  59. EnvStart uint64 `json:"env_start"`
  60. EnvEnd uint64 `json:"env_end"`
  61. ExitCode int64 `json:"exit_code"`
  62. }
  63. var processStatRegExp = regexp.MustCompile("^(\\d+)( \\(.*?\\) )(.*)$")
  64. func ReadProcessStat(path string) (*ProcessStat, error) {
  65. b, err := ioutil.ReadFile(path)
  66. if err != nil {
  67. return nil, err
  68. }
  69. s := string(b)
  70. f := make([]string, 0, 32)
  71. e := processStatRegExp.FindStringSubmatch(strings.TrimSpace(s))
  72. // Inject process Pid
  73. f = append(f, e[1])
  74. // Inject process Comm
  75. f = append(f, strings.TrimSpace(e[2]))
  76. // Inject all remaining process info
  77. f = append(f, (strings.Fields(e[3]))...)
  78. stat := ProcessStat{}
  79. for i := 0; i < len(f); i++ {
  80. switch i {
  81. case 0:
  82. if stat.Pid, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  83. return nil, err
  84. }
  85. case 1:
  86. stat.Comm = f[i]
  87. case 2:
  88. stat.State = f[i]
  89. case 3:
  90. if stat.Ppid, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  91. return nil, err
  92. }
  93. case 4:
  94. if stat.Pgrp, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  95. return nil, err
  96. }
  97. case 5:
  98. if stat.Session, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  99. return nil, err
  100. }
  101. case 6:
  102. if stat.TtyNr, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  103. return nil, err
  104. }
  105. case 7:
  106. if stat.Tpgid, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  107. return nil, err
  108. }
  109. case 8:
  110. if stat.Flags, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  111. return nil, err
  112. }
  113. case 9:
  114. if stat.Minflt, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  115. return nil, err
  116. }
  117. case 10:
  118. if stat.Cminflt, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  119. return nil, err
  120. }
  121. case 11:
  122. if stat.Majflt, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  123. return nil, err
  124. }
  125. case 12:
  126. if stat.Cmajflt, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  127. return nil, err
  128. }
  129. case 13:
  130. if stat.Utime, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  131. return nil, err
  132. }
  133. case 14:
  134. if stat.Stime, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  135. return nil, err
  136. }
  137. case 15:
  138. if stat.Cutime, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  139. return nil, err
  140. }
  141. case 16:
  142. if stat.Cstime, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  143. return nil, err
  144. }
  145. case 17:
  146. if stat.Priority, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  147. return nil, err
  148. }
  149. case 18:
  150. if stat.Nice, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  151. return nil, err
  152. }
  153. case 19:
  154. if stat.NumThreads, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  155. return nil, err
  156. }
  157. case 20:
  158. if stat.Itrealvalue, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  159. return nil, err
  160. }
  161. case 21:
  162. if stat.Starttime, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  163. return nil, err
  164. }
  165. case 22:
  166. if stat.Vsize, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  167. return nil, err
  168. }
  169. case 23:
  170. if stat.Rss, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  171. return nil, err
  172. }
  173. case 24:
  174. if stat.Rsslim, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  175. return nil, err
  176. }
  177. case 25:
  178. if stat.Startcode, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  179. return nil, err
  180. }
  181. case 26:
  182. if stat.Endcode, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  183. return nil, err
  184. }
  185. case 27:
  186. if stat.Startstack, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  187. return nil, err
  188. }
  189. case 28:
  190. if stat.Kstkesp, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  191. return nil, err
  192. }
  193. case 29:
  194. if stat.Kstkeip, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  195. return nil, err
  196. }
  197. case 30:
  198. if stat.Signal, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  199. return nil, err
  200. }
  201. case 31:
  202. if stat.Blocked, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  203. return nil, err
  204. }
  205. case 32:
  206. if stat.Sigignore, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  207. return nil, err
  208. }
  209. case 33:
  210. if stat.Sigcatch, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  211. return nil, err
  212. }
  213. case 34:
  214. if stat.Wchan, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  215. return nil, err
  216. }
  217. case 35:
  218. if stat.Nswap, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  219. return nil, err
  220. }
  221. case 36:
  222. if stat.Cnswap, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  223. return nil, err
  224. }
  225. case 37:
  226. if stat.ExitSignal, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  227. return nil, err
  228. }
  229. case 38:
  230. if stat.Processor, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  231. return nil, err
  232. }
  233. case 39:
  234. if stat.RtPriority, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  235. return nil, err
  236. }
  237. case 40:
  238. if stat.Policy, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  239. return nil, err
  240. }
  241. case 41:
  242. if stat.DelayacctBlkioTicks, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  243. return nil, err
  244. }
  245. case 42:
  246. if stat.GuestTime, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  247. return nil, err
  248. }
  249. case 43:
  250. if stat.CguestTime, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  251. return nil, err
  252. }
  253. case 44:
  254. if stat.StartData, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  255. return nil, err
  256. }
  257. case 45:
  258. if stat.EndData, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  259. return nil, err
  260. }
  261. case 46:
  262. if stat.StartBrk, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  263. return nil, err
  264. }
  265. case 47:
  266. if stat.ArgStart, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  267. return nil, err
  268. }
  269. case 48:
  270. if stat.ArgEnd, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  271. return nil, err
  272. }
  273. case 49:
  274. if stat.EnvStart, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  275. return nil, err
  276. }
  277. case 50:
  278. if stat.EnvEnd, err = strconv.ParseUint(f[i], 10, 64); err != nil {
  279. return nil, err
  280. }
  281. case 51:
  282. if stat.ExitCode, err = strconv.ParseInt(f[i], 10, 64); err != nil {
  283. return nil, err
  284. }
  285. }
  286. }
  287. return &stat, nil
  288. }