mirror of
https://github.com/prometheus-community/postgres_exporter
synced 2025-04-11 03:31:26 +00:00
Support connstring syntax when discovering databases (#473)
* Support connstring syntax when discovering databases Support connstring DSNs (`host=... user=... password=... dbname=...`) in addition to URIs (`postgresql://user:pass@host/dbname`) for purposes of database discovery. Connstring syntax is needed to support accessing PostgreSQL via Unix domain sockets (`host=/run/postgres`), which is not really possible with URI syntax. * Appease gometalinter, don't shadow namespace
This commit is contained in:
parent
aea6fae7d6
commit
1ba1100a72
@ -601,6 +601,8 @@ func makeDescMap(pgVersion semver.Version, serverLabels prometheus.Labels, metri
|
|||||||
for namespace, intermediateMappings := range metricMaps {
|
for namespace, intermediateMappings := range metricMaps {
|
||||||
thisMap := make(map[string]MetricMap)
|
thisMap := make(map[string]MetricMap)
|
||||||
|
|
||||||
|
namespace = strings.Replace(namespace, "pg", *metricPrefix, 1)
|
||||||
|
|
||||||
// Get the constant labels
|
// Get the constant labels
|
||||||
var variableLabels []string
|
var variableLabels []string
|
||||||
for columnName, columnMapping := range intermediateMappings.columnMappings {
|
for columnName, columnMapping := range intermediateMappings.columnMappings {
|
||||||
@ -627,8 +629,6 @@ func makeDescMap(pgVersion semver.Version, serverLabels prometheus.Labels, metri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace := strings.Replace(namespace, "pg", *metricPrefix, 1)
|
|
||||||
|
|
||||||
// Determine how to convert the column based on its usage.
|
// Determine how to convert the column based on its usage.
|
||||||
// nolint: dupl
|
// nolint: dupl
|
||||||
switch columnMapping.usage {
|
switch columnMapping.usage {
|
||||||
@ -1616,11 +1616,27 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exporter) discoverDatabaseDSNs() []string {
|
func (e *Exporter) discoverDatabaseDSNs() []string {
|
||||||
|
// connstring syntax is complex (and not sure if even regular).
|
||||||
|
// we don't need to parse it, so just superficially validate that it starts
|
||||||
|
// with a valid-ish keyword pair
|
||||||
|
connstringRe := regexp.MustCompile(`^ *[a-zA-Z0-9]+ *= *[^= ]+`)
|
||||||
|
|
||||||
dsns := make(map[string]struct{})
|
dsns := make(map[string]struct{})
|
||||||
for _, dsn := range e.dsn {
|
for _, dsn := range e.dsn {
|
||||||
parsedDSN, err := url.Parse(dsn)
|
var dsnURI *url.URL
|
||||||
if err != nil {
|
var dsnConnstring string
|
||||||
log.Errorf("Unable to parse DSN (%s): %v", loggableDSN(dsn), err)
|
|
||||||
|
if strings.HasPrefix(dsn, "postgresql://") {
|
||||||
|
var err error
|
||||||
|
dsnURI, err = url.Parse(dsn)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Unable to parse DSN as URI (%s): %v", loggableDSN(dsn), err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if connstringRe.MatchString(dsn) {
|
||||||
|
dsnConnstring = dsn
|
||||||
|
} else {
|
||||||
|
log.Errorf("Unable to parse DSN as either URI or connstring (%s)", loggableDSN(dsn))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1643,8 +1659,16 @@ func (e *Exporter) discoverDatabaseDSNs() []string {
|
|||||||
if contains(e.excludeDatabases, databaseName) {
|
if contains(e.excludeDatabases, databaseName) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
parsedDSN.Path = databaseName
|
|
||||||
dsns[parsedDSN.String()] = struct{}{}
|
if dsnURI != nil {
|
||||||
|
dsnURI.Path = databaseName
|
||||||
|
dsn = dsnURI.String()
|
||||||
|
} else {
|
||||||
|
// replacing one dbname with another is complicated.
|
||||||
|
// just append new dbname to override.
|
||||||
|
dsn = fmt.Sprintf("%s dbname=%s", dsnConnstring, databaseName)
|
||||||
|
}
|
||||||
|
dsns[dsn] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user