process_collector.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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 "github.com/prometheus/procfs"
  15. type processCollector struct {
  16. pid int
  17. collectFn func(chan<- Metric)
  18. pidFn func() (int, error)
  19. cpuTotal *Desc
  20. openFDs, maxFDs *Desc
  21. vsize, rss *Desc
  22. startTime *Desc
  23. }
  24. // NewProcessCollector returns a collector which exports the current state of
  25. // process metrics including cpu, memory and file descriptor usage as well as
  26. // the process start time for the given process id under the given namespace.
  27. func NewProcessCollector(pid int, namespace string) Collector {
  28. return NewProcessCollectorPIDFn(
  29. func() (int, error) { return pid, nil },
  30. namespace,
  31. )
  32. }
  33. // NewProcessCollectorPIDFn returns a collector which exports the current state
  34. // of process metrics including cpu, memory and file descriptor usage as well
  35. // as the process start time under the given namespace. The given pidFn is
  36. // called on each collect and is used to determine the process to export
  37. // metrics for.
  38. func NewProcessCollectorPIDFn(
  39. pidFn func() (int, error),
  40. namespace string,
  41. ) Collector {
  42. ns := ""
  43. if len(namespace) > 0 {
  44. ns = namespace + "_"
  45. }
  46. c := processCollector{
  47. pidFn: pidFn,
  48. collectFn: func(chan<- Metric) {},
  49. cpuTotal: NewDesc(
  50. ns+"process_cpu_seconds_total",
  51. "Total user and system CPU time spent in seconds.",
  52. nil, nil,
  53. ),
  54. openFDs: NewDesc(
  55. ns+"process_open_fds",
  56. "Number of open file descriptors.",
  57. nil, nil,
  58. ),
  59. maxFDs: NewDesc(
  60. ns+"process_max_fds",
  61. "Maximum number of open file descriptors.",
  62. nil, nil,
  63. ),
  64. vsize: NewDesc(
  65. ns+"process_virtual_memory_bytes",
  66. "Virtual memory size in bytes.",
  67. nil, nil,
  68. ),
  69. rss: NewDesc(
  70. ns+"process_resident_memory_bytes",
  71. "Resident memory size in bytes.",
  72. nil, nil,
  73. ),
  74. startTime: NewDesc(
  75. ns+"process_start_time_seconds",
  76. "Start time of the process since unix epoch in seconds.",
  77. nil, nil,
  78. ),
  79. }
  80. // Set up process metric collection if supported by the runtime.
  81. if _, err := procfs.NewStat(); err == nil {
  82. c.collectFn = c.processCollect
  83. }
  84. return &c
  85. }
  86. // Describe returns all descriptions of the collector.
  87. func (c *processCollector) Describe(ch chan<- *Desc) {
  88. ch <- c.cpuTotal
  89. ch <- c.openFDs
  90. ch <- c.maxFDs
  91. ch <- c.vsize
  92. ch <- c.rss
  93. ch <- c.startTime
  94. }
  95. // Collect returns the current state of all metrics of the collector.
  96. func (c *processCollector) Collect(ch chan<- Metric) {
  97. c.collectFn(ch)
  98. }
  99. // TODO(ts): Bring back error reporting by reverting 7faf9e7 as soon as the
  100. // client allows users to configure the error behavior.
  101. func (c *processCollector) processCollect(ch chan<- Metric) {
  102. pid, err := c.pidFn()
  103. if err != nil {
  104. return
  105. }
  106. p, err := procfs.NewProc(pid)
  107. if err != nil {
  108. return
  109. }
  110. if stat, err := p.NewStat(); err == nil {
  111. ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
  112. ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
  113. ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
  114. if startTime, err := stat.StartTime(); err == nil {
  115. ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
  116. }
  117. }
  118. if fds, err := p.FileDescriptorsLen(); err == nil {
  119. ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
  120. }
  121. if limits, err := p.NewLimits(); err == nil {
  122. ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
  123. }
  124. }