Skip to content
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
102 changes: 102 additions & 0 deletions postgres_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
//"strings"
"math"
"time"
"io/ioutil"
"gopkg.in/yaml.v2"

_ "github.com/lib/pq"
"github.com/prometheus/client_golang/prometheus"
Expand All @@ -30,6 +32,10 @@ var (
"web.telemetry-path", "/metrics",
"Path under which to expose metrics.",
)
queriesPath = flag.String(
"extend.query-path", "",
"Path to custom queries to run.",
)
)

// Metric name parts.
Expand Down Expand Up @@ -215,6 +221,67 @@ var queryOverrides = map[string]string{
ON tmp.state = tmp2.state AND pg_database.datname = tmp2.datname`,
}

// Add queries to the metricMaps and queryOverrides maps
func addQueries(queriesPath string) (err error) {
var extra map[string]interface{}

content, err := ioutil.ReadFile(queriesPath)
if err != nil {
return err
}

err = yaml.Unmarshal(content, &extra)
if err != nil {
return err
}


for metric, specs := range extra {
for key, value := range specs.(map[interface{}]interface{}) {
switch key.(string) {
case "query":
query := value.(string)
queryOverrides[metric] = query

case "metrics":
for _, c := range value.([]interface{}) {
column := c.(map[interface{}]interface{})

for n, a := range column {
var cmap ColumnMapping
var metric_map map[string]ColumnMapping

metric_map = make(map[string]ColumnMapping)

name := n.(string)

for attr_key, attr_val := range a.(map[interface{}]interface{}) {
switch(attr_key.(string)) {
case "usage":
usage, err := stringToColumnUsage(attr_val.(string))
if err != nil {
return err
}
cmap.usage = usage
case "description":
cmap.description = attr_val.(string)
}
}

cmap.mapping = nil

metric_map[name] = cmap

metricMaps[metric] = metric_map
}
}
}
}
}

return
}

// Turn the MetricMap column mapping into a prometheus descriptor mapping.
func makeDescMap(metricMaps map[string]map[string]ColumnMapping) map[string]MetricMapNamespace {
var metricMap = make(map[string]MetricMapNamespace)
Expand Down Expand Up @@ -305,6 +372,34 @@ func makeDescMap(metricMaps map[string]map[string]ColumnMapping) map[string]Metr
return metricMap
}

// convert a string to the corresponding ColumnUsage
func stringToColumnUsage(s string) (u ColumnUsage, err error) {
switch(s) {
case "DISCARD":
u = DISCARD

case "LABEL":
u = LABEL

case "COUNTER":
u = COUNTER

case "GAUGE":
u = GAUGE

case "MAPPEDMETRIC":
u = MAPPEDMETRIC

case "DURATION":
u = DURATION

default:
err = fmt.Errorf("wrong ColumnUsage given : %s", s)
}

return
}

// Convert database.sql types to float64s for Prometheus consumption. Null types are mapped to NaN. string and []byte
// types are mapped as NaN and !ok
func dbToFloat64(t interface{}) (float64, bool) {
Expand Down Expand Up @@ -576,6 +671,13 @@ func main() {
log.Fatal("couldn't find environment variable DATA_SOURCE_NAME")
}

if *queriesPath != "" {
err := addQueries(*queriesPath)
if err != nil {
log.Warnln("Unparseable queries file - discarding merge: ", *queriesPath, err)
}
}

exporter := NewExporter(dsn)
prometheus.MustRegister(exporter)

Expand Down
6 changes: 6 additions & 0 deletions queries.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pg_replication:
query: 'SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::INT as lag'
metrics:
- lag:
usage: 'GAUGE'
description: 'Replication lag behind master in seconds'
188 changes: 188 additions & 0 deletions vendor/gopkg.in/yaml.v2/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions vendor/gopkg.in/yaml.v2/LICENSE.libyaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading