debug.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package metrics
  2. import (
  3. "runtime/debug"
  4. "time"
  5. )
  6. var (
  7. debugMetrics struct {
  8. GCStats struct {
  9. LastGC Gauge
  10. NumGC Gauge
  11. Pause Histogram
  12. //PauseQuantiles Histogram
  13. PauseTotal Gauge
  14. }
  15. ReadGCStats Timer
  16. }
  17. gcStats debug.GCStats
  18. )
  19. // Capture new values for the Go garbage collector statistics exported in
  20. // debug.GCStats. This is designed to be called as a goroutine.
  21. func CaptureDebugGCStats(r Registry, d time.Duration) {
  22. for _ = range time.Tick(d) {
  23. CaptureDebugGCStatsOnce(r)
  24. }
  25. }
  26. // Capture new values for the Go garbage collector statistics exported in
  27. // debug.GCStats. This is designed to be called in a background goroutine.
  28. // Giving a registry which has not been given to RegisterDebugGCStats will
  29. // panic.
  30. //
  31. // Be careful (but much less so) with this because debug.ReadGCStats calls
  32. // the C function runtime·lock(runtime·mheap) which, while not a stop-the-world
  33. // operation, isn't something you want to be doing all the time.
  34. func CaptureDebugGCStatsOnce(r Registry) {
  35. lastGC := gcStats.LastGC
  36. t := time.Now()
  37. debug.ReadGCStats(&gcStats)
  38. debugMetrics.ReadGCStats.UpdateSince(t)
  39. debugMetrics.GCStats.LastGC.Update(int64(gcStats.LastGC.UnixNano()))
  40. debugMetrics.GCStats.NumGC.Update(int64(gcStats.NumGC))
  41. if lastGC != gcStats.LastGC && 0 < len(gcStats.Pause) {
  42. debugMetrics.GCStats.Pause.Update(int64(gcStats.Pause[0]))
  43. }
  44. //debugMetrics.GCStats.PauseQuantiles.Update(gcStats.PauseQuantiles)
  45. debugMetrics.GCStats.PauseTotal.Update(int64(gcStats.PauseTotal))
  46. }
  47. // Register metrics for the Go garbage collector statistics exported in
  48. // debug.GCStats. The metrics are named by their fully-qualified Go symbols,
  49. // i.e. debug.GCStats.PauseTotal.
  50. func RegisterDebugGCStats(r Registry) {
  51. debugMetrics.GCStats.LastGC = NewGauge()
  52. debugMetrics.GCStats.NumGC = NewGauge()
  53. debugMetrics.GCStats.Pause = NewHistogram(NewExpDecaySample(1028, 0.015))
  54. //debugMetrics.GCStats.PauseQuantiles = NewHistogram(NewExpDecaySample(1028, 0.015))
  55. debugMetrics.GCStats.PauseTotal = NewGauge()
  56. debugMetrics.ReadGCStats = NewTimer()
  57. r.Register("debug.GCStats.LastGC", debugMetrics.GCStats.LastGC)
  58. r.Register("debug.GCStats.NumGC", debugMetrics.GCStats.NumGC)
  59. r.Register("debug.GCStats.Pause", debugMetrics.GCStats.Pause)
  60. //r.Register("debug.GCStats.PauseQuantiles", debugMetrics.GCStats.PauseQuantiles)
  61. r.Register("debug.GCStats.PauseTotal", debugMetrics.GCStats.PauseTotal)
  62. r.Register("debug.ReadGCStats", debugMetrics.ReadGCStats)
  63. }
  64. // Allocate an initial slice for gcStats.Pause to avoid allocations during
  65. // normal operation.
  66. func init() {
  67. gcStats.Pause = make([]time.Duration, 11)
  68. }