github.com/kyleu/dbaudit@v0.0.2-0.20240321155047-ff2f2c940496/app/lib/telemetry/dbmetrics/collector.go (about) 1 // Package dbmetrics - Content managed by Project Forge, see [projectforge.md] for details. 2 package dbmetrics 3 4 import ( 5 "database/sql" 6 7 "github.com/prometheus/client_golang/prometheus" 8 ) 9 10 type StatsGetter interface { 11 Stats() sql.DBStats 12 } 13 14 type StatsCollector struct { 15 sg StatsGetter 16 maxOpenDesc *prometheus.Desc 17 openDesc *prometheus.Desc 18 inUseDesc *prometheus.Desc 19 idleDesc *prometheus.Desc 20 waitedForDesc *prometheus.Desc 21 blockedSecondsDesc *prometheus.Desc 22 closedMaxIdleDesc *prometheus.Desc 23 closedMaxLifetimeDesc *prometheus.Desc 24 closedMaxIdleTimeDesc *prometheus.Desc 25 } 26 27 func newStatsCollector(dbName string, sg StatsGetter) *StatsCollector { 28 labels := prometheus.Labels{"db_name": dbName} 29 x := func(key string, help string) *prometheus.Desc { 30 return prometheus.NewDesc(prometheus.BuildFQName("database", "database", key), help, nil, labels) 31 } 32 return &StatsCollector{ 33 sg: sg, 34 maxOpenDesc: x("max_open", "Maximum number of open connections to the database."), 35 openDesc: x("open", "The number of established connections both in use and idle."), 36 inUseDesc: x("in_use", "The number of connections currently in use."), 37 idleDesc: x("idle", "The number of idle connections."), 38 waitedForDesc: x("waited_for", "The total number of connections waited for."), 39 blockedSecondsDesc: x("blocked_seconds", "The total time blocked waiting for a new connection."), 40 closedMaxIdleDesc: x("closed_max_idle", "The total number of connections closed due to SetMaxIdleConns."), 41 closedMaxLifetimeDesc: x("closed_max_lifetime", "The total number of connections closed due to SetConnMaxLifetime."), 42 closedMaxIdleTimeDesc: x("closed_max_idle_time", "The total number of connections closed due to SetConnMaxIdleTime."), 43 } 44 } 45 46 // Describe implements the prometheus.Collector interface. 47 func (c *StatsCollector) Describe(ch chan<- *prometheus.Desc) { 48 ch <- c.maxOpenDesc 49 ch <- c.openDesc 50 ch <- c.inUseDesc 51 ch <- c.idleDesc 52 ch <- c.waitedForDesc 53 ch <- c.blockedSecondsDesc 54 ch <- c.closedMaxIdleDesc 55 ch <- c.closedMaxLifetimeDesc 56 ch <- c.closedMaxIdleTimeDesc 57 } 58 59 func (c *StatsCollector) Collect(ch chan<- prometheus.Metric) { 60 stats := c.sg.Stats() 61 ch <- prometheus.MustNewConstMetric(c.maxOpenDesc, prometheus.GaugeValue, float64(stats.MaxOpenConnections)) 62 ch <- prometheus.MustNewConstMetric(c.openDesc, prometheus.GaugeValue, float64(stats.OpenConnections)) 63 ch <- prometheus.MustNewConstMetric(c.inUseDesc, prometheus.GaugeValue, float64(stats.InUse)) 64 ch <- prometheus.MustNewConstMetric(c.idleDesc, prometheus.GaugeValue, float64(stats.Idle)) 65 ch <- prometheus.MustNewConstMetric(c.waitedForDesc, prometheus.CounterValue, float64(stats.WaitCount)) 66 ch <- prometheus.MustNewConstMetric(c.blockedSecondsDesc, prometheus.CounterValue, stats.WaitDuration.Seconds()) 67 ch <- prometheus.MustNewConstMetric(c.closedMaxIdleDesc, prometheus.CounterValue, float64(stats.MaxIdleClosed)) 68 ch <- prometheus.MustNewConstMetric(c.closedMaxLifetimeDesc, prometheus.CounterValue, float64(stats.MaxLifetimeClosed)) 69 ch <- prometheus.MustNewConstMetric(c.closedMaxIdleTimeDesc, prometheus.CounterValue, float64(stats.MaxIdleTimeClosed)) 70 }