@@ -129,6 +129,16 @@ type MetricMap struct {
129129 conversion func (interface {}) (float64 , bool ) // Conversion function to turn PG result into float64
130130}
131131
132+ // ErrorConnectToServer is a connection to PgSQL server error
133+ type ErrorConnectToServer struct {
134+ Msg string
135+ }
136+
137+ // Error returns error
138+ func (e * ErrorConnectToServer ) Error () string {
139+ return e .Msg
140+ }
141+
132142// TODO: revisit this with the semver system
133143func dumpMaps () {
134144 // TODO: make this function part of the exporter
@@ -813,21 +823,24 @@ func (s *Server) String() string {
813823}
814824
815825// Scrape loads metrics.
816- func (s * Server ) Scrape (ch chan <- prometheus.Metric , errGauge prometheus. Gauge , disableSettingsMetrics bool ) {
826+ func (s * Server ) Scrape (ch chan <- prometheus.Metric , disableSettingsMetrics bool ) error {
817827 s .mappingMtx .RLock ()
818828 defer s .mappingMtx .RUnlock ()
819829
830+ var err error
831+
820832 if ! disableSettingsMetrics {
821- if err := querySettings (ch , s ); err != nil {
822- log .Errorf ("Error retrieving settings: %s" , err )
823- errGauge .Inc ()
833+ if err = querySettings (ch , s ); err != nil {
834+ err = fmt .Errorf ("error retrieving settings: %s" , err )
824835 }
825836 }
826837
827838 errMap := queryNamespaceMappings (ch , s )
828839 if len (errMap ) > 0 {
829- errGauge . Inc ( )
840+ err = fmt . Errorf ( "queryNamespaceMappings returned %d errors" , len ( errMap ) )
830841 }
842+
843+ return err
831844}
832845
833846// Servers contains a collection of servers to Postgres.
@@ -1289,16 +1302,40 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
12891302 e .duration .Set (time .Since (begun ).Seconds ())
12901303 }(time .Now ())
12911304
1292- e .error .Set (0 )
1293- e .psqlUp .Set (0 )
12941305 e .totalScrapes .Inc ()
12951306
12961307 dsns := e .dsn
12971308 if e .autoDiscoverDatabases {
12981309 dsns = e .discoverDatabaseDSNs ()
12991310 }
1311+
1312+ var errorsCount int
1313+ var connectionErrorsCount int
1314+
13001315 for _ , dsn := range dsns {
1301- e .scrapeDSN (ch , dsn )
1316+ if err := e .scrapeDSN (ch , dsn ); err != nil {
1317+ errorsCount ++
1318+
1319+ log .Errorf (err .Error ())
1320+
1321+ if _ , ok := err .(* ErrorConnectToServer ); ok {
1322+ connectionErrorsCount ++
1323+ }
1324+ }
1325+ }
1326+
1327+ switch {
1328+ case connectionErrorsCount >= len (dsns ):
1329+ e .psqlUp .Set (0 )
1330+ default :
1331+ e .psqlUp .Set (1 ) // Didn't fail, can mark connection as up for this scrape.
1332+ }
1333+
1334+ switch errorsCount {
1335+ case 0 :
1336+ e .error .Set (0 )
1337+ default :
1338+ e .error .Set (1 )
13021339 }
13031340}
13041341
@@ -1342,24 +1379,18 @@ func (e *Exporter) discoverDatabaseDSNs() []string {
13421379 return result
13431380}
13441381
1345- func (e * Exporter ) scrapeDSN (ch chan <- prometheus.Metric , dsn string ) {
1382+ func (e * Exporter ) scrapeDSN (ch chan <- prometheus.Metric , dsn string ) error {
13461383 server , err := e .servers .GetServer (dsn )
13471384 if err != nil {
1348- log .Errorf ("Error opening connection to database (%s): %v" , loggableDSN (dsn ), err )
1349- e .error .Inc ()
1350- return
1385+ return & ErrorConnectToServer {fmt .Sprintf ("Error opening connection to database (%s): %s" , loggableDSN (dsn ), err )}
13511386 }
13521387
1353- // Didn't fail, can mark connection as up for this scrape.
1354- e .psqlUp .Inc ()
1355-
13561388 // Check if map versions need to be updated
13571389 if err := e .checkMapVersions (ch , server ); err != nil {
13581390 log .Warnln ("Proceeding with outdated query maps, as the Postgres version could not be determined:" , err )
1359- e .error .Inc ()
13601391 }
13611392
1362- server .Scrape (ch , e . error , e .disableSettingsMetrics )
1393+ return server .Scrape (ch , e .disableSettingsMetrics )
13631394}
13641395
13651396// try to get the DataSource
0 commit comments