Skip to content

server labels are defined as const labels #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ For running it locally on a default Debian/Ubuntu install, this will work (trans

sudo -u postgres DATA_SOURCE_NAME="user=postgres host=/var/run/postgresql/ sslmode=disable" postgres_exporter

Also, you can set a list of sources to scrape different instances from the one exporter setup. Just define a string separated by comma.
Also, you can set a list of sources to scrape different instances from the one exporter setup. Just define a comma separated string.

sudo -u postgres DATA_SOURCE_NAME="port=5432, port=6432" postgres_exporter
sudo -u postgres DATA_SOURCE_NAME="port=5432,port=6432" postgres_exporter

See the [github.com/lib/pq](http://github.com/lib/pq) module for other ways to format the connection string.

Expand Down Expand Up @@ -155,7 +155,8 @@ flag. This removes all built-in metrics, and uses only metrics defined by querie

### Running as non-superuser

To be able to collect metrics from pg_stat_activity and pg_stat_replication as non-superuser you have to create views as a superuser, and assign permissions separately to those. In PostgreSQL, views run with the permissions of the user that created them so they can act as security barriers.
To be able to collect metrics from `pg_stat_activity` and `pg_stat_replication` as non-superuser you have to create views as a superuser, and assign permissions separately to those.
In PostgreSQL, views run with the permissions of the user that created them so they can act as security barriers.

```sql
CREATE USER postgres_exporter PASSWORD 'password';
Expand Down
8 changes: 4 additions & 4 deletions cmd/postgres_exporter/pg_setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func querySettings(ch chan<- prometheus.Metric, server *Server) error {
return fmt.Errorf("Error retrieving rows on %q: %s %v", server, namespace, err)
}

ch <- s.metric(server.String())
ch <- s.metric(server.labels)
}

return nil
Expand All @@ -45,7 +45,7 @@ type pgSetting struct {
name, setting, unit, shortDesc, vartype string
}

func (s *pgSetting) metric(server string) prometheus.Metric {
func (s *pgSetting) metric(labels prometheus.Labels) prometheus.Metric {
var (
err error
name = strings.Replace(s.name, ".", "_", -1)
Expand Down Expand Up @@ -76,8 +76,8 @@ func (s *pgSetting) metric(server string) prometheus.Metric {
panic(fmt.Sprintf("Unsupported vartype %q", s.vartype))
}

desc := newDesc(subsystem, name, shortDesc)
return prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, val, server)
desc := newDesc(subsystem, name, shortDesc, labels)
return prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, val)
}

// TODO: fix linter override
Expand Down
25 changes: 13 additions & 12 deletions cmd/postgres_exporter/pg_setting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package main

import (
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
. "gopkg.in/check.v1"
)
Expand All @@ -25,7 +26,7 @@ var fixtures = []fixture{
unit: "seconds",
err: "",
},
d: `Desc{fqName: "pg_settings_seconds_fixture_metric_seconds", help: "Foo foo foo [Units converted to seconds.]", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_seconds_fixture_metric_seconds", help: "Foo foo foo [Units converted to seconds.]", constLabels: {}, variableLabels: []}`,
v: 5,
},
{
Expand All @@ -41,7 +42,7 @@ var fixtures = []fixture{
unit: "seconds",
err: "",
},
d: `Desc{fqName: "pg_settings_milliseconds_fixture_metric_seconds", help: "Foo foo foo [Units converted to seconds.]", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_milliseconds_fixture_metric_seconds", help: "Foo foo foo [Units converted to seconds.]", constLabels: {}, variableLabels: []}`,
v: 5,
},
{
Expand All @@ -57,7 +58,7 @@ var fixtures = []fixture{
unit: "bytes",
err: "",
},
d: `Desc{fqName: "pg_settings_eight_kb_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_eight_kb_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: []}`,
v: 139264,
},
{
Expand All @@ -73,7 +74,7 @@ var fixtures = []fixture{
unit: "bytes",
err: "",
},
d: `Desc{fqName: "pg_settings_16_kb_real_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_16_kb_real_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: []}`,
v: 49152,
},
{
Expand All @@ -89,7 +90,7 @@ var fixtures = []fixture{
unit: "bytes",
err: "",
},
d: `Desc{fqName: "pg_settings_16_mb_real_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_16_mb_real_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: []}`,
v: 5.0331648e+07,
},
{
Expand All @@ -105,7 +106,7 @@ var fixtures = []fixture{
unit: "bytes",
err: "",
},
d: `Desc{fqName: "pg_settings_32_mb_real_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_32_mb_real_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: []}`,
v: 1.00663296e+08,
},
{
Expand All @@ -121,7 +122,7 @@ var fixtures = []fixture{
unit: "bytes",
err: "",
},
d: `Desc{fqName: "pg_settings_64_mb_real_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_64_mb_real_fixture_metric_bytes", help: "Foo foo foo [Units converted to bytes.]", constLabels: {}, variableLabels: []}`,
v: 2.01326592e+08,
},
{
Expand All @@ -137,7 +138,7 @@ var fixtures = []fixture{
unit: "",
err: "",
},
d: `Desc{fqName: "pg_settings_bool_on_fixture_metric", help: "Foo foo foo", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_bool_on_fixture_metric", help: "Foo foo foo", constLabels: {}, variableLabels: []}`,
v: 1,
},
{
Expand All @@ -153,7 +154,7 @@ var fixtures = []fixture{
unit: "",
err: "",
},
d: `Desc{fqName: "pg_settings_bool_off_fixture_metric", help: "Foo foo foo", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_bool_off_fixture_metric", help: "Foo foo foo", constLabels: {}, variableLabels: []}`,
v: 0,
},
{
Expand All @@ -169,7 +170,7 @@ var fixtures = []fixture{
unit: "seconds",
err: "",
},
d: `Desc{fqName: "pg_settings_special_minus_one_value_seconds", help: "foo foo foo [Units converted to seconds.]", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_special_minus_one_value_seconds", help: "foo foo foo [Units converted to seconds.]", constLabels: {}, variableLabels: []}`,
v: -1,
},
{
Expand All @@ -185,7 +186,7 @@ var fixtures = []fixture{
unit: "",
err: "",
},
d: `Desc{fqName: "pg_settings_rds_rds_superuser_reserved_connections", help: "Sets the number of connection slots reserved for rds_superusers.", constLabels: {}, variableLabels: [` + serverLabelName + `]}`,
d: `Desc{fqName: "pg_settings_rds_rds_superuser_reserved_connections", help: "Sets the number of connection slots reserved for rds_superusers.", constLabels: {}, variableLabels: []}`,
v: 2,
},
{
Expand Down Expand Up @@ -233,7 +234,7 @@ func (s *PgSettingSuite) TestMetric(c *C) {

for _, f := range fixtures {
d := &dto.Metric{}
m := f.p.metric("")
m := f.p.metric(prometheus.Labels{})
m.Write(d) // nolint: errcheck

c.Check(m.Desc().String(), Equals, f.d)
Expand Down
41 changes: 21 additions & 20 deletions cmd/postgres_exporter/postgres_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ func addQueries(content []byte, pgVersion semver.Version, server *Server) error
}

// Convert the loaded metric map into exporter representation
partialExporterMap := makeDescMap(pgVersion, metricMaps)
partialExporterMap := makeDescMap(pgVersion, server.labels, metricMaps)

// Merge the two maps (which are now quite flatteend)
for k, v := range partialExporterMap {
Expand Down Expand Up @@ -480,15 +480,15 @@ func addQueries(content []byte, pgVersion semver.Version, server *Server) error
}

// Turn the MetricMap column mapping into a prometheus descriptor mapping.
func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]ColumnMapping) map[string]MetricMapNamespace {
func makeDescMap(pgVersion semver.Version, serverLabels prometheus.Labels, metricMaps map[string]map[string]ColumnMapping) map[string]MetricMapNamespace {
var metricMap = make(map[string]MetricMapNamespace)

for namespace, mappings := range metricMaps {
thisMap := make(map[string]MetricMap)

// Get the constant labels.
// Server label must be added to each metric.
constLabels := []string{serverLabelName}
var constLabels []string
for columnName, columnMapping := range mappings {
if columnMapping.usage == LABEL {
constLabels = append(constLabels, columnName)
Expand Down Expand Up @@ -526,23 +526,23 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
case COUNTER:
thisMap[columnName] = MetricMap{
vtype: prometheus.CounterValue,
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, constLabels, nil),
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, constLabels, serverLabels),
conversion: func(in interface{}) (float64, bool) {
return dbToFloat64(in)
},
}
case GAUGE:
thisMap[columnName] = MetricMap{
vtype: prometheus.GaugeValue,
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, constLabels, nil),
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, constLabels, serverLabels),
conversion: func(in interface{}) (float64, bool) {
return dbToFloat64(in)
},
}
case MAPPEDMETRIC:
thisMap[columnName] = MetricMap{
vtype: prometheus.GaugeValue,
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, constLabels, nil),
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, constLabels, serverLabels),
conversion: func(in interface{}) (float64, bool) {
text, ok := in.(string)
if !ok {
Expand All @@ -559,7 +559,7 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
case DURATION:
thisMap[columnName] = MetricMap{
vtype: prometheus.GaugeValue,
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s_milliseconds", namespace, columnName), columnMapping.description, constLabels, nil),
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s_milliseconds", namespace, columnName), columnMapping.description, constLabels, serverLabels),
conversion: func(in interface{}) (float64, bool) {
var durationString string
switch t := in.(type) {
Expand Down Expand Up @@ -725,8 +725,8 @@ func parseDSN(dsn string) (*url.URL, error) {
// Server describes a connection to Postgres.
// Also it contains metrics map and query overrides.
type Server struct {
db *sql.DB
fingerprint string
db *sql.DB
labels prometheus.Labels

// Last version used to calculate metric map. If mismatch on scrape,
// then maps are recalculated.
Expand Down Expand Up @@ -755,8 +755,10 @@ func NewServer(dsn string) (*Server, error) {
log.Infof("Established new database connection to %q.", fingerprint)

return &Server{
db: db,
fingerprint: fingerprint,
db: db,
labels: prometheus.Labels{
serverLabelName: fingerprint,
},
}, nil
}

Expand Down Expand Up @@ -784,7 +786,7 @@ func (s *Server) Ping() error {

// String returns server's fingerprint.
func (s *Server) String() string {
return s.fingerprint
return s.labels[serverLabelName]
}

// Scrape loads metrics.
Expand Down Expand Up @@ -976,10 +978,10 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
e.userQueriesError.Collect(ch)
}

func newDesc(subsystem, name, help string) *prometheus.Desc {
func newDesc(subsystem, name, help string, labels prometheus.Labels) *prometheus.Desc {
return prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, name),
help, []string{serverLabelName}, nil,
help, nil, labels,
)
}

Expand Down Expand Up @@ -1040,9 +1042,8 @@ func queryNamespaceMapping(ch chan<- prometheus.Metric, server *Server, namespac

// Get the label values for this row.
labels := make([]string, len(mapping.labels))
labels[0] = server.String() // Server label must be added to each metric.
for idx := 1; idx < len(mapping.labels); idx++ {
labels[idx], _ = dbToString(columnData[columnIdx[mapping.labels[idx]]])
for idx, label := range mapping.labels {
labels[idx], _ = dbToString(columnData[columnIdx[label]])
}

// Loop over column names, and match to scan data. Unknown columns
Expand Down Expand Up @@ -1133,7 +1134,7 @@ func (e *Exporter) checkMapVersions(ch chan<- prometheus.Metric, server *Server)
server.metricMap = make(map[string]MetricMapNamespace)
server.queryOverrides = make(map[string]string)
} else {
server.metricMap = makeDescMap(semanticVersion, e.builtinMetricMaps)
server.metricMap = makeDescMap(semanticVersion, server.labels, e.builtinMetricMaps)
server.queryOverrides = makeQueryOverrideMap(semanticVersion, queryOverrides)
}

Expand Down Expand Up @@ -1166,10 +1167,10 @@ func (e *Exporter) checkMapVersions(ch chan<- prometheus.Metric, server *Server)

// Output the version as a special metric
versionDesc := prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, staticLabelName),
"Version string as reported by postgres", []string{serverLabelName, "version", "short_version"}, nil)
"Version string as reported by postgres", []string{"version", "short_version"}, server.labels)

ch <- prometheus.MustNewConstMetric(versionDesc,
prometheus.UntypedValue, 1, server.String(), versionString, semanticVersion.String())
prometheus.UntypedValue, 1, versionString, semanticVersion.String())
return nil
}

Expand Down
7 changes: 4 additions & 3 deletions cmd/postgres_exporter/postgres_exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"os"

"github.com/blang/semver"
"github.com/prometheus/client_golang/prometheus"
)

// Hook up gocheck into the "go test" runner.
Expand All @@ -34,7 +35,7 @@ func (s *FunctionalSuite) TestSemanticVersionColumnDiscard(c *C) {

{
// No metrics should be eliminated
resultMap := makeDescMap(semver.MustParse("0.0.1"), testMetricMap)
resultMap := makeDescMap(semver.MustParse("0.0.1"), prometheus.Labels{}, testMetricMap)
c.Check(
resultMap["test_namespace"].columnMappings["metric_which_stays"].discard,
Equals,
Expand All @@ -55,7 +56,7 @@ func (s *FunctionalSuite) TestSemanticVersionColumnDiscard(c *C) {
testMetricMap["test_namespace"]["metric_which_discards"] = discardableMetric

// Discard metric should be discarded
resultMap := makeDescMap(semver.MustParse("0.0.1"), testMetricMap)
resultMap := makeDescMap(semver.MustParse("0.0.1"), prometheus.Labels{}, testMetricMap)
c.Check(
resultMap["test_namespace"].columnMappings["metric_which_stays"].discard,
Equals,
Expand All @@ -76,7 +77,7 @@ func (s *FunctionalSuite) TestSemanticVersionColumnDiscard(c *C) {
testMetricMap["test_namespace"]["metric_which_discards"] = discardableMetric

// Discard metric should be discarded
resultMap := makeDescMap(semver.MustParse("0.0.2"), testMetricMap)
resultMap := makeDescMap(semver.MustParse("0.0.2"), prometheus.Labels{}, testMetricMap)
c.Check(
resultMap["test_namespace"].columnMappings["metric_which_stays"].discard,
Equals,
Expand Down