Skip to content

Commit 84413ff

Browse files
Implement query references (#8)
This commit adds a global map of queries which can be reused in each job to save duplication of possibly huge queries. Fixes #7
1 parent 15609d1 commit 84413ff

4 files changed

Lines changed: 32 additions & 12 deletions

File tree

config.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ func Read(path string) (File, error) {
3737

3838
// File is a collection of jobs
3939
type File struct {
40-
Jobs []*Job `yaml:"jobs"`
40+
Jobs []*Job `yaml:"jobs"`
41+
Queries map[string]string `yaml:"queries"`
4142
}
4243

4344
// Job is a collection of connections and queries
@@ -63,12 +64,13 @@ type connection struct {
6364
// Query is an SQL query that is executed on a connection
6465
type Query struct {
6566
sync.Mutex
66-
log log.Logger
67-
desc *prometheus.Desc
68-
metrics map[*connection][]prometheus.Metric
69-
Name string `yaml:"name"` // the prometheus metric name
70-
Help string `yaml:"help"` // the prometheus metric help text
71-
Labels []string `yaml:"labels"` // expose these columns as labels per gauge
72-
Values []string `yaml:"values"` // expose each of these as an gauge
73-
Query string `yaml:"query"`
67+
log log.Logger
68+
desc *prometheus.Desc
69+
metrics map[*connection][]prometheus.Metric
70+
Name string `yaml:"name"` // the prometheus metric name
71+
Help string `yaml:"help"` // the prometheus metric help text
72+
Labels []string `yaml:"labels"` // expose these columns as labels per gauge
73+
Values []string `yaml:"values"` // expose each of these as an gauge
74+
Query string `yaml:"query"` // a literal query
75+
QueryRef string `yaml:"query_ref"` // references an query in the query map
7476
}

config.yml.dist

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,13 @@ jobs:
106106
, idx_blks_read::float
107107
, idx_blks_hit::float
108108
FROM pg_statio_user_tables;
109+
queries:
110+
pg_statio_user_tables: |
111+
SELECT
112+
schemaname::text
113+
, relname::text
114+
, heap_blks_read::float
115+
, heap_blks_hit::float
116+
, idx_blks_read::float
117+
, idx_blks_hit::float
118+
FROM pg_statio_user_tables;

exporter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func NewExporter(logger log.Logger, configFile string) (*Exporter, error) {
3434
if job == nil {
3535
continue
3636
}
37-
if err := job.Init(logger); err != nil {
37+
if err := job.Init(logger, cfg.Queries); err != nil {
3838
level.Warn(logger).Log("msg", "Skipping job. Failed to initialize", "err", err, "job", job.Name)
3939
continue
4040
}

job.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,23 @@ var (
2424
)
2525

2626
// Init will initialize the metric descriptors
27-
func (j *Job) Init(logger log.Logger) error {
27+
func (j *Job) Init(logger log.Logger, queries map[string]string) error {
2828
j.log = log.With(logger, "job", j.Name)
2929
// register each query as an metric
3030
for _, q := range j.Queries {
3131
if q == nil {
3232
level.Warn(j.log).Log("msg", "Skipping invalid query")
3333
continue
3434
}
35+
q.log = log.With(j.log, "query", q.Name)
36+
if q.Query == "" && q.QueryRef != "" {
37+
if qry, found := queries[q.QueryRef]; found {
38+
q.Query = qry
39+
}
40+
}
41+
if q.Query == "" {
42+
level.Warn(q.log).Log("msg", "Skipping empty query")
43+
}
3544
if q.metrics == nil {
3645
// we have no way of knowing how many metrics will be returned by the
3746
// queries, so we just assume that each query returns at least one metric.
@@ -41,7 +50,6 @@ func (j *Job) Init(logger log.Logger) error {
4150
// try to satisfy prometheus naming restrictions
4251
name := MetricNameRE.ReplaceAllString("sql_"+q.Name, "")
4352
help := q.Help
44-
q.log = log.With(j.log, "query", q.Name)
4553
// prepare a new metrics descriptor
4654
//
4755
// the tricky part here is that the *order* of labels has to match the

0 commit comments

Comments
 (0)