From 36d3b1e9fb242cdaabde4acb2d40879c24d7fd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Sat, 22 May 2021 20:27:13 -0700 Subject: [PATCH] Add database stats to Prometheus exporter --- metric/metric.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++ storage/storage.go | 8 ++++-- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/metric/metric.go b/metric/metric.go index 8e1c972e..924f44ac 100644 --- a/metric/metric.go +++ b/metric/metric.go @@ -78,6 +78,62 @@ var ( }, []string{"status"}, ) + + dbOpenConnectionsGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: "miniflux", + Name: "db_open_connections", + Help: "The number of established connections both in use and idle", + }, + ) + + dbConnectionsInUseGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: "miniflux", + Name: "db_connections_in_use", + Help: "The number of connections currently in use", + }, + ) + + dbConnectionsIdleGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: "miniflux", + Name: "db_connections_idle", + Help: "The number of idle connections", + }, + ) + + dbConnectionsWaitCountGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: "miniflux", + Name: "db_connections_wait_count", + Help: "The total number of connections waited for", + }, + ) + + dbConnectionsMaxIdleClosedGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: "miniflux", + Name: "db_connections_max_idle_closed", + Help: "The total number of connections closed due to SetMaxIdleConns", + }, + ) + + dbConnectionsMaxIdleTimeClosedGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: "miniflux", + Name: "db_connections_max_idle_time_closed", + Help: "The total number of connections closed due to SetConnMaxIdleTime", + }, + ) + + dbConnectionsMaxLifetimeClosedGauge = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: "miniflux", + Name: "db_connections_max_lifetime_closed", + Help: "The total number of connections closed due to SetConnMaxLifetime", + }, + ) ) // Collector represents a metric collector. @@ -95,6 +151,13 @@ func NewCollector(store *storage.Storage, refreshInterval int) *Collector { prometheus.MustRegister(feedsGauge) prometheus.MustRegister(brokenFeedsGauge) prometheus.MustRegister(entriesGauge) + prometheus.MustRegister(dbOpenConnectionsGauge) + prometheus.MustRegister(dbConnectionsInUseGauge) + prometheus.MustRegister(dbConnectionsIdleGauge) + prometheus.MustRegister(dbConnectionsWaitCountGauge) + prometheus.MustRegister(dbConnectionsMaxIdleClosedGauge) + prometheus.MustRegister(dbConnectionsMaxIdleTimeClosedGauge) + prometheus.MustRegister(dbConnectionsMaxLifetimeClosedGauge) return &Collector{store, refreshInterval} } @@ -116,5 +179,14 @@ func (c *Collector) GatherStorageMetrics() { for status, count := range entriesCount { entriesGauge.WithLabelValues(status).Set(float64(count)) } + + dbStats := c.store.DBStats() + dbOpenConnectionsGauge.Set(float64(dbStats.OpenConnections)) + dbConnectionsInUseGauge.Set(float64(dbStats.InUse)) + dbConnectionsIdleGauge.Set(float64(dbStats.Idle)) + dbConnectionsWaitCountGauge.Set(float64(dbStats.WaitCount)) + dbConnectionsMaxIdleClosedGauge.Set(float64(dbStats.MaxIdleClosed)) + dbConnectionsMaxIdleTimeClosedGauge.Set(float64(dbStats.MaxIdleTimeClosed)) + dbConnectionsMaxLifetimeClosedGauge.Set(float64(dbStats.MaxLifetimeClosed)) } } diff --git a/storage/storage.go b/storage/storage.go index ef73e569..947011bb 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -31,6 +31,10 @@ func (s *Storage) DatabaseVersion() string { // Ping checks if the database connection works. func (s *Storage) Ping() error { - _, err := s.db.Exec(`SELECT true`) - return err + return s.db.Ping() +} + +// DBStats returns database statistics. +func (s *Storage) DBStats() sql.DBStats { + return s.db.Stats() }