Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123 строки
3.6 KiB

  1. // Copyright 2021 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. //go:build !go1.17
  14. // +build !go1.17
  15. package prometheus
  16. import (
  17. "runtime"
  18. "sync"
  19. "time"
  20. )
  21. type goCollector struct {
  22. base baseGoCollector
  23. // ms... are memstats related.
  24. msLast *runtime.MemStats // Previously collected memstats.
  25. msLastTimestamp time.Time
  26. msMtx sync.Mutex // Protects msLast and msLastTimestamp.
  27. msMetrics memStatsMetrics
  28. msRead func(*runtime.MemStats) // For mocking in tests.
  29. msMaxWait time.Duration // Wait time for fresh memstats.
  30. msMaxAge time.Duration // Maximum allowed age of old memstats.
  31. }
  32. // NewGoCollector is the obsolete version of collectors.NewGoCollector.
  33. // See there for documentation.
  34. //
  35. // Deprecated: Use collectors.NewGoCollector instead.
  36. func NewGoCollector() Collector {
  37. msMetrics := goRuntimeMemStats()
  38. msMetrics = append(msMetrics, struct {
  39. desc *Desc
  40. eval func(*runtime.MemStats) float64
  41. valType ValueType
  42. }{
  43. // This metric is omitted in Go1.17+, see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034
  44. desc: NewDesc(
  45. memstatNamespace("gc_cpu_fraction"),
  46. "The fraction of this program's available CPU time used by the GC since the program started.",
  47. nil, nil,
  48. ),
  49. eval: func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction },
  50. valType: GaugeValue,
  51. })
  52. return &goCollector{
  53. base: newBaseGoCollector(),
  54. msLast: &runtime.MemStats{},
  55. msRead: runtime.ReadMemStats,
  56. msMaxWait: time.Second,
  57. msMaxAge: 5 * time.Minute,
  58. msMetrics: msMetrics,
  59. }
  60. }
  61. // Describe returns all descriptions of the collector.
  62. func (c *goCollector) Describe(ch chan<- *Desc) {
  63. c.base.Describe(ch)
  64. for _, i := range c.msMetrics {
  65. ch <- i.desc
  66. }
  67. }
  68. // Collect returns the current state of all metrics of the collector.
  69. func (c *goCollector) Collect(ch chan<- Metric) {
  70. var (
  71. ms = &runtime.MemStats{}
  72. done = make(chan struct{})
  73. )
  74. // Start reading memstats first as it might take a while.
  75. go func() {
  76. c.msRead(ms)
  77. c.msMtx.Lock()
  78. c.msLast = ms
  79. c.msLastTimestamp = time.Now()
  80. c.msMtx.Unlock()
  81. close(done)
  82. }()
  83. // Collect base non-memory metrics.
  84. c.base.Collect(ch)
  85. timer := time.NewTimer(c.msMaxWait)
  86. select {
  87. case <-done: // Our own ReadMemStats succeeded in time. Use it.
  88. timer.Stop() // Important for high collection frequencies to not pile up timers.
  89. c.msCollect(ch, ms)
  90. return
  91. case <-timer.C: // Time out, use last memstats if possible. Continue below.
  92. }
  93. c.msMtx.Lock()
  94. if time.Since(c.msLastTimestamp) < c.msMaxAge {
  95. // Last memstats are recent enough. Collect from them under the lock.
  96. c.msCollect(ch, c.msLast)
  97. c.msMtx.Unlock()
  98. return
  99. }
  100. // If we are here, the last memstats are too old or don't exist. We have
  101. // to wait until our own ReadMemStats finally completes. For that to
  102. // happen, we have to release the lock.
  103. c.msMtx.Unlock()
  104. <-done
  105. c.msCollect(ch, ms)
  106. }
  107. func (c *goCollector) msCollect(ch chan<- Metric, ms *runtime.MemStats) {
  108. for _, i := range c.msMetrics {
  109. ch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms))
  110. }
  111. }