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.
 
 

278 lines
8.1 KiB

  1. // Copyright 2019 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. "bufio"
  16. "bytes"
  17. "fmt"
  18. "io"
  19. "strconv"
  20. "strings"
  21. "github.com/prometheus/procfs/internal/util"
  22. )
  23. // Meminfo represents memory statistics.
  24. type Meminfo struct {
  25. // Total usable ram (i.e. physical ram minus a few reserved
  26. // bits and the kernel binary code)
  27. MemTotal *uint64
  28. // The sum of LowFree+HighFree
  29. MemFree *uint64
  30. // An estimate of how much memory is available for starting
  31. // new applications, without swapping. Calculated from
  32. // MemFree, SReclaimable, the size of the file LRU lists, and
  33. // the low watermarks in each zone. The estimate takes into
  34. // account that the system needs some page cache to function
  35. // well, and that not all reclaimable slab will be
  36. // reclaimable, due to items being in use. The impact of those
  37. // factors will vary from system to system.
  38. MemAvailable *uint64
  39. // Relatively temporary storage for raw disk blocks shouldn't
  40. // get tremendously large (20MB or so)
  41. Buffers *uint64
  42. Cached *uint64
  43. // Memory that once was swapped out, is swapped back in but
  44. // still also is in the swapfile (if memory is needed it
  45. // doesn't need to be swapped out AGAIN because it is already
  46. // in the swapfile. This saves I/O)
  47. SwapCached *uint64
  48. // Memory that has been used more recently and usually not
  49. // reclaimed unless absolutely necessary.
  50. Active *uint64
  51. // Memory which has been less recently used. It is more
  52. // eligible to be reclaimed for other purposes
  53. Inactive *uint64
  54. ActiveAnon *uint64
  55. InactiveAnon *uint64
  56. ActiveFile *uint64
  57. InactiveFile *uint64
  58. Unevictable *uint64
  59. Mlocked *uint64
  60. // total amount of swap space available
  61. SwapTotal *uint64
  62. // Memory which has been evicted from RAM, and is temporarily
  63. // on the disk
  64. SwapFree *uint64
  65. // Memory which is waiting to get written back to the disk
  66. Dirty *uint64
  67. // Memory which is actively being written back to the disk
  68. Writeback *uint64
  69. // Non-file backed pages mapped into userspace page tables
  70. AnonPages *uint64
  71. // files which have been mapped, such as libraries
  72. Mapped *uint64
  73. Shmem *uint64
  74. // in-kernel data structures cache
  75. Slab *uint64
  76. // Part of Slab, that might be reclaimed, such as caches
  77. SReclaimable *uint64
  78. // Part of Slab, that cannot be reclaimed on memory pressure
  79. SUnreclaim *uint64
  80. KernelStack *uint64
  81. // amount of memory dedicated to the lowest level of page
  82. // tables.
  83. PageTables *uint64
  84. // NFS pages sent to the server, but not yet committed to
  85. // stable storage
  86. NFSUnstable *uint64
  87. // Memory used for block device "bounce buffers"
  88. Bounce *uint64
  89. // Memory used by FUSE for temporary writeback buffers
  90. WritebackTmp *uint64
  91. // Based on the overcommit ratio ('vm.overcommit_ratio'),
  92. // this is the total amount of memory currently available to
  93. // be allocated on the system. This limit is only adhered to
  94. // if strict overcommit accounting is enabled (mode 2 in
  95. // 'vm.overcommit_memory').
  96. // The CommitLimit is calculated with the following formula:
  97. // CommitLimit = ([total RAM pages] - [total huge TLB pages]) *
  98. // overcommit_ratio / 100 + [total swap pages]
  99. // For example, on a system with 1G of physical RAM and 7G
  100. // of swap with a `vm.overcommit_ratio` of 30 it would
  101. // yield a CommitLimit of 7.3G.
  102. // For more details, see the memory overcommit documentation
  103. // in vm/overcommit-accounting.
  104. CommitLimit *uint64
  105. // The amount of memory presently allocated on the system.
  106. // The committed memory is a sum of all of the memory which
  107. // has been allocated by processes, even if it has not been
  108. // "used" by them as of yet. A process which malloc()'s 1G
  109. // of memory, but only touches 300M of it will show up as
  110. // using 1G. This 1G is memory which has been "committed" to
  111. // by the VM and can be used at any time by the allocating
  112. // application. With strict overcommit enabled on the system
  113. // (mode 2 in 'vm.overcommit_memory'),allocations which would
  114. // exceed the CommitLimit (detailed above) will not be permitted.
  115. // This is useful if one needs to guarantee that processes will
  116. // not fail due to lack of memory once that memory has been
  117. // successfully allocated.
  118. CommittedAS *uint64
  119. // total size of vmalloc memory area
  120. VmallocTotal *uint64
  121. // amount of vmalloc area which is used
  122. VmallocUsed *uint64
  123. // largest contiguous block of vmalloc area which is free
  124. VmallocChunk *uint64
  125. HardwareCorrupted *uint64
  126. AnonHugePages *uint64
  127. ShmemHugePages *uint64
  128. ShmemPmdMapped *uint64
  129. CmaTotal *uint64
  130. CmaFree *uint64
  131. HugePagesTotal *uint64
  132. HugePagesFree *uint64
  133. HugePagesRsvd *uint64
  134. HugePagesSurp *uint64
  135. Hugepagesize *uint64
  136. DirectMap4k *uint64
  137. DirectMap2M *uint64
  138. DirectMap1G *uint64
  139. }
  140. // Meminfo returns an information about current kernel/system memory statistics.
  141. // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
  142. func (fs FS) Meminfo() (Meminfo, error) {
  143. b, err := util.ReadFileNoStat(fs.proc.Path("meminfo"))
  144. if err != nil {
  145. return Meminfo{}, err
  146. }
  147. m, err := parseMemInfo(bytes.NewReader(b))
  148. if err != nil {
  149. return Meminfo{}, fmt.Errorf("failed to parse meminfo: %w", err)
  150. }
  151. return *m, nil
  152. }
  153. func parseMemInfo(r io.Reader) (*Meminfo, error) {
  154. var m Meminfo
  155. s := bufio.NewScanner(r)
  156. for s.Scan() {
  157. // Each line has at least a name and value; we ignore the unit.
  158. fields := strings.Fields(s.Text())
  159. if len(fields) < 2 {
  160. return nil, fmt.Errorf("malformed meminfo line: %q", s.Text())
  161. }
  162. v, err := strconv.ParseUint(fields[1], 0, 64)
  163. if err != nil {
  164. return nil, err
  165. }
  166. switch fields[0] {
  167. case "MemTotal:":
  168. m.MemTotal = &v
  169. case "MemFree:":
  170. m.MemFree = &v
  171. case "MemAvailable:":
  172. m.MemAvailable = &v
  173. case "Buffers:":
  174. m.Buffers = &v
  175. case "Cached:":
  176. m.Cached = &v
  177. case "SwapCached:":
  178. m.SwapCached = &v
  179. case "Active:":
  180. m.Active = &v
  181. case "Inactive:":
  182. m.Inactive = &v
  183. case "Active(anon):":
  184. m.ActiveAnon = &v
  185. case "Inactive(anon):":
  186. m.InactiveAnon = &v
  187. case "Active(file):":
  188. m.ActiveFile = &v
  189. case "Inactive(file):":
  190. m.InactiveFile = &v
  191. case "Unevictable:":
  192. m.Unevictable = &v
  193. case "Mlocked:":
  194. m.Mlocked = &v
  195. case "SwapTotal:":
  196. m.SwapTotal = &v
  197. case "SwapFree:":
  198. m.SwapFree = &v
  199. case "Dirty:":
  200. m.Dirty = &v
  201. case "Writeback:":
  202. m.Writeback = &v
  203. case "AnonPages:":
  204. m.AnonPages = &v
  205. case "Mapped:":
  206. m.Mapped = &v
  207. case "Shmem:":
  208. m.Shmem = &v
  209. case "Slab:":
  210. m.Slab = &v
  211. case "SReclaimable:":
  212. m.SReclaimable = &v
  213. case "SUnreclaim:":
  214. m.SUnreclaim = &v
  215. case "KernelStack:":
  216. m.KernelStack = &v
  217. case "PageTables:":
  218. m.PageTables = &v
  219. case "NFS_Unstable:":
  220. m.NFSUnstable = &v
  221. case "Bounce:":
  222. m.Bounce = &v
  223. case "WritebackTmp:":
  224. m.WritebackTmp = &v
  225. case "CommitLimit:":
  226. m.CommitLimit = &v
  227. case "Committed_AS:":
  228. m.CommittedAS = &v
  229. case "VmallocTotal:":
  230. m.VmallocTotal = &v
  231. case "VmallocUsed:":
  232. m.VmallocUsed = &v
  233. case "VmallocChunk:":
  234. m.VmallocChunk = &v
  235. case "HardwareCorrupted:":
  236. m.HardwareCorrupted = &v
  237. case "AnonHugePages:":
  238. m.AnonHugePages = &v
  239. case "ShmemHugePages:":
  240. m.ShmemHugePages = &v
  241. case "ShmemPmdMapped:":
  242. m.ShmemPmdMapped = &v
  243. case "CmaTotal:":
  244. m.CmaTotal = &v
  245. case "CmaFree:":
  246. m.CmaFree = &v
  247. case "HugePages_Total:":
  248. m.HugePagesTotal = &v
  249. case "HugePages_Free:":
  250. m.HugePagesFree = &v
  251. case "HugePages_Rsvd:":
  252. m.HugePagesRsvd = &v
  253. case "HugePages_Surp:":
  254. m.HugePagesSurp = &v
  255. case "Hugepagesize:":
  256. m.Hugepagesize = &v
  257. case "DirectMap4k:":
  258. m.DirectMap4k = &v
  259. case "DirectMap2M:":
  260. m.DirectMap2M = &v
  261. case "DirectMap1G:":
  262. m.DirectMap1G = &v
  263. }
  264. }
  265. return &m, nil
  266. }