Skip to content

Commit c225a1e

Browse files
robsonpeixotowrouesnel
authored andcommitted
Accept constantLabels as parameters
When you area monitoring server from cloud providers the exporter IP/hostname is not the server IP, so add some constant labels is useful on dashboards and alerts. And is very important to use with `--disable-default-metrics` to add info like `datname` and figure out the database name that you are monitoring
1 parent 265a2ea commit c225a1e

File tree

1 file changed

+59
-29
lines changed

1 file changed

+59
-29
lines changed

cmd/postgres_exporter/postgres_exporter.go

+59-29
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var (
3838
disableDefaultMetrics = kingpin.Flag("disable-default-metrics", "Do not include default metrics.").Default("false").OverrideDefaultFromEnvar("PG_EXPORTER_DISABLE_DEFAULT_METRICS").Bool()
3939
queriesPath = kingpin.Flag("extend.query-path", "Path to custom queries to run.").Default("").OverrideDefaultFromEnvar("PG_EXPORTER_EXTEND_QUERY_PATH").String()
4040
onlyDumpMaps = kingpin.Flag("dumpmaps", "Do not run, simply dump the maps.").Bool()
41+
constantLabelsList = kingpin.Flag("constantLabels", "A list of label=value separated by comma(,).").Default("").OverrideDefaultFromEnvar("PG_EXPORTER_CONTANT_LABELS").String()
4142
)
4243

4344
// Metric name parts.
@@ -484,13 +485,15 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
484485
thisMap := make(map[string]MetricMap)
485486

486487
// Get the constant labels
487-
var constLabels []string
488+
var variableLabels []string
488489
for columnName, columnMapping := range mappings {
489490
if columnMapping.usage == LABEL {
490-
constLabels = append(constLabels, columnName)
491+
variableLabels = append(variableLabels, columnName)
491492
}
492493
}
493494

495+
constLabels := newConstLabels()
496+
494497
for columnName, columnMapping := range mappings {
495498
// Check column version compatibility for the current map
496499
// Force to discard if not compatible.
@@ -522,23 +525,23 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
522525
case COUNTER:
523526
thisMap[columnName] = MetricMap{
524527
vtype: prometheus.CounterValue,
525-
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, constLabels, nil),
528+
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, variableLabels, constLabels),
526529
conversion: func(in interface{}) (float64, bool) {
527530
return dbToFloat64(in)
528531
},
529532
}
530533
case GAUGE:
531534
thisMap[columnName] = MetricMap{
532535
vtype: prometheus.GaugeValue,
533-
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, constLabels, nil),
536+
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, variableLabels, constLabels),
534537
conversion: func(in interface{}) (float64, bool) {
535538
return dbToFloat64(in)
536539
},
537540
}
538541
case MAPPEDMETRIC:
539542
thisMap[columnName] = MetricMap{
540543
vtype: prometheus.GaugeValue,
541-
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, constLabels, nil),
544+
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, columnName), columnMapping.description, variableLabels, constLabels),
542545
conversion: func(in interface{}) (float64, bool) {
543546
text, ok := in.(string)
544547
if !ok {
@@ -555,7 +558,7 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
555558
case DURATION:
556559
thisMap[columnName] = MetricMap{
557560
vtype: prometheus.GaugeValue,
558-
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s_milliseconds", namespace, columnName), columnMapping.description, constLabels, nil),
561+
desc: prometheus.NewDesc(fmt.Sprintf("%s_%s_milliseconds", namespace, columnName), columnMapping.description, variableLabels, constLabels),
559562
conversion: func(in interface{}) (float64, bool) {
560563
var durationString string
561564
switch t := in.(type) {
@@ -583,7 +586,7 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
583586
}
584587
}
585588

586-
metricMap[namespace] = MetricMapNamespace{constLabels, thisMap}
589+
metricMap[namespace] = MetricMapNamespace{variableLabels, thisMap}
587590
}
588591

589592
return metricMap
@@ -711,33 +714,38 @@ func NewExporter(dsn string, disableDefaultMetrics bool, userQueriesPath string)
711714
disableDefaultMetrics: disableDefaultMetrics,
712715
userQueriesPath: userQueriesPath,
713716
duration: prometheus.NewGauge(prometheus.GaugeOpts{
714-
Namespace: namespace,
715-
Subsystem: exporter,
716-
Name: "last_scrape_duration_seconds",
717-
Help: "Duration of the last scrape of metrics from PostgresSQL.",
717+
Namespace: namespace,
718+
Subsystem: exporter,
719+
Name: "last_scrape_duration_seconds",
720+
Help: "Duration of the last scrape of metrics from PostgresSQL.",
721+
ConstLabels: newConstLabels(),
718722
}),
719723
totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{
720-
Namespace: namespace,
721-
Subsystem: exporter,
722-
Name: "scrapes_total",
723-
Help: "Total number of times PostgresSQL was scraped for metrics.",
724+
Namespace: namespace,
725+
Subsystem: exporter,
726+
Name: "scrapes_total",
727+
Help: "Total number of times PostgresSQL was scraped for metrics.",
728+
ConstLabels: newConstLabels(),
724729
}),
725730
error: prometheus.NewGauge(prometheus.GaugeOpts{
726-
Namespace: namespace,
727-
Subsystem: exporter,
728-
Name: "last_scrape_error",
729-
Help: "Whether the last scrape of metrics from PostgreSQL resulted in an error (1 for error, 0 for success).",
731+
Namespace: namespace,
732+
Subsystem: exporter,
733+
Name: "last_scrape_error",
734+
Help: "Whether the last scrape of metrics from PostgreSQL resulted in an error (1 for error, 0 for success).",
735+
ConstLabels: newConstLabels(),
730736
}),
731737
psqlUp: prometheus.NewGauge(prometheus.GaugeOpts{
732-
Namespace: namespace,
733-
Name: "up",
734-
Help: "Whether the last scrape of metrics from PostgreSQL was able to connect to the server (1 for yes, 0 for no).",
738+
Namespace: namespace,
739+
Name: "up",
740+
Help: "Whether the last scrape of metrics from PostgreSQL was able to connect to the server (1 for yes, 0 for no).",
741+
ConstLabels: newConstLabels(),
735742
}),
736743
userQueriesError: prometheus.NewGaugeVec(prometheus.GaugeOpts{
737-
Namespace: namespace,
738-
Subsystem: exporter,
739-
Name: "user_queries_load_error",
740-
Help: "Whether the user queries file was loaded and parsed successfully (1 for error, 0 for success).",
744+
Namespace: namespace,
745+
Subsystem: exporter,
746+
Name: "user_queries_load_error",
747+
Help: "Whether the user queries file was loaded and parsed successfully (1 for error, 0 for success).",
748+
ConstLabels: newConstLabels(),
741749
}, []string{"filename", "hashsum"}),
742750
metricMap: nil,
743751
queryOverrides: nil,
@@ -783,10 +791,32 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
783791
e.userQueriesError.Collect(ch)
784792
}
785793

