Skip to content

Commit c00d93c

Browse files
authored
PMM-14527 Ability to have aurora specific queries. (#373)
* PMM-14527 Ability to have aurora queries. * PMM-14527 Functionality to skip query for Aurora completely. * PMM-14527 Add test case for Aurora skip. * PMM-14527 Better check if Aurora. * PMM-14527 Check for func of Aurora. * PMM-14527 Different check for func exists. * PMM-14527 Bump minimum PG to 10. * PMM-14527 Improvements. * PMM-14527 Fix. * PMM-14527 Fix. * PMM-14527 Fix. * PMM-14527 Fix.
1 parent d9db239 commit c00d93c

20 files changed

Lines changed: 230 additions & 174 deletions

.promu.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ go:
22
# This must match .circle/config.yml.
33
version: 1.21
44
repository:
5-
path: github.com/prometheus-community/postgres_exporter
5+
path: github.com/percona/postgres_exporter
66
build:
77
binaries:
88
- name: postgres_exporter

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![Build Status](https://circleci.com/gh/prometheus-community/postgres_exporter.svg?style=svg)](https://circleci.com/gh/prometheus-community/postgres_exporter)
22
[![Coverage Status](https://coveralls.io/repos/github/prometheus-community/postgres_exporter/badge.svg?branch=master)](https://coveralls.io/github/prometheus-community/postgres_exporter?branch=master)
3-
[![Go Report Card](https://goreportcard.com/badge/github.com/prometheus-community/postgres_exporter)](https://goreportcard.com/report/github.com/prometheus-community/postgres_exporter)
3+
[![Go Report Card](https://goreportcard.com/badge/github.com/percona/postgres_exporter)](https://goreportcard.com/report/github.com/percona/postgres_exporter)
44
[![Docker Pulls](https://img.shields.io/docker/pulls/prometheuscommunity/postgres-exporter.svg)](https://hub.docker.com/r/prometheuscommunity/postgres-exporter/tags)
55

66
# PostgreSQL Server Exporter
@@ -73,7 +73,7 @@ auth_modules:
7373

7474
## Building and running
7575

76-
git clone https://github.com/prometheus-community/postgres_exporter.git
76+
git clone https://github.com/percona/postgres_exporter.git
7777
cd postgres_exporter
7878
make build
7979
./postgres_exporter <flags>

cmd/postgres_exporter/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
"github.com/alecthomas/kingpin/v2"
2424
"github.com/go-kit/log"
2525
"github.com/go-kit/log/level"
26-
"github.com/prometheus-community/postgres_exporter/config"
26+
"github.com/percona/postgres_exporter/config"
2727
"github.com/prometheus/client_golang/prometheus"
2828
"github.com/prometheus/client_golang/prometheus/collectors"
2929
vc "github.com/prometheus/client_golang/prometheus/collectors/version"

cmd/postgres_exporter/percona_exporter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
"github.com/blang/semver/v4"
1717
"github.com/go-kit/log"
1818
"github.com/go-kit/log/level"
19-
"github.com/prometheus-community/postgres_exporter/collector"
19+
"github.com/percona/postgres_exporter/collector"
2020
"github.com/prometheus/client_golang/prometheus"
2121
"github.com/prometheus/client_golang/prometheus/promhttp"
2222
"golang.org/x/sync/semaphore"

cmd/postgres_exporter/postgres_exporter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ type Mapping map[string]MappingOptions
8181

8282
// Regex used to get the "short-version" from the postgres version field.
8383
var versionRegex = regexp.MustCompile(`^\w+ ((\d+)(\.\d+)?(\.\d+)?)`)
84-
var lowestSupportedVersion = semver.MustParse("9.1.0")
84+
var lowestSupportedVersion = semver.MustParse("10.0.0")
8585

8686
// Parses the version of postgres into the short version string we can use to
8787
// match behaviors.

cmd/postgres_exporter/postgres_exporter_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"time"
2424

2525
"github.com/blang/semver/v4"
26+
"github.com/percona/postgres_exporter/distribution"
2627
"github.com/prometheus/client_golang/prometheus"
2728
. "gopkg.in/check.v1"
2829
)
@@ -409,7 +410,7 @@ func (s *FunctionalSuite) TestBooleanConversionToValueAndString(c *C) {
409410
func (s *FunctionalSuite) TestParseUserQueries(c *C) {
410411
userQueriesData, err := os.ReadFile("./tests/user_queries_ok.yaml")
411412
if err == nil {
412-
metricMaps, newQueryOverrides, err := parseUserQueries(userQueriesData)
413+
metricMaps, newQueryOverrides, err := parseUserQueries(userQueriesData, distribution.Standard)
413414
c.Assert(err, Equals, nil)
414415
c.Assert(metricMaps, NotNil)
415416
c.Assert(newQueryOverrides, NotNil)

cmd/postgres_exporter/probe.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import (
1919

2020
"github.com/go-kit/log"
2121
"github.com/go-kit/log/level"
22-
"github.com/prometheus-community/postgres_exporter/collector"
23-
"github.com/prometheus-community/postgres_exporter/config"
22+
"github.com/percona/postgres_exporter/collector"
23+
"github.com/percona/postgres_exporter/config"
2424
"github.com/prometheus/client_golang/prometheus"
2525
"github.com/prometheus/client_golang/prometheus/promhttp"
2626
"golang.org/x/sync/semaphore"

cmd/postgres_exporter/queries.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,20 @@ import (
2121
"github.com/blang/semver/v4"
2222
"github.com/go-kit/log/level"
2323
"gopkg.in/yaml.v2"
24+
25+
"github.com/percona/postgres_exporter/distribution"
26+
)
27+
28+
const (
29+
// '!' is a reserved character indicating that the query is not supported on Aurora and should be skipped for Aurora instances.
30+
notSupportedByAurora = "!"
2431
)
2532

26-
// UserQuery represents a user defined query
33+
// UserQuery represents a user defined query, including support for Aurora, if needed
2734
type UserQuery struct {
28-
Query string `yaml:"query"`
29-
Metrics []Mapping `yaml:"metrics"`
35+
Query string `yaml:"query"` // Standard query
36+
QueryAurora string `yaml:"query_aurora"` // Aurora specific query
37+
Metrics []Mapping `yaml:"metrics"` // Metrics to be collected
3038
Master bool `yaml:"master"` // Querying only for master database
3139
CacheSeconds uint64 `yaml:"cache_seconds"` // Number of seconds to cache the namespace result metrics for.
3240
RunOnServer string `yaml:"runonserver"` // Querying to run on which server version
@@ -197,7 +205,7 @@ func makeQueryOverrideMap(pgVersion semver.Version, queryOverrides map[string][]
197205
return resultMap
198206
}
199207

200-
func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[string]string, error) {
208+
func parseUserQueries(content []byte, dist string) (map[string]intermediateMetricMap, map[string]string, error) {
201209
var userQueries UserQueries
202210

203211
err := yaml.Unmarshal(content, &userQueries)
@@ -211,7 +219,25 @@ func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[str
211219

212220
for metric, specs := range userQueries {
213221
level.Debug(logger).Log("msg", "New user metric namespace from YAML metric", "metric", metric, "cache_seconds", specs.CacheSeconds)
214-
newQueryOverrides[metric] = specs.Query
222+
223+
// Query selection logic:
224+
// For Aurora: use query_aurora if defined and not empty, otherwise use query if defined and not empty.
225+
// If query_aurora is set to '!', skip this query for Aurora (not supported).
226+
// For standard (non-Aurora): always use query.
227+
switch dist {
228+
case distribution.Aurora:
229+
if specs.QueryAurora != "" {
230+
if specs.QueryAurora == notSupportedByAurora {
231+
continue
232+
}
233+
newQueryOverrides[metric] = specs.QueryAurora
234+
} else {
235+
newQueryOverrides[metric] = specs.Query
236+
}
237+
default:
238+
newQueryOverrides[metric] = specs.Query
239+
}
240+
215241
metricMap, ok := metricMaps[metric]
216242
if !ok {
217243
// Namespace for metric not found - add it.
@@ -251,7 +277,7 @@ func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[str
251277
// TODO: test code for all cu.
252278
// TODO: the YAML this supports is "non-standard" - we should move away from it.
253279
func addQueries(content []byte, pgVersion semver.Version, server *Server) error {
254-
metricMaps, newQueryOverrides, err := parseUserQueries(content)
280+
metricMaps, newQueryOverrides, err := parseUserQueries(content, server.distribution)
255281
if err != nil {
256282
return err
257283
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (C) 2023 Percona LLC
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU Affero General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// This program is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU Affero General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Affero General Public License
14+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
15+
16+
package main
17+
18+
import (
19+
"testing"
20+
21+
"github.com/stretchr/testify/require"
22+
)
23+
24+
func TestParseUserQueries_DistributionSelection(t *testing.T) {
25+
cases := []struct {
26+
name string
27+
yamlInput string
28+
distribution string
29+
wantQuery string
30+
}{
31+
{
32+
name: "Standard uses query",
33+
yamlInput: `
34+
pg_replication:
35+
query: "standard"
36+
query_aurora: "aurora"
37+
`,
38+
distribution: "standard",
39+
wantQuery: "standard",
40+
},
41+
{
42+
name: "Aurora uses query_aurora",
43+
yamlInput: `
44+
pg_replication:
45+
query: "standard"
46+
query_aurora: "aurora"
47+
`,
48+
distribution: "aurora",
49+
wantQuery: "aurora",
50+
},
51+
{
52+
name: "Aurora falls back to query",
53+
yamlInput: `
54+
pg_replication:
55+
query: "standard"
56+
`,
57+
distribution: "aurora",
58+
wantQuery: "standard",
59+
},
60+
{
61+
name: "Aurora skips if neither",
62+
yamlInput: `
63+
pg_replication:
64+
`,
65+
distribution: "aurora",
66+
wantQuery: "",
67+
},
68+
{
69+
name: "Standard query only",
70+
yamlInput: `
71+
pg_replication:
72+
query: "standard"
73+
`,
74+
distribution: "standard",
75+
wantQuery: "standard",
76+
},
77+
{
78+
name: "Aurora query only",
79+
yamlInput: `
80+
pg_replication:
81+
query_aurora: "aurora"
82+
`,
83+
distribution: "aurora",
84+
wantQuery: "aurora",
85+
},
86+
{
87+
name: "Not supported by Aurora",
88+
yamlInput: `
89+
pg_replication:
90+
query: "standard"
91+
query_aurora: "!"
92+
`,
93+
distribution: "aurora",
94+
wantQuery: "",
95+
},
96+
}
97+
for _, tc := range cases {
98+
t.Run(tc.name, func(t *testing.T) {
99+
_, metricsQueries, err := parseUserQueries([]byte(tc.yamlInput), tc.distribution)
100+
require.NoError(t, err)
101+
require.Equal(t, tc.wantQuery, metricsQueries["pg_replication"])
102+
})
103+
}
104+
}

cmd/postgres_exporter/server.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@ import (
2121

2222
"github.com/blang/semver/v4"
2323
"github.com/go-kit/log/level"
24+
"github.com/percona/postgres_exporter/distribution"
2425
"github.com/prometheus/client_golang/prometheus"
2526
)
2627

2728
// Server describes a connection to Postgres.
2829
// Also it contains metrics map and query overrides.
2930
type Server struct {
30-
db *sql.DB
31-
labels prometheus.Labels
32-
master bool
33-
runonserver string
31+
db *sql.DB
32+
distribution string
33+
labels prometheus.Labels
34+
master bool
35+
runonserver string
3436

3537
// Last version used to calculate metric map. If mismatch on scrape,
3638
// then maps are recalculated.
@@ -82,6 +84,7 @@ func NewServer(dsn string, opts ...ServerOpt) (*Server, error) {
8284
},
8385
metricCache: make(map[string]cachedMetrics),
8486
}
87+
s.distribution = distribution.Get(dsn, db)
8588

8689
for _, opt := range opts {
8790
opt(s)

0 commit comments

Comments
 (0)