runtime.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package metrics
  2. import (
  3. "runtime"
  4. "time"
  5. )
  6. var (
  7. memStats runtime.MemStats
  8. runtimeMetrics struct {
  9. MemStats struct {
  10. Alloc Gauge
  11. BuckHashSys Gauge
  12. DebugGC Gauge
  13. EnableGC Gauge
  14. Frees Gauge
  15. HeapAlloc Gauge
  16. HeapIdle Gauge
  17. HeapInuse Gauge
  18. HeapObjects Gauge
  19. HeapReleased Gauge
  20. HeapSys Gauge
  21. LastGC Gauge
  22. Lookups Gauge
  23. Mallocs Gauge
  24. MCacheInuse Gauge
  25. MCacheSys Gauge
  26. MSpanInuse Gauge
  27. MSpanSys Gauge
  28. NextGC Gauge
  29. NumGC Gauge
  30. PauseNs Histogram
  31. PauseTotalNs Gauge
  32. StackInuse Gauge
  33. StackSys Gauge
  34. Sys Gauge
  35. TotalAlloc Gauge
  36. }
  37. NumCgoCall Gauge
  38. NumGoroutine Gauge
  39. ReadMemStats Timer
  40. }
  41. frees uint64
  42. lookups uint64
  43. mallocs uint64
  44. numGC uint32
  45. )
  46. // Capture new values for the Go runtime statistics exported in
  47. // runtime.MemStats. This is designed to be called as a goroutine.
  48. func CaptureRuntimeMemStats(r Registry, d time.Duration) {
  49. for {
  50. CaptureRuntimeMemStatsOnce(r)
  51. time.Sleep(d)
  52. }
  53. }
  54. // Capture new values for the Go runtime statistics exported in
  55. // runtime.MemStats. This is designed to be called in a background
  56. // goroutine. Giving a registry which has not been given to
  57. // RegisterRuntimeMemStats will panic.
  58. //
  59. // Be very careful with this because runtime.ReadMemStats calls the C
  60. // functions runtime·semacquire(&runtime·worldsema) and runtime·stoptheworld()
  61. // and that last one does what it says on the tin.
  62. func CaptureRuntimeMemStatsOnce(r Registry) {
  63. t := time.Now()
  64. runtime.ReadMemStats(&memStats) // This takes 50-200us.
  65. runtimeMetrics.ReadMemStats.UpdateSince(t)
  66. runtimeMetrics.MemStats.Alloc.Update(int64(memStats.Alloc))
  67. runtimeMetrics.MemStats.BuckHashSys.Update(int64(memStats.BuckHashSys))
  68. if memStats.DebugGC {
  69. runtimeMetrics.MemStats.DebugGC.Update(1)
  70. } else {
  71. runtimeMetrics.MemStats.DebugGC.Update(0)
  72. }
  73. if memStats.EnableGC {
  74. runtimeMetrics.MemStats.EnableGC.Update(1)
  75. } else {
  76. runtimeMetrics.MemStats.EnableGC.Update(0)
  77. }
  78. runtimeMetrics.MemStats.Frees.Update(int64(memStats.Frees - frees))
  79. runtimeMetrics.MemStats.HeapAlloc.Update(int64(memStats.HeapAlloc))
  80. runtimeMetrics.MemStats.HeapIdle.Update(int64(memStats.HeapIdle))
  81. runtimeMetrics.MemStats.HeapInuse.Update(int64(memStats.HeapInuse))
  82. runtimeMetrics.MemStats.HeapObjects.Update(int64(memStats.HeapObjects))
  83. runtimeMetrics.MemStats.HeapReleased.Update(int64(memStats.HeapReleased))
  84. runtimeMetrics.MemStats.HeapSys.Update(int64(memStats.HeapSys))
  85. runtimeMetrics.MemStats.LastGC.Update(int64(memStats.LastGC))
  86. runtimeMetrics.MemStats.Lookups.Update(int64(memStats.Lookups - lookups))
  87. runtimeMetrics.MemStats.Mallocs.Update(int64(memStats.Mallocs - mallocs))
  88. runtimeMetrics.MemStats.MCacheInuse.Update(int64(memStats.MCacheInuse))
  89. runtimeMetrics.MemStats.MCacheSys.Update(int64(memStats.MCacheSys))
  90. runtimeMetrics.MemStats.MSpanInuse.Update(int64(memStats.MSpanInuse))
  91. runtimeMetrics.MemStats.MSpanSys.Update(int64(memStats.MSpanSys))
  92. runtimeMetrics.MemStats.NextGC.Update(int64(memStats.NextGC))
  93. runtimeMetrics.MemStats.NumGC.Update(int64(memStats.NumGC - numGC))
  94. // <https://code.google.com/p/go/source/browse/src/pkg/runtime/mgc0.c>
  95. i := numGC % uint32(len(memStats.PauseNs))
  96. ii := memStats.NumGC % uint32(len(memStats.PauseNs))
  97. if memStats.NumGC-numGC >= uint32(len(memStats.PauseNs)) {
  98. for i = 0; i < uint32(len(memStats.PauseNs)); i++ {
  99. runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i]))
  100. }
  101. } else {
  102. if i > ii {
  103. for ; i < uint32(len(memStats.PauseNs)); i++ {
  104. runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i]))
  105. }
  106. i = 0
  107. }
  108. for ; i < ii; i++ {
  109. runtimeMetrics.MemStats.PauseNs.Update(int64(memStats.PauseNs[i]))
  110. }
  111. }
  112. frees = memStats.Frees
  113. lookups = memStats.Lookups
  114. mallocs = memStats.Mallocs
  115. numGC = memStats.NumGC
  116. runtimeMetrics.MemStats.PauseTotalNs.Update(int64(memStats.PauseTotalNs))
  117. runtimeMetrics.MemStats.StackInuse.Update(int64(memStats.StackInuse))
  118. runtimeMetrics.MemStats.StackSys.Update(int64(memStats.StackSys))
  119. runtimeMetrics.MemStats.Sys.Update(int64(memStats.Sys))
  120. runtimeMetrics.MemStats.TotalAlloc.Update(int64(memStats.TotalAlloc))
  121. runtimeMetrics.NumCgoCall.Update(numCgoCall())
  122. runtimeMetrics.NumGoroutine.Update(int64(runtime.NumGoroutine()))
  123. }
  124. // Register runtimeMetrics for the Go runtime statistics exported in runtime and
  125. // specifically runtime.MemStats. The runtimeMetrics are named by their
  126. // fully-qualified Go symbols, i.e. runtime.MemStats.Alloc.
  127. func RegisterRuntimeMemStats(r Registry) {
  128. runtimeMetrics.MemStats.Alloc = NewGauge()
  129. runtimeMetrics.MemStats.BuckHashSys = NewGauge()
  130. runtimeMetrics.MemStats.DebugGC = NewGauge()
  131. runtimeMetrics.MemStats.EnableGC = NewGauge()
  132. runtimeMetrics.MemStats.Frees = NewGauge()
  133. runtimeMetrics.MemStats.HeapAlloc = NewGauge()
  134. runtimeMetrics.MemStats.HeapIdle = NewGauge()
  135. runtimeMetrics.MemStats.HeapInuse = NewGauge()
  136. runtimeMetrics.MemStats.HeapObjects = NewGauge()
  137. runtimeMetrics.MemStats.HeapReleased = NewGauge()
  138. runtimeMetrics.MemStats.HeapSys = NewGauge()
  139. runtimeMetrics.MemStats.LastGC = NewGauge()
  140. runtimeMetrics.MemStats.Lookups = NewGauge()
  141. runtimeMetrics.MemStats.Mallocs = NewGauge()
  142. runtimeMetrics.MemStats.MCacheInuse = NewGauge()
  143. runtimeMetrics.MemStats.MCacheSys = NewGauge()
  144. runtimeMetrics.MemStats.MSpanInuse = NewGauge()
  145. runtimeMetrics.MemStats.MSpanSys = NewGauge()
  146. runtimeMetrics.MemStats.NextGC = NewGauge()
  147. runtimeMetrics.MemStats.NumGC = NewGauge()
  148. runtimeMetrics.MemStats.PauseNs = NewHistogram(NewExpDecaySample(1028, 0.015))
  149. runtimeMetrics.MemStats.PauseTotalNs = NewGauge()
  150. runtimeMetrics.MemStats.StackInuse = NewGauge()
  151. runtimeMetrics.MemStats.StackSys = NewGauge()
  152. runtimeMetrics.MemStats.Sys = NewGauge()
  153. runtimeMetrics.MemStats.TotalAlloc = NewGauge()
  154. runtimeMetrics.NumCgoCall = NewGauge()
  155. runtimeMetrics.NumGoroutine = NewGauge()
  156. runtimeMetrics.ReadMemStats = NewTimer()
  157. r.Register("runtime.MemStats.Alloc", runtimeMetrics.MemStats.Alloc)
  158. r.Register("runtime.MemStats.BuckHashSys", runtimeMetrics.MemStats.BuckHashSys)
  159. r.Register("runtime.MemStats.DebugGC", runtimeMetrics.MemStats.DebugGC)
  160. r.Register("runtime.MemStats.EnableGC", runtimeMetrics.MemStats.EnableGC)
  161. r.Register("runtime.MemStats.Frees", runtimeMetrics.MemStats.Frees)
  162. r.Register("runtime.MemStats.HeapAlloc", runtimeMetrics.MemStats.HeapAlloc)
  163. r.Register("runtime.MemStats.HeapIdle", runtimeMetrics.MemStats.HeapIdle)
  164. r.Register("runtime.MemStats.HeapInuse", runtimeMetrics.MemStats.HeapInuse)
  165. r.Register("runtime.MemStats.HeapObjects", runtimeMetrics.MemStats.HeapObjects)
  166. r.Register("runtime.MemStats.HeapReleased", runtimeMetrics.MemStats.HeapReleased)
  167. r.Register("runtime.MemStats.HeapSys", runtimeMetrics.MemStats.HeapSys)
  168. r.Register("runtime.MemStats.LastGC", runtimeMetrics.MemStats.LastGC)
  169. r.Register("runtime.MemStats.Lookups", runtimeMetrics.MemStats.Lookups)
  170. r.Register("runtime.MemStats.Mallocs", runtimeMetrics.MemStats.Mallocs)
  171. r.Register("runtime.MemStats.MCacheInuse", runtimeMetrics.MemStats.MCacheInuse)
  172. r.Register("runtime.MemStats.MCacheSys", runtimeMetrics.MemStats.MCacheSys)
  173. r.Register("runtime.MemStats.MSpanInuse", runtimeMetrics.MemStats.MSpanInuse)
  174. r.Register("runtime.MemStats.MSpanSys", runtimeMetrics.MemStats.MSpanSys)
  175. r.Register("runtime.MemStats.NextGC", runtimeMetrics.MemStats.NextGC)
  176. r.Register("runtime.MemStats.NumGC", runtimeMetrics.MemStats.NumGC)
  177. r.Register("runtime.MemStats.PauseNs", runtimeMetrics.MemStats.PauseNs)
  178. r.Register("runtime.MemStats.PauseTotalNs", runtimeMetrics.MemStats.PauseTotalNs)
  179. r.Register("runtime.MemStats.StackInuse", runtimeMetrics.MemStats.StackInuse)
  180. r.Register("runtime.MemStats.StackSys", runtimeMetrics.MemStats.StackSys)
  181. r.Register("runtime.MemStats.Sys", runtimeMetrics.MemStats.Sys)
  182. r.Register("runtime.MemStats.TotalAlloc", runtimeMetrics.MemStats.TotalAlloc)
  183. r.Register("runtime.NumCgoCall", runtimeMetrics.NumCgoCall)
  184. r.Register("runtime.NumGoroutine", runtimeMetrics.NumGoroutine)
  185. r.Register("runtime.ReadMemStats", runtimeMetrics.ReadMemStats)
  186. }