794+
func newConstLabels() prometheus.Labels {
795+
if constantLabelsList == nil || *constantLabelsList == "" {
796+
return nil
797+
}
798+
799+
var constLabels = make(prometheus.Labels)
800+
parts := strings.Split(*constantLabelsList, ",")
801+
for _, p := range parts {
802+
keyValue := strings.Split(strings.TrimSpace(p), "=")
803+
if len(keyValue) != 2 {
804+
continue
805+
}
806+
key := strings.TrimSpace(keyValue[0])
807+
value := strings.TrimSpace(keyValue[1])
808+
if key == "" || value == "" {
809+
continue
810+
}
811+
constLabels[key] = value
812+
}
813+
return constLabels
814+
}
815+
786816
func newDesc(subsystem, name, help string) *prometheus.Desc {
787817
return prometheus.NewDesc(
788818
prometheus.BuildFQName(namespace, subsystem, name),
789-
help, nil, nil,
819+
help, nil, newConstLabels(),
790820
)
791821
}
792822

@@ -872,7 +902,7 @@ func queryNamespaceMapping(ch chan<- prometheus.Metric, db *sql.DB, namespace st
872902
} else {
873903
// Unknown metric. Report as untyped if scan to float64 works, else note an error too.
874904
metricLabel := fmt.Sprintf("%s_%s", namespace, columnName)
875-
desc := prometheus.NewDesc(metricLabel, fmt.Sprintf("Unknown metric from %s", namespace), mapping.labels, nil)
905+
desc := prometheus.NewDesc(metricLabel, fmt.Sprintf("Unknown metric from %s", namespace), mapping.labels, newConstLabels())
876906

877907
// Its not an error to fail here, since the values are
878908
// unexpected anyway.
@@ -976,7 +1006,7 @@ func (e *Exporter) checkMapVersions(ch chan<- prometheus.Metric, db *sql.DB) err
9761006

9771007
// Output the version as a special metric
9781008
versionDesc := prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, staticLabelName),
979-
"Version string as reported by postgres", []string{"version", "short_version"}, nil)
1009+
"Version string as reported by postgres", []string{"version", "short_version"}, newConstLabels())
9801010

9811011
ch <- prometheus.MustNewConstMetric(versionDesc,
9821012
prometheus.UntypedValue, 1, versionString, semanticVersion.String())

0 commit comments

Comments
 (0)