From 2850ac800aa0920740e1e190a7c94b031be81df4 Mon Sep 17 00:00:00 2001
From: Pavel Sapezhko <me@weastur.com>
Date: Thu, 11 Mar 2021 12:57:14 +0300
Subject: [PATCH] Add ability to set allow DBs list

Signed-off-by: Pavel Sapezhko <me@weastur.com>
---
 README.md                                  | 10 ++++++++++
 cmd/postgres_exporter/postgres_exporter.go | 14 ++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/README.md b/README.md
index 9d5900c6..1e4f572a 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,9 @@ This will build the docker image as `prometheuscommunity/postgres_exporter:${bra
 * `exclude-databases`
   A list of databases to remove when autoDiscoverDatabases is enabled.
 
+* `include-databases`
+  A list of databases to only include when autoDiscoverDatabases is enabled.
+
 * `log.level`
   Set logging level: one of `debug`, `info`, `warn`, `error`.
 
@@ -138,6 +141,10 @@ The following environment variables configure the exporter:
 * `PG_EXPORTER_EXCLUDE_DATABASES`
   A comma-separated list of databases to remove when autoDiscoverDatabases is enabled. Default is empty string.
 
+* `PG_EXPORTER_INCLUDE_DATABASES`
+  A comma-separated list of databases to only include when autoDiscoverDatabases is enabled. Default is empty string,
+  means allow all.
+
 * `PG_EXPORTER_METRIC_PREFIX`
   A prefix to use for each of the default metrics exported by postgres-exporter. Default is `pg`
 
@@ -191,6 +198,9 @@ result a new set of DSN's is created for which the metrics are scraped.
 
 In addition, the option `--exclude-databases` adds the possibily to filter the result from the auto discovery to discard databases you do not need.
 
+If you want to include only subset of databases, you can use option `--include-databases`. Exporter still makes request to
+`pg_database` table, but do scrape from only if database is in include list.
+
 ### Running as non-superuser
 
 To be able to collect metrics from `pg_stat_activity` and `pg_stat_replication`
diff --git a/cmd/postgres_exporter/postgres_exporter.go b/cmd/postgres_exporter/postgres_exporter.go
index 10c89987..5abadaff 100644
--- a/cmd/postgres_exporter/postgres_exporter.go
+++ b/cmd/postgres_exporter/postgres_exporter.go
@@ -55,6 +55,7 @@ var (
 	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("").Envar("PG_EXPORTER_CONSTANT_LABELS").String()
 	excludeDatabases       = kingpin.Flag("exclude-databases", "A list of databases to remove when autoDiscoverDatabases is enabled").Default("").Envar("PG_EXPORTER_EXCLUDE_DATABASES").String()
+	includeDatabases       = kingpin.Flag("include-databases", "A list of databases to include when autoDiscoverDatabases is enabled").Default("").Envar("PG_EXPORTER_INCLUDE_DATABASES").String()
 	metricPrefix           = kingpin.Flag("metric-prefix", "A metric prefix can be used to have non-default (not \"pg\") prefixes for each of the metrics").Default("pg").Envar("PG_EXPORTER_METRIC_PREFIX").String()
 	logger                 = log.NewNopLogger()
 )
@@ -1099,6 +1100,7 @@ type Exporter struct {
 	disableDefaultMetrics, disableSettingsMetrics, autoDiscoverDatabases bool
 
 	excludeDatabases []string
+	includeDatabases []string
 	dsn              []string
 	userQueriesPath  string
 	constantLabels   prometheus.Labels
@@ -1144,6 +1146,13 @@ func ExcludeDatabases(s string) ExporterOpt {
 	}
 }
 
+// IncludeDatabases allows to filter result from AutoDiscoverDatabases
+func IncludeDatabases(s string) ExporterOpt {
+	return func(e *Exporter) {
+		e.includeDatabases = strings.Split(s, ",")
+	}
+}
+
 // WithUserQueriesPath configures user's queries path.
 func WithUserQueriesPath(p string) ExporterOpt {
 	return func(e *Exporter) {
@@ -1678,6 +1687,10 @@ func (e *Exporter) discoverDatabaseDSNs() []string {
 				continue
 			}
 
+			if len(e.includeDatabases) != 0 && !contains(e.includeDatabases, databaseName) {
+				continue
+			}
+
 			if dsnURI != nil {
 				dsnURI.Path = databaseName
 				dsn = dsnURI.String()
@@ -1822,6 +1835,7 @@ func main() {
 		WithUserQueriesPath(*queriesPath),
 		WithConstantLabels(*constantLabelsList),
 		ExcludeDatabases(*excludeDatabases),
+		IncludeDatabases(*includeDatabases),
 	}
 
 	exporter := NewExporter(dsn, opts...)