Skip to content
Snippets Groups Projects
Commit c225a1e1 authored by Robson Roberto Souza Peixoto's avatar Robson Roberto Souza Peixoto Committed by Will Rouesnel
Browse files

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
parent 265a2ea8
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -38,6 +38,7 @@ var (
disableDefaultMetrics = kingpin.Flag("disable-default-metrics", "Do not include default metrics.").Default("false").OverrideDefaultFromEnvar("PG_EXPORTER_DISABLE_DEFAULT_METRICS").Bool()
queriesPath = kingpin.Flag("extend.query-path", "Path to custom queries to run.").Default("").OverrideDefaultFromEnvar("PG_EXPORTER_EXTEND_QUERY_PATH").String()
onlyDumpMaps = kingpin.Flag("dumpmaps", "Do not run, simply dump the maps.").Bool()
constantLabelsList = kingpin.Flag("constantLabels", "A list of label=value separated by comma(,).").Default("").OverrideDefaultFromEnvar("PG_EXPORTER_CONTANT_LABELS").String()
)
 
// Metric name parts.
Loading
Loading
@@ -484,13 +485,15 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
thisMap := make(map[string]MetricMap)
 
// Get the constant labels
var constLabels []string
var variableLabels []string
for columnName, columnMapping := range mappings {
if columnMapping.usage == LABEL {
constLabels = append(constLabels, columnName)
variableLabels = append(variableLabels, columnName)
}
}
 
constLabels := newConstLabels()
for columnName, columnMapping := range mappings {
// Check column version compatibility for the current map
// Force to discard if not compatible.
Loading
Loading
@@ -522,7 +525,7 @@ 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, variableLabels, constLabels),
conversion: func(in interface{}) (float64, bool) {
return dbToFloat64(in)
},
Loading
Loading
@@ -530,7 +533,7 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
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, variableLabels, constLabels),
conversion: func(in interface{}) (float64, bool) {
return dbToFloat64(in)
},
Loading
Loading
@@ -538,7 +541,7 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
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, variableLabels, constLabels),
conversion: func(in interface{}) (float64, bool) {
text, ok := in.(string)
if !ok {
Loading
Loading
@@ -555,7 +558,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, variableLabels, constLabels),
conversion: func(in interface{}) (float64, bool) {
var durationString string
switch t := in.(type) {
Loading
Loading
@@ -583,7 +586,7 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
}
}
 
metricMap[namespace] = MetricMapNamespace{constLabels, thisMap}
metricMap[namespace] = MetricMapNamespace{variableLabels, thisMap}
}
 
return metricMap
Loading
Loading
@@ -711,33 +714,38 @@ func NewExporter(dsn string, disableDefaultMetrics bool, userQueriesPath string)
disableDefaultMetrics: disableDefaultMetrics,
userQueriesPath: userQueriesPath,
duration: prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: exporter,
Name: "last_scrape_duration_seconds",
Help: "Duration of the last scrape of metrics from PostgresSQL.",
Namespace: namespace,
Subsystem: exporter,
Name: "last_scrape_duration_seconds",
Help: "Duration of the last scrape of metrics from PostgresSQL.",
ConstLabels: newConstLabels(),
}),
totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: exporter,
Name: "scrapes_total",
Help: "Total number of times PostgresSQL was scraped for metrics.",
Namespace: namespace,
Subsystem: exporter,
Name: "scrapes_total",
Help: "Total number of times PostgresSQL was scraped for metrics.",
ConstLabels: newConstLabels(),
}),
error: prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: exporter,
Name: "last_scrape_error",
Help: "Whether the last scrape of metrics from PostgreSQL resulted in an error (1 for error, 0 for success).",
Namespace: namespace,
Subsystem: exporter,
Name: "last_scrape_error",
Help: "Whether the last scrape of metrics from PostgreSQL resulted in an error (1 for error, 0 for success).",
ConstLabels: newConstLabels(),
}),
psqlUp: prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: namespace,
Name: "up",
Help: "Whether the last scrape of metrics from PostgreSQL was able to connect to the server (1 for yes, 0 for no).",
Namespace: namespace,
Name: "up",
Help: "Whether the last scrape of metrics from PostgreSQL was able to connect to the server (1 for yes, 0 for no).",
ConstLabels: newConstLabels(),
}),
userQueriesError: prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: exporter,
Name: "user_queries_load_error",
Help: "Whether the user queries file was loaded and parsed successfully (1 for error, 0 for success).",
Namespace: namespace,
Subsystem: exporter,
Name: "user_queries_load_error",
Help: "Whether the user queries file was loaded and parsed successfully (1 for error, 0 for success).",
ConstLabels: newConstLabels(),
}, []string{"filename", "hashsum"}),
metricMap: nil,
queryOverrides: nil,
Loading
Loading
@@ -783,10 +791,32 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
e.userQueriesError.Collect(ch)
}
 
func newConstLabels() prometheus.Labels {
if constantLabelsList == nil || *constantLabelsList == "" {
return nil
}
var constLabels = make(prometheus.Labels)
parts := strings.Split(*constantLabelsList, ",")
for _, p := range parts {
keyValue := strings.Split(strings.TrimSpace(p), "=")
if len(keyValue) != 2 {
continue
}
key := strings.TrimSpace(keyValue[0])
value := strings.TrimSpace(keyValue[1])
if key == "" || value == "" {
continue
}
constLabels[key] = value
}
return constLabels
}
func newDesc(subsystem, name, help string) *prometheus.Desc {
return prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, name),
help, nil, nil,
help, nil, newConstLabels(),
)
}
 
Loading
Loading
@@ -872,7 +902,7 @@ func queryNamespaceMapping(ch chan<- prometheus.Metric, db *sql.DB, namespace st
} else {
// Unknown metric. Report as untyped if scan to float64 works, else note an error too.
metricLabel := fmt.Sprintf("%s_%s", namespace, columnName)
desc := prometheus.NewDesc(metricLabel, fmt.Sprintf("Unknown metric from %s", namespace), mapping.labels, nil)
desc := prometheus.NewDesc(metricLabel, fmt.Sprintf("Unknown metric from %s", namespace), mapping.labels, newConstLabels())
 
// Its not an error to fail here, since the values are
// unexpected anyway.
Loading
Loading
@@ -976,7 +1006,7 @@ func (e *Exporter) checkMapVersions(ch chan<- prometheus.Metric, db *sql.DB) err
 
// Output the version as a special metric
versionDesc := prometheus.NewDesc(fmt.Sprintf("%s_%s", namespace, staticLabelName),
"Version string as reported by postgres", []string{"version", "short_version"}, nil)
"Version string as reported by postgres", []string{"version", "short_version"}, newConstLabels())
 
ch <- prometheus.MustNewConstMetric(versionDesc,
prometheus.UntypedValue, 1, versionString, semanticVersion.String())
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment