@@ -24,16 +24,32 @@ import (
24
24
25
25
// UserQuery represents a user defined query
26
26
type UserQuery struct {
27
- Query string `yaml:"query"`
28
- Metrics []Mapping `yaml:"metrics"`
29
- Master bool `yaml:"master"` // Querying only for master database
30
- CacheSeconds uint64 `yaml:"cache_seconds"` // Number of seconds to cache the namespace result metrics for.
31
- RunOnServer string `yaml:"runonserver"` // Querying to run on which server version
27
+ Query string `yaml:"query"`
28
+ Metrics []Mapping `yaml:"metrics"`
29
+ VersionQueries []VersionQ `yaml:"versionQueries"`
30
+ Master bool `yaml:"master"` // Querying only for master database
31
+ CacheSeconds uint64 `yaml:"cache_seconds"` // Number of seconds to cache the namespace result metrics for.
32
+ RunOnServer string `yaml:"runonserver"` // Querying to run on which server version
32
33
}
33
34
34
35
// UserQueries represents a set of UserQuery objects
35
36
type UserQueries map [string ]UserQuery
36
37
38
+ func (uq * UserQuery ) getVersionedQuery (pgVersion semver.Version ) (string , error ) {
39
+ r := uq .Query
40
+ if len (uq .VersionQueries ) != 0 {
41
+ for i := range uq .VersionQueries {
42
+ if err := uq .VersionQueries [i ].parseVerTolerant (); err != nil {
43
+ return "" , err
44
+ }
45
+ if pgVersion .GE (uq .VersionQueries [i ].ver ) {
46
+ r = uq .VersionQueries [i ].Query
47
+ }
48
+ }
49
+ }
50
+ return r , nil
51
+ }
52
+
37
53
// OverrideQuery 's are run in-place of simple namespace look ups, and provide
38
54
// advanced functionality. But they have a tendency to postgres version specific.
39
55
// There aren't too many versions, so we simply store customized versions using
@@ -197,7 +213,7 @@ func makeQueryOverrideMap(pgVersion semver.Version, queryOverrides map[string][]
197
213
return resultMap
198
214
}
199
215
200
- func parseUserQueries (content []byte ) (map [string ]intermediateMetricMap , map [string ]string , error ) {
216
+ func parseUserQueries (content []byte , pgVersion semver. Version ) (map [string ]intermediateMetricMap , map [string ]string , error ) {
201
217
var userQueries UserQueries
202
218
203
219
err := yaml .Unmarshal (content , & userQueries )
@@ -211,7 +227,12 @@ func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[str
211
227
212
228
for metric , specs := range userQueries {
213
229
level .Debug (logger ).Log ("msg" , "New user metric namespace from YAML metric" , "metric" , metric , "cache_seconds" , specs .CacheSeconds )
214
- newQueryOverrides [metric ] = specs .Query
230
+ versionQuery , err := specs .getVersionedQuery (pgVersion )
231
+ if err != nil {
232
+ return nil , nil , err
233
+ }
234
+ newQueryOverrides [metric ] = versionQuery
235
+
215
236
metricMap , ok := metricMaps [metric ]
216
237
if ! ok {
217
238
// Namespace for metric not found - add it.
@@ -251,7 +272,7 @@ func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[str
251
272
// TODO: test code for all cu.
252
273
// TODO: the YAML this supports is "non-standard" - we should move away from it.
253
274
func addQueries (content []byte , pgVersion semver.Version , server * Server ) error {
254
- metricMaps , newQueryOverrides , err := parseUserQueries (content )
275
+ metricMaps , newQueryOverrides , err := parseUserQueries (content , pgVersion )
255
276
if err != nil {
256
277
return err
257
278
}
0 commit comments