您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

161 行
4.8 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. "bufio"
  16. "fmt"
  17. "os"
  18. "regexp"
  19. "strconv"
  20. )
  21. // ProcLimits represents the soft limits for each of the process's resource
  22. // limits. For more information see getrlimit(2):
  23. // http://man7.org/linux/man-pages/man2/getrlimit.2.html.
  24. type ProcLimits struct {
  25. // CPU time limit in seconds.
  26. CPUTime uint64
  27. // Maximum size of files that the process may create.
  28. FileSize uint64
  29. // Maximum size of the process's data segment (initialized data,
  30. // uninitialized data, and heap).
  31. DataSize uint64
  32. // Maximum size of the process stack in bytes.
  33. StackSize uint64
  34. // Maximum size of a core file.
  35. CoreFileSize uint64
  36. // Limit of the process's resident set in pages.
  37. ResidentSet uint64
  38. // Maximum number of processes that can be created for the real user ID of
  39. // the calling process.
  40. Processes uint64
  41. // Value one greater than the maximum file descriptor number that can be
  42. // opened by this process.
  43. OpenFiles uint64
  44. // Maximum number of bytes of memory that may be locked into RAM.
  45. LockedMemory uint64
  46. // Maximum size of the process's virtual memory address space in bytes.
  47. AddressSpace uint64
  48. // Limit on the combined number of flock(2) locks and fcntl(2) leases that
  49. // this process may establish.
  50. FileLocks uint64
  51. // Limit of signals that may be queued for the real user ID of the calling
  52. // process.
  53. PendingSignals uint64
  54. // Limit on the number of bytes that can be allocated for POSIX message
  55. // queues for the real user ID of the calling process.
  56. MsqqueueSize uint64
  57. // Limit of the nice priority set using setpriority(2) or nice(2).
  58. NicePriority uint64
  59. // Limit of the real-time priority set using sched_setscheduler(2) or
  60. // sched_setparam(2).
  61. RealtimePriority uint64
  62. // Limit (in microseconds) on the amount of CPU time that a process
  63. // scheduled under a real-time scheduling policy may consume without making
  64. // a blocking system call.
  65. RealtimeTimeout uint64
  66. }
  67. const (
  68. limitsFields = 4
  69. limitsUnlimited = "unlimited"
  70. )
  71. var (
  72. limitsMatch = regexp.MustCompile(`(Max \w+\s{0,1}?\w*\s{0,1}\w*)\s{2,}(\w+)\s+(\w+)`)
  73. )
  74. // NewLimits returns the current soft limits of the process.
  75. //
  76. // Deprecated: Use p.Limits() instead.
  77. func (p Proc) NewLimits() (ProcLimits, error) {
  78. return p.Limits()
  79. }
  80. // Limits returns the current soft limits of the process.
  81. func (p Proc) Limits() (ProcLimits, error) {
  82. f, err := os.Open(p.path("limits"))
  83. if err != nil {
  84. return ProcLimits{}, err
  85. }
  86. defer f.Close()
  87. var (
  88. l = ProcLimits{}
  89. s = bufio.NewScanner(f)
  90. )
  91. s.Scan() // Skip limits header
  92. for s.Scan() {
  93. //fields := limitsMatch.Split(s.Text(), limitsFields)
  94. fields := limitsMatch.FindStringSubmatch(s.Text())
  95. if len(fields) != limitsFields {
  96. return ProcLimits{}, fmt.Errorf("couldn't parse %q line %q", f.Name(), s.Text())
  97. }
  98. switch fields[1] {
  99. case "Max cpu time":
  100. l.CPUTime, err = parseUint(fields[2])
  101. case "Max file size":
  102. l.FileSize, err = parseUint(fields[2])
  103. case "Max data size":
  104. l.DataSize, err = parseUint(fields[2])
  105. case "Max stack size":
  106. l.StackSize, err = parseUint(fields[2])
  107. case "Max core file size":
  108. l.CoreFileSize, err = parseUint(fields[2])
  109. case "Max resident set":
  110. l.ResidentSet, err = parseUint(fields[2])
  111. case "Max processes":
  112. l.Processes, err = parseUint(fields[2])
  113. case "Max open files":
  114. l.OpenFiles, err = parseUint(fields[2])
  115. case "Max locked memory":
  116. l.LockedMemory, err = parseUint(fields[2])
  117. case "Max address space":
  118. l.AddressSpace, err = parseUint(fields[2])
  119. case "Max file locks":
  120. l.FileLocks, err = parseUint(fields[2])
  121. case "Max pending signals":
  122. l.PendingSignals, err = parseUint(fields[2])
  123. case "Max msgqueue size":
  124. l.MsqqueueSize, err = parseUint(fields[2])
  125. case "Max nice priority":
  126. l.NicePriority, err = parseUint(fields[2])
  127. case "Max realtime priority":
  128. l.RealtimePriority, err = parseUint(fields[2])
  129. case "Max realtime timeout":
  130. l.RealtimeTimeout, err = parseUint(fields[2])
  131. }
  132. if err != nil {
  133. return ProcLimits{}, err
  134. }
  135. }
  136. return l, s.Err()
  137. }
  138. func parseUint(s string) (uint64, error) {
  139. if s == limitsUnlimited {
  140. return 18446744073709551615, nil
  141. }
  142. i, err := strconv.ParseUint(s, 10, 64)
  143. if err != nil {
  144. return 0, fmt.Errorf("couldn't parse value %q: %w", s, err)
  145. }
  146. return i, nil
  147. }