proc_status.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Copyright 2018 The Prometheus Authors
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the License.
  4. // You may obtain a copy of the License at
  5. //
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. package procfs
  14. import (
  15. "bytes"
  16. "io/ioutil"
  17. "os"
  18. "strconv"
  19. "strings"
  20. )
  21. // ProcStat provides status information about the process,
  22. // read from /proc/[pid]/stat.
  23. type ProcStatus struct {
  24. // The process ID.
  25. PID int
  26. // The process name.
  27. Name string
  28. // Peak virtual memory size.
  29. VmPeak uint64
  30. // Virtual memory size.
  31. VmSize uint64
  32. // Locked memory size.
  33. VmLck uint64
  34. // Pinned memory size.
  35. VmPin uint64
  36. // Peak resident set size.
  37. VmHWM uint64
  38. // Resident set size (sum of RssAnnon RssFile and RssShmem).
  39. VmRSS uint64
  40. // Size of resident anonymous memory.
  41. RssAnon uint64
  42. // Size of resident file mappings.
  43. RssFile uint64
  44. // Size of resident shared memory.
  45. RssShmem uint64
  46. // Size of data segments.
  47. VmData uint64
  48. // Size of stack segments.
  49. VmStk uint64
  50. // Size of text segments.
  51. VmExe uint64
  52. // Shared library code size.
  53. VmLib uint64
  54. // Page table entries size.
  55. VmPTE uint64
  56. // Size of second-level page tables.
  57. VmPMD uint64
  58. // Swapped-out virtual memory size by anonymous private.
  59. VmSwap uint64
  60. // Size of hugetlb memory portions
  61. HugetlbPages uint64
  62. // Number of voluntary context switches.
  63. VoluntaryCtxtSwitches uint64
  64. // Number of involuntary context switches.
  65. NonVoluntaryCtxtSwitches uint64
  66. }
  67. // NewStatus returns the current status information of the process.
  68. func (p Proc) NewStatus() (ProcStatus, error) {
  69. f, err := os.Open(p.path("status"))
  70. if err != nil {
  71. return ProcStatus{}, err
  72. }
  73. defer f.Close()
  74. data, err := ioutil.ReadAll(f)
  75. if err != nil {
  76. return ProcStatus{}, err
  77. }
  78. s := ProcStatus{PID: p.PID}
  79. lines := strings.Split(string(data), "\n")
  80. for _, line := range lines {
  81. if !bytes.Contains([]byte(line), []byte(":")) {
  82. continue
  83. }
  84. kv := strings.SplitN(line, ":", 2)
  85. // removes spaces
  86. k := string(strings.TrimSpace(kv[0]))
  87. v := string(strings.TrimSpace(kv[1]))
  88. // removes "kB"
  89. v = string(bytes.Trim([]byte(v), " kB"))
  90. // value to int when possible
  91. // we can skip error check here, 'cause vKBytes is not used when value is a string
  92. vKBytes, _ := strconv.ParseUint(v, 10, 64)
  93. // convert kB to B
  94. vBytes := vKBytes * 1024
  95. s.fillStatus(k, v, vKBytes, vBytes)
  96. }
  97. return s, nil
  98. }
  99. func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintBytes uint64) {
  100. switch k {
  101. case "Name":
  102. s.Name = vString
  103. case "VmPeak":
  104. s.VmPeak = vUintBytes
  105. case "VmSize":
  106. s.VmSize = vUintBytes
  107. case "VmLck":
  108. s.VmLck = vUintBytes
  109. case "VmPin":
  110. s.VmPin = vUintBytes
  111. case "VmHWM":
  112. s.VmHWM = vUintBytes
  113. case "VmRSS":
  114. s.VmRSS = vUintBytes
  115. case "RssAnon":
  116. s.RssAnon = vUintBytes
  117. case "RssFile":
  118. s.RssFile = vUintBytes
  119. case "RssShmem":
  120. s.RssShmem = vUintBytes
  121. case "VmData":
  122. s.VmData = vUintBytes
  123. case "VmStk":
  124. s.VmStk = vUintBytes
  125. case "VmExe":
  126. s.VmExe = vUintBytes
  127. case "VmLib":
  128. s.VmLib = vUintBytes
  129. case "VmPTE":
  130. s.VmPTE = vUintBytes
  131. case "VmPMD":
  132. s.VmPMD = vUintBytes
  133. case "VmSwap":
  134. s.VmSwap = vUintBytes
  135. case "HugetlbPages":
  136. s.HugetlbPages = vUintBytes
  137. case "voluntary_ctxt_switches":
  138. s.VoluntaryCtxtSwitches = vUint
  139. case "nonvoluntary_ctxt_switches":
  140. s.NonVoluntaryCtxtSwitches = vUint
  141. }
  142. }
  143. // TotalCtxtSwitches returns the total context switch.
  144. func (s ProcStatus) TotalCtxtSwitches() uint64 {
  145. return s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches
  146. }