From bd841c3a3599e14f5103188e259e1f34e9255cce Mon Sep 17 00:00:00 2001
From: Hector <dev@hsmith.org>
Date: Wed, 7 Apr 2021 21:32:49 +0100
Subject: [PATCH] feat: set up metric to 0 if errors found

The `up` metric is now based on whether an error was found while reading
data from the database to build other metrics. Note that there is a chance
the `up` metric will not be correctly set if the last metric to be built
before the `up` metric does not throw an error.
---
 src/exporter.go | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/exporter.go b/src/exporter.go
index 9a031c0..5519a40 100644
--- a/src/exporter.go
+++ b/src/exporter.go
@@ -42,7 +42,8 @@ var (
 )
 
 type Exporter struct {
-	db *fail2banDb.Fail2BanDB
+	db        *fail2banDb.Fail2BanDB
+	lastError error
 }
 
 func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
@@ -53,16 +54,26 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
 }
 
 func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
-	ch <- prometheus.MustNewConstMetric(
-		metricUp, prometheus.GaugeValue, 1,
-	)
 	e.collectBadIpsPerJailMetrics(ch)
 	e.collectBannedIpsPerJailMetrics(ch)
 	e.collectEnabledJailMetrics(ch)
+	e.collectUpMetric(ch)
+}
+
+func (e *Exporter) collectUpMetric(ch chan<- prometheus.Metric) {
+	var upMetricValue float64 = 1
+	if e.lastError != nil {
+		upMetricValue = 0
+	}
+	ch <- prometheus.MustNewConstMetric(
+		metricUp, prometheus.GaugeValue, upMetricValue,
+	)
 }
 
 func (e *Exporter) collectBadIpsPerJailMetrics(ch chan<- prometheus.Metric) {
 	jailNameToCountMap, err := e.db.CountBadIpsPerJail()
+	e.lastError = err
+
 	if err != nil {
 		log.Print(err)
 	}
@@ -76,6 +87,8 @@ func (e *Exporter) collectBadIpsPerJailMetrics(ch chan<- prometheus.Metric) {
 
 func (e *Exporter) collectBannedIpsPerJailMetrics(ch chan<- prometheus.Metric) {
 	jailNameToCountMap, err := e.db.CountBannedIpsPerJail()
+	e.lastError = err
+
 	if err != nil {
 		log.Print(err)
 	}
@@ -89,6 +102,8 @@ func (e *Exporter) collectBannedIpsPerJailMetrics(ch chan<- prometheus.Metric) {
 
 func (e *Exporter) collectEnabledJailMetrics(ch chan<- prometheus.Metric) {
 	jailNameToEnabledMap, err := e.db.JailNameToEnabledValue()
+	e.lastError = err
+
 	if err != nil {
 		log.Print(err)
 	}