Skip to content

Instantly share code, notes, and snippets.

@kushsharma
Created April 17, 2024 11:10
Show Gist options
  • Save kushsharma/558e6782ed5b820b6505db7a35cc463c to your computer and use it in GitHub Desktop.
Save kushsharma/558e6782ed5b820b6505db7a35cc463c to your computer and use it in GitHub Desktop.
Go: Collecting pgx/v4 prometheus metrics
package metrics
import (
"github.com/jackc/pgx/v4/pgxpool"
"github.com/prometheus/client_golang/prometheus"
)
// PgxPoolStatPromCollector is a Prometheus collector for pgx metrics using prometheus.Collector interface
type PgxPoolStatPromCollector struct {
db *pgxpool.Pool
stats []PgxPoolStatProm
}
type PgxPoolStatProm struct {
desc *prometheus.Desc
fn func(stats *pgxpool.Stat) float64
vt prometheus.ValueType
}
// NewPgxPoolStatPromCollector returns a new prometheus pgx Collector
func NewPgxPoolStatPromCollector(db *pgxpool.Pool, dbName string) *PgxPoolStatPromCollector {
fqName := func(name string) string {
return prometheus.BuildFQName("pgx", "pool", name)
}
promDesc := func(name string, help string) *prometheus.Desc {
return prometheus.NewDesc(
fqName(name),
help,
nil,
prometheus.Labels{"db": dbName},
)
}
return &PgxPoolStatPromCollector{
db: db,
stats: []PgxPoolStatProm{
{
desc: promDesc(
"acquire_connections",
"Number of connections currently acquired in the pool",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.AcquiredConns())
},
vt: prometheus.GaugeValue,
},
{
desc: promDesc(
"acquire_duration_seconds",
"The total duration of all successful acquires from the pool in seconds",
),
fn: func(stats *pgxpool.Stat) float64 {
return stats.AcquireDuration().Seconds()
},
vt: prometheus.CounterValue,
},
{
desc: promDesc(
"acquire_count",
"The cumulative count of successful acquires from the pool",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.AcquireCount())
},
vt: prometheus.CounterValue,
},
{
desc: promDesc(
"canceled_acquire_count",
"Number of cumulative times a connection acquire was canceled",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.CanceledAcquireCount())
},
vt: prometheus.CounterValue,
},
{
desc: promDesc(
"constructing_connections",
"Number of connections currently in the process of being constructed",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.ConstructingConns())
},
vt: prometheus.GaugeValue,
},
{
desc: promDesc(
"empty_acquire_count",
"The cumulative count of successful acquires from the pool that waited for a resource to be released or constructed because the pool was empty",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.EmptyAcquireCount())
},
vt: prometheus.CounterValue,
},
{
desc: promDesc(
"idle_connections",
"Number of idle connections in the pool",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.IdleConns())
},
vt: prometheus.GaugeValue,
},
{
desc: promDesc(
"max_connections",
"Maximum number of connections allowed in the pool",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.MaxConns())
},
vt: prometheus.CounterValue,
},
{
desc: promDesc(
"total_connections",
"The total number of resources currently in the pool. The value is the sum of Constructing, Acquired, and Idle connections",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.TotalConns())
},
vt: prometheus.GaugeValue,
},
{
desc: promDesc(
"new_connections_count",
"The cumulative count of new connections opened",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.NewConnsCount())
},
vt: prometheus.CounterValue,
},
{
desc: promDesc(
"max_lifetime_destroy_count",
"Number of connections destroyed due to MaxLifetime",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.MaxLifetimeDestroyCount())
},
vt: prometheus.CounterValue,
},
{
desc: promDesc(
"max_idle_destroy_count",
"Number of connections destroyed due to MaxIdleTime",
),
fn: func(stats *pgxpool.Stat) float64 {
return float64(stats.MaxIdleDestroyCount())
},
vt: prometheus.CounterValue,
},
},
}
}
// Describe implements the prometheus.Collector interface
func (p PgxPoolStatPromCollector) Describe(descs chan<- *prometheus.Desc) {
for _, stat := range p.stats {
descs <- stat.desc
}
}
// Collect implements the prometheus.Collector interface
func (p PgxPoolStatPromCollector) Collect(metrics chan<- prometheus.Metric) {
stats := p.db.Stat()
for _, stat := range p.stats {
metrics <- prometheus.MustNewConstMetric(stat.desc, stat.vt, stat.fn(stats))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment