Skip to content

Commit 43c7666

Browse files
committed
added breaking changes feature
Signed-off-by: vl4deee11 <[email protected]>
1 parent e43b976 commit 43c7666

File tree

4 files changed

+84
-9
lines changed

4 files changed

+84
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2021 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package main
15+
16+
import (
17+
"github.com/blang/semver"
18+
)
19+
20+
type BreakingChanges struct {
21+
Version string `yaml:"version"`
22+
ver semver.Version
23+
Columns map[string]string `yaml:"columns"`
24+
}
25+
26+
func (bc *BreakingChanges) parseVerTolerant() error {
27+
bcVer, err := semver.ParseTolerant(bc.Version)
28+
if err != nil {
29+
return err
30+
}
31+
32+
bc.ver = bcVer
33+
return nil
34+
}

cmd/postgres_exporter/postgres_exporter.go

+32-7
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,12 @@ type Mapping map[string]MappingOptions
119119

120120
// nolint: golint
121121
type UserQuery struct {
122-
Query string `yaml:"query"`
123-
Metrics []Mapping `yaml:"metrics"`
124-
Master bool `yaml:"master"` // Querying only for master database
125-
CacheSeconds uint64 `yaml:"cache_seconds"` // Number of seconds to cache the namespace result metrics for.
126-
RunOnServer string `yaml:"runonserver"` // Querying to run on which server version
122+
Query string `yaml:"query"`
123+
Metrics []Mapping `yaml:"metrics"`
124+
BreakingChanges []BreakingChanges `yaml:"breakingChanges"`
125+
Master bool `yaml:"master"` // Querying only for master database
126+
CacheSeconds uint64 `yaml:"cache_seconds"` // Number of seconds to cache the namespace result metrics for.
127+
RunOnServer string `yaml:"runonserver"` // Querying to run on which server version
127128
}
128129

129130
// nolint: golint
@@ -517,7 +518,7 @@ func makeQueryOverrideMap(pgVersion semver.Version, queryOverrides map[string][]
517518
return resultMap
518519
}
519520

520-
func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[string]string, error) {
521+
func parseUserQueries(content []byte, pgVersion semver.Version) (map[string]intermediateMetricMap, map[string]string, error) {
521522
var userQueries UserQueries
522523

523524
err := yaml.Unmarshal(content, &userQueries)
@@ -532,6 +533,30 @@ func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[str
532533
for metric, specs := range userQueries {
533534
level.Debug(logger).Log("msg", "New user metric namespace from YAML metric", "metric", metric, "cache_seconds", specs.CacheSeconds)
534535
newQueryOverrides[metric] = specs.Query
536+
columnT := make(map[string]string)
537+
for i := range specs.BreakingChanges {
538+
if err := specs.BreakingChanges[i].parseVerTolerant(); err != nil {
539+
return nil, nil, err
540+
}
541+
542+
if pgVersion.GE(specs.BreakingChanges[i].ver) {
543+
for t := range specs.BreakingChanges[i].Columns {
544+
columnT[t] = specs.BreakingChanges[i].Columns[t]
545+
}
546+
}
547+
}
548+
549+
// nolint: golint
550+
// 2 because old - new
551+
oldnew := make([]string, 0, 2*len(columnT))
552+
for t := range columnT {
553+
oldnew = append(oldnew, t, columnT[t])
554+
}
555+
556+
r := strings.NewReplacer(oldnew...)
557+
558+
newQueryOverrides[metric] = r.Replace(newQueryOverrides[metric])
559+
535560
metricMap, ok := metricMaps[metric]
536561
if !ok {
537562
// Namespace for metric not found - add it.
@@ -571,7 +596,7 @@ func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[str
571596
// TODO: test code for all cu.
572597
// TODO: the YAML this supports is "non-standard" - we should move away from it.
573598
func addQueries(content []byte, pgVersion semver.Version, server *Server) error {
574-
metricMaps, newQueryOverrides, err := parseUserQueries(content)
599+
metricMaps, newQueryOverrides, err := parseUserQueries(content, pgVersion)
575600
if err != nil {
576601
return err
577602
}

cmd/postgres_exporter/postgres_exporter_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ func (s *FunctionalSuite) TestBooleanConversionToValueAndString(c *C) {
410410
func (s *FunctionalSuite) TestParseUserQueries(c *C) {
411411
userQueriesData, err := ioutil.ReadFile("./tests/user_queries_ok.yaml")
412412
if err == nil {
413-
metricMaps, newQueryOverrides, err := parseUserQueries(userQueriesData)
413+
metricMaps, newQueryOverrides, err := parseUserQueries(userQueriesData, semver.Version{Major: 13})
414414
c.Assert(err, Equals, nil)
415415
c.Assert(metricMaps, NotNil)
416416
c.Assert(newQueryOverrides, NotNil)

queries.yaml

+17-1
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,24 @@ pg_database:
159159
description: "Disk space used by the database"
160160

161161
pg_stat_statements:
162-
query: "SELECT t2.rolname, t3.datname, queryid, calls, total_time / 1000 as total_time_seconds, min_time / 1000 as min_time_seconds, max_time / 1000 as max_time_seconds, mean_time / 1000 as mean_time_seconds, stddev_time / 1000 as stddev_time_seconds, rows, shared_blks_hit, shared_blks_read, shared_blks_dirtied, shared_blks_written, local_blks_hit, local_blks_read, local_blks_dirtied, local_blks_written, temp_blks_read, temp_blks_written, blk_read_time / 1000 as blk_read_time_seconds, blk_write_time / 1000 as blk_write_time_seconds FROM pg_stat_statements t1 JOIN pg_roles t2 ON (t1.userid=t2.oid) JOIN pg_database t3 ON (t1.dbid=t3.oid) WHERE t2.rolname != 'rdsadmin'"
162+
query: "SELECT t2.rolname, t3.datname, queryid, calls, total_time_T / 1000 as total_time_seconds, min_time_T / 1000 as min_time_seconds, max_time_T / 1000 as max_time_seconds, mean_time_T / 1000 as mean_time_seconds, stddev_time_T / 1000 as stddev_time_seconds, rows, shared_blks_hit, shared_blks_read, shared_blks_dirtied, shared_blks_written, local_blks_hit, local_blks_read, local_blks_dirtied, local_blks_written, temp_blks_read, temp_blks_written, blk_read_time / 1000 as blk_read_time_seconds, blk_write_time / 1000 as blk_write_time_seconds FROM pg_stat_statements t1 JOIN pg_roles t2 ON (t1.userid=t2.oid) JOIN pg_database t3 ON (t1.dbid=t3.oid) WHERE t2.rolname != 'rdsadmin'"
163163
master: true
164+
breakingChanges:
165+
# should be in asc order by version
166+
- version: '9.4.0'
167+
columns:
168+
total_time_T: total_time
169+
min_time_T: min_time
170+
max_time_T: max_time
171+
mean_time_T: mean_time
172+
stddev_time_T: stddev_time
173+
- version: '13.0.0'
174+
columns:
175+
total_time_T: total_exec_time
176+
min_time_T: min_exec_time
177+
max_time_T: max_exec_time
178+
mean_time_T: mean_exec_time
179+
stddev_time_T: stddev_exec_time
164180
metrics:
165181
- rolname:
166182
usage: "LABEL"

0 commit comments

Comments
 (0)