1
0
mirror of https://github.com/prometheus-community/postgres_exporter.git synced 2025-11-22 11:02:36 +03:00

Use the pg_settings view to retrieve runtime variable

Adds all bool/integer/real runtime variables that can be retrieved ths way.

Use the `pg_settings` view to retrieve runtime variables:
https://www.postgresql.org/docs/current/static/view-pg-settings.html

Replaces the use of `SHOW` to retrieve runtime variables.

Only runtime variables with a `vartype` of `bool`, `real`, or `integer`
are currently supported. Uses the `short_desc` field as a description.

This commit deprecates the following metric names:
```
pg_runtime_variable_max_connections
pg_runtime_variable_max_files_per_process
pg_runtime_variable_max_function_args
pg_runtime_variable_max_identifier_length
pg_runtime_variable_max_index_keys
pg_runtime_variable_max_locks_per_transaction
pg_runtime_variable_max_pred_locks_per_transaction
pg_runtime_variable_max_prepared_transactions
pg_runtime_variable_max_standby_archive_delay_milliseconds
pg_runtime_variable_max_standby_streaming_delay_milliseconds
pg_runtime_variable_max_wal_senders
```

They are replaced by equivalent names under `pg_settings` with the exception of
```
pg_runtime_variable_max_standby_archive_delay_milliseconds
pg_runtime_variable_max_standby_streaming_delay_milliseconds
```
which are replaced with
```
pg_settings_max_standby_archive_delay_seconds
pg_settings_max_standby_streaming_delay_seconds
```

Adds approximately 195 new metrics, when considered across all supported
PostgreSQL versions.
This commit is contained in:
Matt Bostock
2017-03-27 22:34:22 +01:00
committed by Will Rouesnel
parent 994be318d4
commit 98ba566322
4 changed files with 331 additions and 75 deletions

View File

@@ -95,12 +95,6 @@ const (
DURATION ColumnUsage = iota // This column should be interpreted as a text duration (and converted to milliseconds)
)
// Special case matric mappings
const (
// Which metric mapping should be acquired using "SHOW" queries
SHOW_METRIC = "pg_runtime_variables"
)
// Regex used to get the "short-version" from the postgres version field.
var versionRegex = regexp.MustCompile(`^\w+ (\d+\.\d+\.\d+)`)
var lowestSupportedVersion = semver.MustParse("9.1.0")
@@ -147,24 +141,6 @@ type MetricMap struct {
conversion func(interface{}) (float64, bool) // Conversion function to turn PG result into float64
}
// Metric descriptors for dynamically created metrics.
var variableMaps = map[string]map[string]ColumnMapping{
"pg_runtime_variable": {
"max_connections": {GAUGE, "Sets the maximum number of concurrent connections.", nil, nil},
"max_files_per_process": {GAUGE, "Sets the maximum number of simultaneously open files for each server process.", nil, nil},
"max_function_args": {GAUGE, "Shows the maximum number of function arguments.", nil, nil},
"max_identifier_length": {GAUGE, "Shows the maximum identifier length.", nil, nil},
"max_index_keys": {GAUGE, "Shows the maximum number of index keys.", nil, nil},
"max_locks_per_transaction": {GAUGE, "Sets the maximum number of locks per transaction.", nil, nil},
"max_pred_locks_per_transaction": {GAUGE, "Sets the maximum number of predicate locks per transaction.", nil, nil},
"max_prepared_transactions": {GAUGE, "Sets the maximum number of simultaneously prepared transactions.", nil, nil},
//"max_stack_depth" : { GAUGE, "Sets the maximum number of concurrent connections.", nil }, // No dehumanize support yet
"max_standby_archive_delay": {DURATION, "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data.", nil, nil},
"max_standby_streaming_delay": {DURATION, "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data.", nil, nil},
"max_wal_senders": {GAUGE, "Sets the maximum number of simultaneously running WAL sender processes.", nil, nil},
},
}
// TODO: revisit this with the semver system
func dumpMaps() {
for name, cmap := range metricMaps {
@@ -694,8 +670,6 @@ type Exporter struct {
// Last version used to calculate metric map. If mismatch on scrape,
// then maps are recalculated.
lastMapVersion semver.Version
// Currently active variable map
variableMap map[string]MetricMapNamespace
// Currently active metric map
metricMap map[string]MetricMapNamespace
// Currently active query overrides
@@ -726,7 +700,6 @@ func NewExporter(dsn string, userQueriesPath string) *Exporter {
Name: "last_scrape_error",
Help: "Whether the last scrape of metrics from PostgreSQL resulted in an error (1 for error, 0 for success).",
}),
variableMap: nil,
metricMap: nil,
queryOverrides: nil,
}
@@ -776,42 +749,6 @@ func newDesc(subsystem, name, help string) *prometheus.Desc {
)
}
// Query the SHOW variables from the query map
// TODO: make this more functional
func queryShowVariables(ch chan<- prometheus.Metric, db *sql.DB, variableMap map[string]MetricMapNamespace) []error {
log.Debugln("Querying SHOW variables")
nonFatalErrors := []error{}
for _, mapping := range variableMap {
for columnName, columnMapping := range mapping.columnMappings {
// Check for a discard request on this value
if columnMapping.discard {
continue
}
// Use SHOW to get the value
row := db.QueryRow(fmt.Sprintf("SHOW %s;", columnName))
var val interface{}
err := row.Scan(&val)
if err != nil {
nonFatalErrors = append(nonFatalErrors, errors.New(fmt.Sprintln("Error scanning runtime variable:", columnName, err)))
continue
}
fval, ok := columnMapping.conversion(val)
if !ok {
nonFatalErrors = append(nonFatalErrors, errors.New(fmt.Sprintln("Unexpected error parsing column: ", namespace, columnName, val)))
continue
}
ch <- prometheus.MustNewConstMetric(columnMapping.desc, columnMapping.vtype, fval)
}
}
return nonFatalErrors
}
// Query within a namespace mapping and emit metrics. Returns fatal errors if
// the scrape fails, and a slice of errors if they were non-fatal.
func queryNamespaceMapping(ch chan<- prometheus.Metric, db *sql.DB, namespace string, mapping MetricMapNamespace, queryOverrides map[string]string) ([]error, error) {
@@ -942,11 +879,10 @@ func (e *Exporter) checkMapVersions(ch chan<- prometheus.Metric, db *sql.DB) err
semanticVersion, err := parseVersion(versionString)
// Check if semantic version changed and recalculate maps if needed.
if semanticVersion.NE(e.lastMapVersion) || e.variableMap == nil || e.metricMap == nil {
if semanticVersion.NE(e.lastMapVersion) || e.metricMap == nil {
log.Infoln("Semantic Version Changed:", e.lastMapVersion.String(), "->", semanticVersion.String())
e.mappingMtx.Lock()
e.variableMap = makeDescMap(semanticVersion, variableMaps)
e.metricMap = makeDescMap(semanticVersion, metricMaps)
e.queryOverrides = makeQueryOverrideMap(semanticVersion, queryOverrides)
e.lastMapVersion = semanticVersion
@@ -1016,9 +952,8 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
// Lock the exporter maps
e.mappingMtx.RLock()
defer e.mappingMtx.RUnlock()
// Handle querying the show variables
nonFatalErrors := queryShowVariables(ch, db, e.variableMap)
if len(nonFatalErrors) > 0 {
if err := querySettings(ch, db); err != nil {
log.Infof("Error retrieving settings: %s", err)
e.error.Set(1)
}