|
@@ -1,8 +1,14 @@
|
|
|
package sqlx
|
|
|
|
|
|
-import "github.com/zeromicro/go-zero/core/metric"
|
|
|
+import (
|
|
|
+ "database/sql"
|
|
|
+ "sync"
|
|
|
|
|
|
-const namespace = "sql_client"
|
|
|
+ "github.com/prometheus/client_golang/prometheus"
|
|
|
+ "github.com/zeromicro/go-zero/core/metric"
|
|
|
+)
|
|
|
+
|
|
|
+const namespace = "mysql_client"
|
|
|
|
|
|
var (
|
|
|
metricReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
|
|
@@ -11,7 +17,7 @@ var (
|
|
|
Name: "duration_ms",
|
|
|
Help: "mysql client requests duration(ms).",
|
|
|
Labels: []string{"command"},
|
|
|
- Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000, 2500},
|
|
|
+ Buckets: []float64{0.25, 0.5, 1, 1.5, 2, 3, 5, 10, 25, 50, 100, 250, 500, 1000, 2000, 5000, 10000, 15000},
|
|
|
})
|
|
|
metricReqErr = metric.NewCounterVec(&metric.CounterVecOpts{
|
|
|
Namespace: namespace,
|
|
@@ -20,4 +26,138 @@ var (
|
|
|
Help: "mysql client requests error count.",
|
|
|
Labels: []string{"command", "error"},
|
|
|
})
|
|
|
+ metricSlowCount = metric.NewCounterVec(&metric.CounterVecOpts{
|
|
|
+ Namespace: namespace,
|
|
|
+ Subsystem: "requests",
|
|
|
+ Name: "slow_total",
|
|
|
+ Help: "mysql client requests slow count.",
|
|
|
+ Labels: []string{"command"},
|
|
|
+ })
|
|
|
+
|
|
|
+ connLabels = []string{"db_name", "hash"}
|
|
|
+
|
|
|
+ connCollector = newCollector()
|
|
|
+
|
|
|
+ _ prometheus.Collector = (*collector)(nil)
|
|
|
)
|
|
|
+
|
|
|
+type (
|
|
|
+ statGetter struct {
|
|
|
+ dbName string
|
|
|
+ hash string
|
|
|
+ poolStats func() sql.DBStats
|
|
|
+ }
|
|
|
+
|
|
|
+ // collector collects statistics from a redis client.
|
|
|
+ // It implements the prometheus.Collector interface.
|
|
|
+ collector struct {
|
|
|
+ maxOpenConnections *prometheus.Desc
|
|
|
+
|
|
|
+ openConnections *prometheus.Desc
|
|
|
+ inUseConnections *prometheus.Desc
|
|
|
+ idleConnections *prometheus.Desc
|
|
|
+
|
|
|
+ waitCount *prometheus.Desc
|
|
|
+ waitDuration *prometheus.Desc
|
|
|
+ maxIdleClosed *prometheus.Desc
|
|
|
+ maxIdleTimeClosed *prometheus.Desc
|
|
|
+ maxLifetimeClosed *prometheus.Desc
|
|
|
+
|
|
|
+ clients []*statGetter
|
|
|
+ lock sync.Mutex
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
+func newCollector() *collector {
|
|
|
+ c := &collector{
|
|
|
+ maxOpenConnections: prometheus.NewDesc(
|
|
|
+ prometheus.BuildFQName(namespace, "", "max_open_connections"),
|
|
|
+ "Maximum number of open connections to the database.",
|
|
|
+ connLabels, nil,
|
|
|
+ ),
|
|
|
+ openConnections: prometheus.NewDesc(
|
|
|
+ prometheus.BuildFQName(namespace, "", "open_connections"),
|
|
|
+ "The number of established connections both in use and idle.",
|
|
|
+ connLabels, nil,
|
|
|
+ ),
|
|
|
+ inUseConnections: prometheus.NewDesc(
|
|
|
+ prometheus.BuildFQName(namespace, "", "in_use_connections"),
|
|
|
+ "The number of connections currently in use.",
|
|
|
+ connLabels, nil,
|
|
|
+ ),
|
|
|
+ idleConnections: prometheus.NewDesc(
|
|
|
+ prometheus.BuildFQName(namespace, "", "idle_connections"),
|
|
|
+ "The number of idle connections.",
|
|
|
+ connLabels, nil,
|
|
|
+ ),
|
|
|
+ waitCount: prometheus.NewDesc(
|
|
|
+ prometheus.BuildFQName(namespace, "", "wait_count_total"),
|
|
|
+ "The total number of connections waited for.",
|
|
|
+ connLabels, nil,
|
|
|
+ ),
|
|
|
+ waitDuration: prometheus.NewDesc(
|
|
|
+ prometheus.BuildFQName(namespace, "", "wait_duration_seconds_total"),
|
|
|
+ "The total time blocked waiting for a new connection.",
|
|
|
+ connLabels, nil,
|
|
|
+ ),
|
|
|
+ maxIdleClosed: prometheus.NewDesc(
|
|
|
+ prometheus.BuildFQName(namespace, "", "max_idle_closed_total"),
|
|
|
+ "The total number of connections closed due to SetMaxIdleConns.",
|
|
|
+ connLabels, nil,
|
|
|
+ ),
|
|
|
+ maxIdleTimeClosed: prometheus.NewDesc(
|
|
|
+ prometheus.BuildFQName(namespace, "", "max_idle_time_closed_total"),
|
|
|
+ "The total number of connections closed due to SetConnMaxIdleTime.",
|
|
|
+ connLabels, nil,
|
|
|
+ ),
|
|
|
+ maxLifetimeClosed: prometheus.NewDesc(
|
|
|
+ prometheus.BuildFQName(namespace, "", "max_lifetime_closed_total"),
|
|
|
+ "The total number of connections closed due to SetConnMaxLifetime.",
|
|
|
+ connLabels, nil,
|
|
|
+ ),
|
|
|
+ }
|
|
|
+
|
|
|
+ prometheus.MustRegister(c)
|
|
|
+
|
|
|
+ return c
|
|
|
+}
|
|
|
+
|
|
|
+// Describe implements the prometheus.Collector interface.
|
|
|
+func (c *collector) Describe(ch chan<- *prometheus.Desc) {
|
|
|
+ ch <- c.maxOpenConnections
|
|
|
+ ch <- c.openConnections
|
|
|
+ ch <- c.inUseConnections
|
|
|
+ ch <- c.idleConnections
|
|
|
+ ch <- c.waitCount
|
|
|
+ ch <- c.waitDuration
|
|
|
+ ch <- c.maxIdleClosed
|
|
|
+ ch <- c.maxLifetimeClosed
|
|
|
+ ch <- c.maxIdleTimeClosed
|
|
|
+}
|
|
|
+
|
|
|
+// Collect implements the prometheus.Collector interface.
|
|
|
+func (c *collector) Collect(ch chan<- prometheus.Metric) {
|
|
|
+ c.lock.Lock()
|
|
|
+ defer c.lock.Unlock()
|
|
|
+
|
|
|
+ for _, client := range c.clients {
|
|
|
+ dbName, hash := client.dbName, client.hash
|
|
|
+ stats := client.poolStats()
|
|
|
+ ch <- prometheus.MustNewConstMetric(c.maxOpenConnections, prometheus.GaugeValue, float64(stats.MaxOpenConnections), dbName, hash)
|
|
|
+ ch <- prometheus.MustNewConstMetric(c.openConnections, prometheus.GaugeValue, float64(stats.OpenConnections), dbName, hash)
|
|
|
+ ch <- prometheus.MustNewConstMetric(c.inUseConnections, prometheus.GaugeValue, float64(stats.InUse), dbName, hash)
|
|
|
+ ch <- prometheus.MustNewConstMetric(c.idleConnections, prometheus.GaugeValue, float64(stats.Idle), dbName, hash)
|
|
|
+ ch <- prometheus.MustNewConstMetric(c.waitCount, prometheus.CounterValue, float64(stats.WaitCount), dbName, hash)
|
|
|
+ ch <- prometheus.MustNewConstMetric(c.waitDuration, prometheus.CounterValue, stats.WaitDuration.Seconds(), dbName, hash)
|
|
|
+ ch <- prometheus.MustNewConstMetric(c.maxIdleClosed, prometheus.CounterValue, float64(stats.MaxIdleClosed), dbName, hash)
|
|
|
+ ch <- prometheus.MustNewConstMetric(c.maxLifetimeClosed, prometheus.CounterValue, float64(stats.MaxLifetimeClosed), dbName, hash)
|
|
|
+ ch <- prometheus.MustNewConstMetric(c.maxIdleTimeClosed, prometheus.CounterValue, float64(stats.MaxIdleTimeClosed), dbName, hash)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (c *collector) registerClient(client *statGetter) {
|
|
|
+ c.lock.Lock()
|
|
|
+ defer c.lock.Unlock()
|
|
|
+
|
|
|
+ c.clients = append(c.clients, client)
|
|
|
+}
|