@@ -24,16 +24,32 @@ import (
2424
2525// UserQuery represents a user defined query
2626type 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
3233}
3334
3435// UserQueries represents a set of UserQuery objects
3536type UserQueries map [string ]UserQuery
3637
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+
3753// OverrideQuery 's are run in-place of simple namespace look ups, and provide
3854// advanced functionality. But they have a tendency to postgres version specific.
3955// 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][]
197213 return resultMap
198214}
199215
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 ) {
201217 var userQueries UserQueries
202218
203219 err := yaml .Unmarshal (content , & userQueries )
@@ -211,7 +227,12 @@ func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[str
211227
212228 for metric , specs := range userQueries {
213229 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+
215236 metricMap , ok := metricMaps [metric ]
216237 if ! ok {
217238 // Namespace for metric not found - add it.
@@ -251,7 +272,7 @@ func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[str
251272// TODO: test code for all cu.
252273// TODO: the YAML this supports is "non-standard" - we should move away from it.
253274func addQueries (content []byte , pgVersion semver.Version , server * Server ) error {
254- metricMaps , newQueryOverrides , err := parseUserQueries (content )
275+ metricMaps , newQueryOverrides , err := parseUserQueries (content , pgVersion )
255276 if err != nil {
256277 return err
257278 }
0 commit comments