Skip to content

Commit f92f0b3

Browse files
dliakhovritbl
andauthored
PMM-11984: Add new metrics pg_available_extensions and pg_extensions to expose info about available extensions and installed extensions accordingly (#117)
* PMM-11984: Add new metrics `pg_available_extensions` and `pg_extensions` to expose info about available extensions and installed extensions accordingly * PMM-11984: Exclude comment from the metric * PMM-11984: Fix small issues * PMM-11984: Update label values --------- Co-authored-by: Alexey Mukas <[email protected]>
1 parent 324071f commit f92f0b3

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

Diff for: collector/pg_extensions.go

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package collector
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
"github.com/go-kit/log"
7+
"github.com/prometheus/client_golang/prometheus"
8+
"strconv"
9+
)
10+
11+
func init() {
12+
registerCollector("extensions", defaultEnabled, NewExtensionsCollector)
13+
}
14+
15+
var pgExtensions = map[string]*prometheus.Desc{
16+
"pg_available_extensions": prometheus.NewDesc(
17+
"pg_available_extensions",
18+
"Extensions that are available for installation",
19+
[]string{
20+
"name",
21+
"default_version",
22+
"installed_version",
23+
},
24+
prometheus.Labels{},
25+
),
26+
"pg_extensions": prometheus.NewDesc(
27+
"pg_extensions",
28+
"Installed extensions",
29+
[]string{
30+
"name",
31+
"relocatable",
32+
"version",
33+
},
34+
prometheus.Labels{},
35+
),
36+
}
37+
38+
type ExtensionsCollector struct {
39+
logger log.Logger
40+
}
41+
42+
func NewExtensionsCollector(logger log.Logger) (Collector, error) {
43+
return &ExtensionsCollector{logger: logger}, nil
44+
}
45+
46+
func (e *ExtensionsCollector) Update(ctx context.Context, server *server, ch chan<- prometheus.Metric) error {
47+
db, err := server.GetDB()
48+
if err != nil {
49+
return err
50+
}
51+
52+
err = e.scrapeAvailableExtensions(ctx, db, ch)
53+
if err != nil {
54+
return err
55+
}
56+
57+
err = e.scrapeInstalledExtensions(ctx, db, ch)
58+
if err != nil {
59+
return err
60+
}
61+
62+
return nil
63+
}
64+
65+
func (e *ExtensionsCollector) scrapeInstalledExtensions(ctx context.Context, db *sql.DB, ch chan<- prometheus.Metric) error {
66+
rowsExtensions, err := db.QueryContext(ctx, `SELECT extname, extrelocatable, extversion FROM pg_extension`)
67+
68+
if err != nil {
69+
return err
70+
}
71+
defer rowsExtensions.Close()
72+
73+
for rowsExtensions.Next() {
74+
var extname string
75+
var extrelocatable bool
76+
var extversion string
77+
if err := rowsExtensions.Scan(&extname, &extrelocatable, &extversion); err != nil {
78+
return err
79+
}
80+
81+
ch <- prometheus.MustNewConstMetric(
82+
pgExtensions["pg_extensions"],
83+
prometheus.GaugeValue,
84+
1,
85+
extname,
86+
strconv.FormatBool(extrelocatable),
87+
extversion,
88+
)
89+
}
90+
91+
return nil
92+
}
93+
94+
func (e *ExtensionsCollector) scrapeAvailableExtensions(ctx context.Context, db *sql.DB, ch chan<- prometheus.Metric) error {
95+
rows, err := db.QueryContext(ctx, `SELECT name, default_version, installed_version FROM pg_available_extensions`)
96+
if err != nil {
97+
return err
98+
}
99+
defer rows.Close()
100+
101+
for rows.Next() {
102+
var name sql.NullString
103+
var defaultVersion sql.NullString
104+
var installedVersion sql.NullString
105+
if err := rows.Scan(&name, &defaultVersion, &installedVersion); err != nil {
106+
return err
107+
}
108+
109+
ch <- prometheus.MustNewConstMetric(
110+
pgExtensions["pg_available_extensions"],
111+
prometheus.GaugeValue,
112+
1,
113+
name.String,
114+
defaultVersion.String,
115+
installedVersion.String,
116+
)
117+
}
118+
119+
return nil
120+
}
121+
122+
var _ = (Collector)(&ExtensionsCollector{})

0 commit comments

Comments
 (0)