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:
committed by
Will Rouesnel
parent
994be318d4
commit
98ba566322
132
pg_setting.go
Normal file
132
pg_setting.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/common/log"
|
||||
)
|
||||
|
||||
// Query the pg_settings view containing runtime variables
|
||||
func querySettings(ch chan<- prometheus.Metric, db *sql.DB) error {
|
||||
log.Debugln("Querying pg_setting view")
|
||||
|
||||
// pg_settings docs: https://www.postgresql.org/docs/current/static/view-pg-settings.html
|
||||
//
|
||||
// NOTE: If you add more vartypes here, you must update the supported
|
||||
// types in normaliseUnit() below
|
||||
query := "SELECT name, setting, COALESCE(unit, ''), short_desc, vartype FROM pg_settings WHERE vartype IN ('bool', 'integer', 'real');"
|
||||
|
||||
rows, err := db.Query(query)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintln("Error running query on database: ", namespace, err))
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
s := &pgSetting{}
|
||||
err = rows.Scan(&s.name, &s.setting, &s.unit, &s.shortDesc, &s.vartype)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintln("Error retrieving rows:", namespace, err))
|
||||
}
|
||||
|
||||
ch <- s.metric()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// pgSetting is represents a PostgreSQL runtime variable as returned by the
|
||||
// pg_settings view.
|
||||
type pgSetting struct {
|
||||
name, setting, unit, shortDesc, vartype string
|
||||
}
|
||||
|
||||
func (s *pgSetting) metric() prometheus.Metric {
|
||||
var (
|
||||
err error
|
||||
name = s.name
|
||||
unit = s.unit
|
||||
shortDesc = s.shortDesc
|
||||
subsystem = "settings"
|
||||
val float64
|
||||
)
|
||||
|
||||
switch s.vartype {
|
||||
case "bool":
|
||||
if s.setting == "on" {
|
||||
val = 1
|
||||
}
|
||||
case "integer", "real":
|
||||
if val, unit, err = s.normaliseUnit(); err != nil {
|
||||
// Panic, since we should recognise all units
|
||||
// and don't want to silently exlude metrics
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(unit) > 0 {
|
||||
name = fmt.Sprintf("%s_%s", name, unit)
|
||||
shortDesc = fmt.Sprintf("%s [Units converted to %s.]", shortDesc, unit)
|
||||
}
|
||||
default:
|
||||
// Panic because we got a type we didn't ask for
|
||||
panic(fmt.Sprintf("Unsupported vartype %q", s.vartype))
|
||||
}
|
||||
|
||||
desc := newDesc(subsystem, name, shortDesc)
|
||||
return prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, val)
|
||||
}
|
||||
|
||||
func (s *pgSetting) normaliseUnit() (val float64, unit string, err error) {
|
||||
val, err = strconv.ParseFloat(s.setting, 64)
|
||||
if err != nil {
|
||||
return val, unit, errors.New(fmt.Sprintf("Error converting setting %q value %q to float: %s", s.name, s.setting, err))
|
||||
}
|
||||
|
||||
// Units defined in: https://www.postgresql.org/docs/current/static/config-setting.html
|
||||
switch s.unit {
|
||||
case "":
|
||||
return
|
||||
case "ms", "s", "min", "h", "d":
|
||||
unit = "seconds"
|
||||
case "kB", "MB", "GB", "TB", "8kB", "16MB":
|
||||
unit = "bytes"
|
||||
default:
|
||||
err = errors.New(fmt.Sprintf("Unknown unit for runtime variable: %q", s.unit))
|
||||
return
|
||||
}
|
||||
|
||||
// -1 is special, don't modify the value
|
||||
if val == -1 {
|
||||
return
|
||||
}
|
||||
|
||||
switch s.unit {
|
||||
case "ms":
|
||||
val /= 1000
|
||||
case "min":
|
||||
val *= 60
|
||||
case "h":
|
||||
val *= 60 * 60
|
||||
case "d":
|
||||
val *= 60 * 60 * 24
|
||||
case "kB":
|
||||
val *= math.Pow(2, 10)
|
||||
case "MB":
|
||||
val *= math.Pow(2, 20)
|
||||
case "GB":
|
||||
val *= math.Pow(2, 30)
|
||||
case "TB":
|
||||
val *= math.Pow(2, 40)
|
||||
case "8kB":
|
||||
val *= math.Pow(2, 13)
|
||||
case "16MB":
|
||||
val *= math.Pow(2, 24)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user