1// Copyright 2021 The Prometheus Authors 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package collectors 15 16import ( 17 "database/sql" 18 19 "github.com/prometheus/client_golang/prometheus" 20) 21 22type dbStatsCollector struct { 23 db *sql.DB 24 25 maxOpenConnections *prometheus.Desc 26 27 openConnections *prometheus.Desc 28 inUseConnections *prometheus.Desc 29 idleConnections *prometheus.Desc 30 31 waitCount *prometheus.Desc 32 waitDuration *prometheus.Desc 33 maxIdleClosed *prometheus.Desc 34 maxIdleTimeClosed *prometheus.Desc 35 maxLifetimeClosed *prometheus.Desc 36} 37 38// NewDBStatsCollector returns a collector that exports metrics about the given *sql.DB. 39// See https://golang.org/pkg/database/sql/#DBStats for more information on stats. 40func NewDBStatsCollector(db *sql.DB, dbName string) prometheus.Collector { 41 fqName := func(name string) string { 42 return "go_sql_" + name 43 } 44 return &dbStatsCollector{ 45 db: db, 46 maxOpenConnections: prometheus.NewDesc( 47 fqName("max_open_connections"), 48 "Maximum number of open connections to the database.", 49 nil, prometheus.Labels{"db_name": dbName}, 50 ), 51 openConnections: prometheus.NewDesc( 52 fqName("open_connections"), 53 "The number of established connections both in use and idle.", 54 nil, prometheus.Labels{"db_name": dbName}, 55 ), 56 inUseConnections: prometheus.NewDesc( 57 fqName("in_use_connections"), 58 "The number of connections currently in use.", 59 nil, prometheus.Labels{"db_name": dbName}, 60 ), 61 idleConnections: prometheus.NewDesc( 62 fqName("idle_connections"), 63 "The number of idle connections.", 64 nil, prometheus.Labels{"db_name": dbName}, 65 ), 66 waitCount: prometheus.NewDesc( 67 fqName("wait_count_total"), 68 "The total number of connections waited for.", 69 nil, prometheus.Labels{"db_name": dbName}, 70 ), 71 waitDuration: prometheus.NewDesc( 72 fqName("wait_duration_seconds_total"), 73 "The total time blocked waiting for a new connection.", 74 nil, prometheus.Labels{"db_name": dbName}, 75 ), 76 maxIdleClosed: prometheus.NewDesc( 77 fqName("max_idle_closed_total"), 78 "The total number of connections closed due to SetMaxIdleConns.", 79 nil, prometheus.Labels{"db_name": dbName}, 80 ), 81 maxIdleTimeClosed: prometheus.NewDesc( 82 fqName("max_idle_time_closed_total"), 83 "The total number of connections closed due to SetConnMaxIdleTime.", 84 nil, prometheus.Labels{"db_name": dbName}, 85 ), 86 maxLifetimeClosed: prometheus.NewDesc( 87 fqName("max_lifetime_closed_total"), 88 "The total number of connections closed due to SetConnMaxLifetime.", 89 nil, prometheus.Labels{"db_name": dbName}, 90 ), 91 } 92} 93 94// Describe implements Collector. 95func (c *dbStatsCollector) Describe(ch chan<- *prometheus.Desc) { 96 ch <- c.maxOpenConnections 97 ch <- c.openConnections 98 ch <- c.inUseConnections 99 ch <- c.idleConnections 100 ch <- c.waitCount 101 ch <- c.waitDuration 102 ch <- c.maxIdleClosed 103 ch <- c.maxLifetimeClosed 104 c.describeNewInGo115(ch) 105} 106 107// Collect implements Collector. 108func (c *dbStatsCollector) Collect(ch chan<- prometheus.Metric) { 109 stats := c.db.Stats() 110 ch <- prometheus.MustNewConstMetric(c.maxOpenConnections, prometheus.GaugeValue, float64(stats.MaxOpenConnections)) 111 ch <- prometheus.MustNewConstMetric(c.openConnections, prometheus.GaugeValue, float64(stats.OpenConnections)) 112 ch <- prometheus.MustNewConstMetric(c.inUseConnections, prometheus.GaugeValue, float64(stats.InUse)) 113 ch <- prometheus.MustNewConstMetric(c.idleConnections, prometheus.GaugeValue, float64(stats.Idle)) 114 ch <- prometheus.MustNewConstMetric(c.waitCount, prometheus.CounterValue, float64(stats.WaitCount)) 115 ch <- prometheus.MustNewConstMetric(c.waitDuration, prometheus.CounterValue, stats.WaitDuration.Seconds()) 116 ch <- prometheus.MustNewConstMetric(c.maxIdleClosed, prometheus.CounterValue, float64(stats.MaxIdleClosed)) 117 ch <- prometheus.MustNewConstMetric(c.maxLifetimeClosed, prometheus.CounterValue, float64(stats.MaxLifetimeClosed)) 118 c.collectNewInGo115(ch, stats) 119} 120