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

167 行
4.6 KiB

  1. // Copyright 2015 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 prometheus
  14. import (
  15. "errors"
  16. "fmt"
  17. "io/ioutil"
  18. "os"
  19. "strconv"
  20. "strings"
  21. )
  22. type processCollector struct {
  23. collectFn func(chan<- Metric)
  24. pidFn func() (int, error)
  25. reportErrors bool
  26. cpuTotal *Desc
  27. openFDs, maxFDs *Desc
  28. vsize, maxVsize *Desc
  29. rss *Desc
  30. startTime *Desc
  31. }
  32. // ProcessCollectorOpts defines the behavior of a process metrics collector
  33. // created with NewProcessCollector.
  34. type ProcessCollectorOpts struct {
  35. // PidFn returns the PID of the process the collector collects metrics
  36. // for. It is called upon each collection. By default, the PID of the
  37. // current process is used, as determined on construction time by
  38. // calling os.Getpid().
  39. PidFn func() (int, error)
  40. // If non-empty, each of the collected metrics is prefixed by the
  41. // provided string and an underscore ("_").
  42. Namespace string
  43. // If true, any error encountered during collection is reported as an
  44. // invalid metric (see NewInvalidMetric). Otherwise, errors are ignored
  45. // and the collected metrics will be incomplete. (Possibly, no metrics
  46. // will be collected at all.) While that's usually not desired, it is
  47. // appropriate for the common "mix-in" of process metrics, where process
  48. // metrics are nice to have, but failing to collect them should not
  49. // disrupt the collection of the remaining metrics.
  50. ReportErrors bool
  51. }
  52. // NewProcessCollector is the obsolete version of collectors.NewProcessCollector.
  53. // See there for documentation.
  54. //
  55. // Deprecated: Use collectors.NewProcessCollector instead.
  56. func NewProcessCollector(opts ProcessCollectorOpts) Collector {
  57. ns := ""
  58. if len(opts.Namespace) > 0 {
  59. ns = opts.Namespace + "_"
  60. }
  61. c := &processCollector{
  62. reportErrors: opts.ReportErrors,
  63. cpuTotal: NewDesc(
  64. ns+"process_cpu_seconds_total",
  65. "Total user and system CPU time spent in seconds.",
  66. nil, nil,
  67. ),
  68. openFDs: NewDesc(
  69. ns+"process_open_fds",
  70. "Number of open file descriptors.",
  71. nil, nil,
  72. ),
  73. maxFDs: NewDesc(
  74. ns+"process_max_fds",
  75. "Maximum number of open file descriptors.",
  76. nil, nil,
  77. ),
  78. vsize: NewDesc(
  79. ns+"process_virtual_memory_bytes",
  80. "Virtual memory size in bytes.",
  81. nil, nil,
  82. ),
  83. maxVsize: NewDesc(
  84. ns+"process_virtual_memory_max_bytes",
  85. "Maximum amount of virtual memory available in bytes.",
  86. nil, nil,
  87. ),
  88. rss: NewDesc(
  89. ns+"process_resident_memory_bytes",
  90. "Resident memory size in bytes.",
  91. nil, nil,
  92. ),
  93. startTime: NewDesc(
  94. ns+"process_start_time_seconds",
  95. "Start time of the process since unix epoch in seconds.",
  96. nil, nil,
  97. ),
  98. }
  99. if opts.PidFn == nil {
  100. pid := os.Getpid()
  101. c.pidFn = func() (int, error) { return pid, nil }
  102. } else {
  103. c.pidFn = opts.PidFn
  104. }
  105. // Set up process metric collection if supported by the runtime.
  106. if canCollectProcess() {
  107. c.collectFn = c.processCollect
  108. } else {
  109. c.collectFn = func(ch chan<- Metric) {
  110. c.reportError(ch, nil, errors.New("process metrics not supported on this platform"))
  111. }
  112. }
  113. return c
  114. }
  115. // Describe returns all descriptions of the collector.
  116. func (c *processCollector) Describe(ch chan<- *Desc) {
  117. ch <- c.cpuTotal
  118. ch <- c.openFDs
  119. ch <- c.maxFDs
  120. ch <- c.vsize
  121. ch <- c.maxVsize
  122. ch <- c.rss
  123. ch <- c.startTime
  124. }
  125. // Collect returns the current state of all metrics of the collector.
  126. func (c *processCollector) Collect(ch chan<- Metric) {
  127. c.collectFn(ch)
  128. }
  129. func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {
  130. if !c.reportErrors {
  131. return
  132. }
  133. if desc == nil {
  134. desc = NewInvalidDesc(err)
  135. }
  136. ch <- NewInvalidMetric(desc, err)
  137. }
  138. // NewPidFileFn returns a function that retrieves a pid from the specified file.
  139. // It is meant to be used for the PidFn field in ProcessCollectorOpts.
  140. func NewPidFileFn(pidFilePath string) func() (int, error) {
  141. return func() (int, error) {
  142. content, err := ioutil.ReadFile(pidFilePath)
  143. if err != nil {
  144. return 0, fmt.Errorf("can't read pid file %q: %+v", pidFilePath, err)
  145. }
  146. pid, err := strconv.Atoi(strings.TrimSpace(string(content)))
  147. if err != nil {
  148. return 0, fmt.Errorf("can't parse pid file %q: %+v", pidFilePath, err)
  149. }
  150. return pid, nil
  151. }
  152. }