From f70b52d0b6d91bfb19fc45ac5ef7872d2ba78064 Mon Sep 17 00:00:00 2001
From: Jeremy Meulemans <meule012@umn.edu>
Date: Thu, 16 Feb 2017 17:55:42 -0600
Subject: [PATCH] Adding gauge for number of open head chunks.

Fixes #1710
---
 storage/local/storage.go | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/storage/local/storage.go b/storage/local/storage.go
index 25dc30b0a7..81e1fd7306 100644
--- a/storage/local/storage.go
+++ b/storage/local/storage.go
@@ -180,6 +180,7 @@ type MemorySeriesStorage struct {
 	persistErrors                 prometheus.Counter
 	queuedChunksToPersist         prometheus.Counter
 	numSeries                     prometheus.Gauge
+	numHeadChunks                 prometheus.Gauge
 	dirtySeries                   prometheus.Gauge
 	seriesOps                     *prometheus.CounterVec
 	ingestedSamplesCount          prometheus.Counter
@@ -254,6 +255,12 @@ func NewMemorySeriesStorage(o *MemorySeriesStorageOptions) *MemorySeriesStorage
 			Name:      "memory_series",
 			Help:      "The current number of series in memory.",
 		}),
+		numHeadChunks: prometheus.NewGauge(prometheus.GaugeOpts{
+			Namespace: namespace,
+			Subsystem: subsystem,
+			Name:      "num_head_chunks_open",
+			Help:      "The current number of open head chunks.",
+		}),
 		dirtySeries: prometheus.NewGauge(prometheus.GaugeOpts{
 			Namespace: namespace,
 			Subsystem: subsystem,
@@ -372,6 +379,16 @@ func (s *MemorySeriesStorage) Start() (err error) {
 
 	log.Info("Loading series map and head chunks...")
 	s.fpToSeries, s.numChunksToPersist, err = p.loadSeriesMapAndHeads()
+	openHeadCount := 0
+	for fp := range s.fpToSeries.fpIter() {
+		if series, ok := s.fpToSeries.get(fp); ok {
+			if !series.headChunkClosed {
+				openHeadCount += 1
+			}
+		}
+	}
+	s.numHeadChunks.Set(float64(openHeadCount))
+
 	if err != nil {
 		return err
 	}
@@ -977,6 +994,9 @@ func (s *MemorySeriesStorage) getOrCreateSeries(fp model.Fingerprint, m model.Me
 		}
 		s.fpToSeries.put(fp, series)
 		s.numSeries.Inc()
+		if !series.headChunkClosed {
+			s.numHeadChunks.Inc()
+		}
 	}
 	return series, nil
 }
@@ -1383,6 +1403,7 @@ func (s *MemorySeriesStorage) maintainMemorySeries(
 	}
 	if closed {
 		s.incNumChunksToPersist(1)
+		s.numHeadChunks.Dec()
 	}
 
 	seriesWasDirty := series.dirty
@@ -1783,6 +1804,7 @@ func (s *MemorySeriesStorage) Describe(ch chan<- *prometheus.Desc) {
 	ch <- maxChunksToPersistDesc
 	ch <- numChunksToPersistDesc
 	ch <- s.numSeries.Desc()
+	ch <- s.numHeadChunks.Desc()
 	ch <- s.dirtySeries.Desc()
 	s.seriesOps.Describe(ch)
 	ch <- s.ingestedSamplesCount.Desc()
@@ -1812,6 +1834,7 @@ func (s *MemorySeriesStorage) Collect(ch chan<- prometheus.Metric) {
 		float64(s.getNumChunksToPersist()),
 	)
 	ch <- s.numSeries
+	ch <- s.numHeadChunks
 	ch <- s.dirtySeries
 	s.seriesOps.Collect(ch)
 	ch <- s.ingestedSamplesCount