You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

171 lines
4.4 KiB

  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. "strconv"
  17. "strings"
  18. "github.com/prometheus/procfs/internal/util"
  19. )
  20. // ProcStatus provides status information about the process,
  21. // read from /proc/[pid]/stat.
  22. type ProcStatus struct {
  23. // The process ID.
  24. PID int
  25. // The process name.
  26. Name string
  27. // Thread group ID.
  28. TGID int
  29. // Peak virtual memory size.
  30. VmPeak uint64 // nolint:revive
  31. // Virtual memory size.
  32. VmSize uint64 // nolint:revive
  33. // Locked memory size.
  34. VmLck uint64 // nolint:revive
  35. // Pinned memory size.
  36. VmPin uint64 // nolint:revive
  37. // Peak resident set size.
  38. VmHWM uint64 // nolint:revive
  39. // Resident set size (sum of RssAnnon RssFile and RssShmem).
  40. VmRSS uint64 // nolint:revive
  41. // Size of resident anonymous memory.
  42. RssAnon uint64 // nolint:revive
  43. // Size of resident file mappings.
  44. RssFile uint64 // nolint:revive
  45. // Size of resident shared memory.
  46. RssShmem uint64 // nolint:revive
  47. // Size of data segments.
  48. VmData uint64 // nolint:revive
  49. // Size of stack segments.
  50. VmStk uint64 // nolint:revive
  51. // Size of text segments.
  52. VmExe uint64 // nolint:revive
  53. // Shared library code size.
  54. VmLib uint64 // nolint:revive
  55. // Page table entries size.
  56. VmPTE uint64 // nolint:revive
  57. // Size of second-level page tables.
  58. VmPMD uint64 // nolint:revive
  59. // Swapped-out virtual memory size by anonymous private.
  60. VmSwap uint64 // nolint:revive
  61. // Size of hugetlb memory portions
  62. HugetlbPages uint64
  63. // Number of voluntary context switches.
  64. VoluntaryCtxtSwitches uint64
  65. // Number of involuntary context switches.
  66. NonVoluntaryCtxtSwitches uint64
  67. // UIDs of the process (Real, effective, saved set, and filesystem UIDs)
  68. UIDs [4]string
  69. // GIDs of the process (Real, effective, saved set, and filesystem GIDs)
  70. GIDs [4]string
  71. }
  72. // NewStatus returns the current status information of the process.
  73. func (p Proc) NewStatus() (ProcStatus, error) {
  74. data, err := util.ReadFileNoStat(p.path("status"))
  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 := strings.TrimSpace(kv[0])
  87. v := strings.TrimSpace(kv[1])
  88. // removes "kB"
  89. v = strings.TrimSuffix(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 "Tgid":
  102. s.TGID = int(vUint)
  103. case "Name":
  104. s.Name = vString
  105. case "Uid":
  106. copy(s.UIDs[:], strings.Split(vString, "\t"))
  107. case "Gid":
  108. copy(s.GIDs[:], strings.Split(vString, "\t"))
  109. case "VmPeak":
  110. s.VmPeak = vUintBytes
  111. case "VmSize":
  112. s.VmSize = vUintBytes
  113. case "VmLck":
  114. s.VmLck = vUintBytes
  115. case "VmPin":
  116. s.VmPin = vUintBytes
  117. case "VmHWM":
  118. s.VmHWM = vUintBytes
  119. case "VmRSS":
  120. s.VmRSS = vUintBytes
  121. case "RssAnon":
  122. s.RssAnon = vUintBytes
  123. case "RssFile":
  124. s.RssFile = vUintBytes
  125. case "RssShmem":
  126. s.RssShmem = vUintBytes
  127. case "VmData":
  128. s.VmData = vUintBytes
  129. case "VmStk":
  130. s.VmStk = vUintBytes
  131. case "VmExe":
  132. s.VmExe = vUintBytes
  133. case "VmLib":
  134. s.VmLib = vUintBytes
  135. case "VmPTE":
  136. s.VmPTE = vUintBytes
  137. case "VmPMD":
  138. s.VmPMD = vUintBytes
  139. case "VmSwap":
  140. s.VmSwap = vUintBytes
  141. case "HugetlbPages":
  142. s.HugetlbPages = vUintBytes
  143. case "voluntary_ctxt_switches":
  144. s.VoluntaryCtxtSwitches = vUint
  145. case "nonvoluntary_ctxt_switches":
  146. s.NonVoluntaryCtxtSwitches = vUint
  147. }
  148. }
  149. // TotalCtxtSwitches returns the total context switch.
  150. func (s ProcStatus) TotalCtxtSwitches() uint64 {
  151. return s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches
  152. }