Skip to content

PMM-11984: Add new metrics pg_available_extensions and pg_extensions to expose info about available extensions and installed extensions accordingly #117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 19, 2023
112 changes: 112 additions & 0 deletions collector/pg_extensions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package collector

import (
"context"
"database/sql"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"strconv"
)

func init() {
registerCollector("extensions", defaultEnabled, NewExtensionsCollector)
}

var pgExtensions = map[string]*prometheus.Desc{
"pg_available_extensions": prometheus.NewDesc(
"pg_available_extensions",
"Extensions that are available for installation",
[]string{
"name",
"default_version",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does it mean default? used? I think we need a better name here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these lablels are copies of column names from the table from which we fetch these metrics.

I believe it means if you install this extensions and not specify the version this default version will be used.

"installed_version",
},
prometheus.Labels{},
),
"pg_extensions": prometheus.NewDesc(
"pg_extensions",
"Installed extensions",
[]string{
"extname",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why ext prefixes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably it means 'extension'

removed it

"extrelocatable",
"extversion",
},
prometheus.Labels{},
),
}

type ExtensionsCollector struct {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about checking that struct implements interface?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added it

logger log.Logger
}

func NewExtensionsCollector(logger log.Logger) (Collector, error) {
return &ExtensionsCollector{logger: logger}, nil
}

func (e *ExtensionsCollector) Update(ctx context.Context, server *server, ch chan<- prometheus.Metric) error {
db, err := server.GetDB()
if err != nil {
return err
}

err = e.scrapeAvailableExtensions(ctx, db, ch)
if err != nil {
return err
}

err = e.scrapeInstalledExtensions(ctx, db, ch)
if err != nil {
return err
}

return nil
}

func (e *ExtensionsCollector) scrapeInstalledExtensions(ctx context.Context, db *sql.DB, ch chan<- prometheus.Metric) error {
rowsExtensions, err := db.QueryContext(ctx, `SELECT extname, extrelocatable, extversion FROM pg_extension`)

if err != nil {
return err
}
defer rowsExtensions.Close()

for rowsExtensions.Next() {
var extname string
var extrelocatable bool
var extversion string
if err := rowsExtensions.Scan(&extname, &extrelocatable, &extversion); err != nil {
return err
}

ch <- prometheus.MustNewConstMetric(
pgExtensions["pg_extensions"],
prometheus.GaugeValue, 1,
extname, strconv.FormatBool(extrelocatable), extversion,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about putting each param on it's own line?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatted

)
}
return nil
}

func (e *ExtensionsCollector) scrapeAvailableExtensions(ctx context.Context, db *sql.DB, ch chan<- prometheus.Metric) error {
rows, err := db.QueryContext(ctx, `SELECT name, default_version, installed_version FROM pg_available_extensions`)
if err != nil {
return err
}
defer rows.Close()

for rows.Next() {
var name sql.NullString
var defaultVersion sql.NullString
var installedVersion sql.NullString
if err := rows.Scan(&name, &defaultVersion, &installedVersion); err != nil {
return err
}

ch <- prometheus.MustNewConstMetric(
pgExtensions["pg_available_extensions"],
prometheus.GaugeValue, 1,
name.String, defaultVersion.String, installedVersion.String,
)
}
return nil
}