-
Notifications
You must be signed in to change notification settings - Fork 12
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
Changes from 2 commits
5f094d2
44c5308
0aaa625
e5538d4
f8981d7
6785609
38dbe1c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why ext prefixes? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how about checking that struct implements interface? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added it |
||
logger log.Logger | ||
} | ||
|
||
func NewExtensionsCollector(logger log.Logger) (Collector, error) { | ||
ritbl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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`) | ||
ritbl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how about putting each param on it's own line? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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`) | ||
ritbl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 | ||
} |
Uh oh!
There was an error while loading. Please reload this page.