diff --git a/postgres_exporter.go b/postgres_exporter.go index c4efed13..00c2bb1e 100644 --- a/postgres_exporter.go +++ b/postgres_exporter.go @@ -965,9 +965,13 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) { db, err := e.getDB(e.dsn) if err != nil { loggableDsn := "could not parse DATA_SOURCE_NAME" - if pDsn, pErr := url.Parse(e.dsn); pErr != nil { - log.Debugln("Blanking password for loggable DSN:", e.dsn) - pDsn.User = url.UserPassword(pDsn.User.Username(), "xxx") + // If the DSN is parseable, log it with a blanked out password + pDsn, pErr := url.Parse(e.dsn) + if pErr == nil { + // Blank user info if not nil + if pDsn.User != nil { + pDsn.User = url.UserPassword(pDsn.User.Username(), "PASSWORD_REMOVED") + } loggableDsn = pDsn.String() } log.Infof("Error opening connection to database (%s): %s", loggableDsn, err) @@ -1017,6 +1021,12 @@ func main() { } exporter := NewExporter(dsn, *queriesPath) + defer func() { + if exporter.dbConnection != nil { + exporter.dbConnection.Close() // nolint: errcheck + } + }() + prometheus.MustRegister(exporter) http.Handle(*metricPath, prometheus.Handler()) @@ -1026,7 +1036,4 @@ func main() { log.Infof("Starting Server: %s", *listenAddress) log.Fatal(http.ListenAndServe(*listenAddress, nil)) - if sharedDBConn != nil { - defer sharedDBConn.Close() // nolint: errcheck - } } diff --git a/postgres_exporter_integration_test.go b/postgres_exporter_integration_test.go index 63216d25..ee3c62f7 100644 --- a/postgres_exporter_integration_test.go +++ b/postgres_exporter_integration_test.go @@ -48,7 +48,6 @@ func (s *IntegrationSuite) TestAllNamespacesReturnResults(c *C) { } }() - // Open a database connection db, err := sql.Open("postgres", s.e.dsn) c.Assert(db, NotNil) @@ -75,8 +74,9 @@ func (s *IntegrationSuite) TestAllNamespacesReturnResults(c *C) { } } -// TestInvalidDsnDoesntCrash tests that specifying an invalid DSN doesn't crash the exporter. -// https://github.com/wrouesnel/postgres_exporter/issues/93 +// TestInvalidDsnDoesntCrash tests that specifying an invalid DSN doesn't crash +// the exporter. Related to https://github.com/wrouesnel/postgres_exporter/issues/93 +// although not a replication of the scenario. func (s *IntegrationSuite) TestInvalidDsnDoesntCrash(c *C) { // Setup a dummy channel to consume metrics ch := make(chan prometheus.Metric, 100) @@ -85,6 +85,13 @@ func (s *IntegrationSuite) TestInvalidDsnDoesntCrash(c *C) { } }() - exporter := NewExporter("an invalid dsn", *queriesPath) + // Send a bad DSN + exporter := NewExporter("invalid dsn", *queriesPath) + c.Assert(exporter, NotNil) exporter.scrape(ch) -} \ No newline at end of file + + // Send a DSN to a non-listening port. + exporter = NewExporter("postgresql://nothing:nothing@127.0.0.1:1/nothing", *queriesPath) + c.Assert(exporter, NotNil) + exporter.scrape(ch) +}