From 7ceaa2dda80b3ea25fc5e7887f32caf62ea92955 Mon Sep 17 00:00:00 2001
From: Richard van der Hoff <github@rvanderhoff.org.uk>
Date: Fri, 10 Nov 2017 20:37:02 +0000
Subject: [PATCH] Send zeros for any nonexistent scoreboard states (#28)

* Send zeros for any nonexistent scoreboard states

Make sure that we report any unused worker states as having zero workers in
that state - otherwise Prometheus will continue to use the previous value for a
while.

* Update expected metric counts in tests

We now return metrics for each potential worker state, so there are a lot more
of them.
---
 apache_exporter.go      | 45 ++++++++++++++++++++---------------------
 apache_exporter_test.go | 14 ++++++++-----
 2 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/apache_exporter.go b/apache_exporter.go
index 3d1299f..0e796da 100644
--- a/apache_exporter.go
+++ b/apache_exporter.go
@@ -134,34 +134,33 @@ func splitkv(s string) (string, string) {
 	return strings.TrimSpace(slice[0]), strings.TrimSpace(slice[1])
 }
 
+var scoreboardLabelMap = map[string]string{
+	"_": "idle",
+	"S": "startup",
+	"R": "read",
+	"W": "reply",
+	"K": "keepalive",
+	"D": "dns",
+	"C": "closing",
+	"L": "logging",
+	"G": "graceful_stop",
+	"I": "idle_cleanup",
+	".": "open_slot",
+}
+
 func (e *Exporter) updateScoreboard(scoreboard string) {
 	e.scoreboard.Reset()
+	for _, v := range scoreboardLabelMap {
+		e.scoreboard.WithLabelValues(v)
+	}
+
 	for _, worker_status := range scoreboard {
 		s := string(worker_status)
-		switch {
-		case s == "_":
-			e.scoreboard.WithLabelValues("idle").Inc()
-		case s == "S":
-			e.scoreboard.WithLabelValues("startup").Inc()
-		case s == "R":
-			e.scoreboard.WithLabelValues("read").Inc()
-		case s == "W":
-			e.scoreboard.WithLabelValues("reply").Inc()
-		case s == "K":
-			e.scoreboard.WithLabelValues("keepalive").Inc()
-		case s == "D":
-			e.scoreboard.WithLabelValues("dns").Inc()
-		case s == "C":
-			e.scoreboard.WithLabelValues("closing").Inc()
-		case s == "L":
-			e.scoreboard.WithLabelValues("logging").Inc()
-		case s == "G":
-			e.scoreboard.WithLabelValues("graceful_stop").Inc()
-		case s == "I":
-			e.scoreboard.WithLabelValues("idle_cleanup").Inc()
-		case s == ".":
-			e.scoreboard.WithLabelValues("open_slot").Inc()
+		label, ok := scoreboardLabelMap[s]
+		if !ok {
+			label = s
 		}
+		e.scoreboard.WithLabelValues(label).Inc()
 	}
 }
 
diff --git a/apache_exporter_test.go b/apache_exporter_test.go
index a131781..1b47f65 100644
--- a/apache_exporter_test.go
+++ b/apache_exporter_test.go
@@ -99,9 +99,9 @@ IdleWorkers: 8
 Scoreboard: _W_______K......................................................................................................................................................................................................................................................
 `
 
-	metricCountApache22       = 11
-	metricCountApache24       = 13
-	metricCountApache24Worker = 11
+	metricCountApache22       = 18
+	metricCountApache24       = 22
+	metricCountApache24Worker = 18
 )
 
 func checkApacheStatus(t *testing.T, status string, metricCount int) {
@@ -124,8 +124,12 @@ func checkApacheStatus(t *testing.T, status string, metricCount int) {
 			t.Error("expected metric but got nil")
 		}
 	}
-	if <-ch != nil {
-		t.Error("expected closed channel")
+	extraMetrics := 0
+	for <-ch != nil {
+		extraMetrics++
+	}
+	if extraMetrics > 0 {
+		t.Errorf("expected closed channel, got %d extra metrics", extraMetrics)
 	}
 }
 
-- 
GitLab