metrics.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package sqlx
  2. import (
  3. "database/sql"
  4. "sync"
  5. "github.com/prometheus/client_golang/prometheus"
  6. "github.com/zeromicro/go-zero/core/metric"
  7. )
  8. const namespace = "mysql_client"
  9. var (
  10. metricReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
  11. Namespace: namespace,
  12. Subsystem: "requests",
  13. Name: "duration_ms",
  14. Help: "mysql client requests duration(ms).",
  15. Labels: []string{"command"},
  16. Buckets: []float64{0.25, 0.5, 1, 1.5, 2, 3, 5, 10, 25, 50, 100, 250, 500, 1000, 2000, 5000, 10000, 15000},
  17. })
  18. metricReqErr = metric.NewCounterVec(&metric.CounterVecOpts{
  19. Namespace: namespace,
  20. Subsystem: "requests",
  21. Name: "error_total",
  22. Help: "mysql client requests error count.",
  23. Labels: []string{"command", "error"},
  24. })
  25. metricSlowCount = metric.NewCounterVec(&metric.CounterVecOpts{
  26. Namespace: namespace,
  27. Subsystem: "requests",
  28. Name: "slow_total",
  29. Help: "mysql client requests slow count.",
  30. Labels: []string{"command"},
  31. })
  32. connLabels = []string{"db_name", "hash"}
  33. connCollector = newCollector()
  34. _ prometheus.Collector = (*collector)(nil)
  35. )
  36. type (
  37. statGetter struct {
  38. dbName string
  39. hash string
  40. poolStats func() sql.DBStats
  41. }
  42. // collector collects statistics from a redis client.
  43. // It implements the prometheus.Collector interface.
  44. collector struct {
  45. maxOpenConnections *prometheus.Desc
  46. openConnections *prometheus.Desc
  47. inUseConnections *prometheus.Desc
  48. idleConnections *prometheus.Desc
  49. waitCount *prometheus.Desc
  50. waitDuration *prometheus.Desc
  51. maxIdleClosed *prometheus.Desc
  52. maxIdleTimeClosed *prometheus.Desc
  53. maxLifetimeClosed *prometheus.Desc
  54. clients []*statGetter
  55. lock sync.Mutex
  56. }
  57. )
  58. func newCollector() *collector {
  59. c := &collector{
  60. maxOpenConnections: prometheus.NewDesc(
  61. prometheus.BuildFQName(namespace, "", "max_open_connections"),
  62. "Maximum number of open connections to the database.",
  63. connLabels, nil,
  64. ),
  65. openConnections: prometheus.NewDesc(
  66. prometheus.BuildFQName(namespace, "", "open_connections"),
  67. "The number of established connections both in use and idle.",
  68. connLabels, nil,
  69. ),
  70. inUseConnections: prometheus.NewDesc(
  71. prometheus.BuildFQName(namespace, "", "in_use_connections"),
  72. "The number of connections currently in use.",
  73. connLabels, nil,
  74. ),
  75. idleConnections: prometheus.NewDesc(
  76. prometheus.BuildFQName(namespace, "", "idle_connections"),
  77. "The number of idle connections.",
  78. connLabels, nil,
  79. ),
  80. waitCount: prometheus.NewDesc(
  81. prometheus.BuildFQName(namespace, "", "wait_count_total"),
  82. "The total number of connections waited for.",
  83. connLabels, nil,
  84. ),
  85. waitDuration: prometheus.NewDesc(
  86. prometheus.BuildFQName(namespace, "", "wait_duration_seconds_total"),
  87. "The total time blocked waiting for a new connection.",
  88. connLabels, nil,
  89. ),
  90. maxIdleClosed: prometheus.NewDesc(
  91. prometheus.BuildFQName(namespace, "", "max_idle_closed_total"),
  92. "The total number of connections closed due to SetMaxIdleConns.",
  93. connLabels, nil,
  94. ),
  95. maxIdleTimeClosed: prometheus.NewDesc(
  96. prometheus.BuildFQName(namespace, "", "max_idle_time_closed_total"),
  97. "The total number of connections closed due to SetConnMaxIdleTime.",
  98. connLabels, nil,
  99. ),
  100. maxLifetimeClosed: prometheus.NewDesc(
  101. prometheus.BuildFQName(namespace, "", "max_lifetime_closed_total"),
  102. "The total number of connections closed due to SetConnMaxLifetime.",
  103. connLabels, nil,
  104. ),
  105. }
  106. prometheus.MustRegister(c)
  107. return c
  108. }
  109. // Describe implements the prometheus.Collector interface.
  110. func (c *collector) Describe(ch chan<- *prometheus.Desc) {
  111. ch <- c.maxOpenConnections
  112. ch <- c.openConnections
  113. ch <- c.inUseConnections
  114. ch <- c.idleConnections
  115. ch <- c.waitCount
  116. ch <- c.waitDuration
  117. ch <- c.maxIdleClosed
  118. ch <- c.maxLifetimeClosed
  119. ch <- c.maxIdleTimeClosed
  120. }
  121. // Collect implements the prometheus.Collector interface.
  122. func (c *collector) Collect(ch chan<- prometheus.Metric) {
  123. c.lock.Lock()
  124. defer c.lock.Unlock()
  125. for _, client := range c.clients {
  126. dbName, hash := client.dbName, client.hash
  127. stats := client.poolStats()
  128. ch <- prometheus.MustNewConstMetric(c.maxOpenConnections, prometheus.GaugeValue, float64(stats.MaxOpenConnections), dbName, hash)
  129. ch <- prometheus.MustNewConstMetric(c.openConnections, prometheus.GaugeValue, float64(stats.OpenConnections), dbName, hash)
  130. ch <- prometheus.MustNewConstMetric(c.inUseConnections, prometheus.GaugeValue, float64(stats.InUse), dbName, hash)
  131. ch <- prometheus.MustNewConstMetric(c.idleConnections, prometheus.GaugeValue, float64(stats.Idle), dbName, hash)
  132. ch <- prometheus.MustNewConstMetric(c.waitCount, prometheus.CounterValue, float64(stats.WaitCount), dbName, hash)
  133. ch <- prometheus.MustNewConstMetric(c.waitDuration, prometheus.CounterValue, stats.WaitDuration.Seconds(), dbName, hash)
  134. ch <- prometheus.MustNewConstMetric(c.maxIdleClosed, prometheus.CounterValue, float64(stats.MaxIdleClosed), dbName, hash)
  135. ch <- prometheus.MustNewConstMetric(c.maxLifetimeClosed, prometheus.CounterValue, float64(stats.MaxLifetimeClosed), dbName, hash)
  136. ch <- prometheus.MustNewConstMetric(c.maxIdleTimeClosed, prometheus.CounterValue, float64(stats.MaxIdleTimeClosed), dbName, hash)
  137. }
  138. }
  139. func (c *collector) registerClient(client *statGetter) {
  140. c.lock.Lock()
  141. defer c.lock.Unlock()
  142. c.clients = append(c.clients, client)
  143. }