diff --git a/storage/metric/interface.go b/storage/metric/interface.go index 40d1a1452..a1823f7e2 100644 --- a/storage/metric/interface.go +++ b/storage/metric/interface.go @@ -52,7 +52,7 @@ type MetricPersistence interface { ForEachSample(IteratorsForFingerprintBuilder) (err error) - GetAllMetricNames() ([]string, error) + GetAllValuesForLabel(model.LabelName) (model.LabelValues, error) // Requests the storage stack to build a materialized View of the values // contained therein. diff --git a/storage/metric/leveldb.go b/storage/metric/leveldb.go index 5c52eacae..be1841e0b 100644 --- a/storage/metric/leveldb.go +++ b/storage/metric/leveldb.go @@ -1236,35 +1236,40 @@ func (d *MetricKeyDecoder) DecodeValue(in interface{}) (out interface{}, err err return } -type MetricNamesFilter struct{} +type LabelNameFilter struct { + labelName model.LabelName +} -func (f *MetricNamesFilter) Filter(key, value interface{}) (filterResult storage.FilterResult) { +func (f *LabelNameFilter) Filter(key, value interface{}) (filterResult storage.FilterResult) { unmarshaled, ok := key.(*dto.LabelPair) - if ok && *unmarshaled.Name == "name" { + if ok && model.LabelName(*unmarshaled.Name) == f.labelName { return storage.ACCEPT } return storage.SKIP } -type CollectMetricNamesOp struct { - metricNames []string +type CollectLabelValuesOp struct { + labelValues []model.LabelValue } -func (op *CollectMetricNamesOp) Operate(key, value interface{}) (err *storage.OperatorError) { +func (op *CollectLabelValuesOp) Operate(key, value interface{}) (err *storage.OperatorError) { unmarshaled := key.(*dto.LabelPair) - op.metricNames = append(op.metricNames, *unmarshaled.Value) + op.labelValues = append(op.labelValues, model.LabelValue(*unmarshaled.Value)) return } -func (l *LevelDBMetricPersistence) GetAllMetricNames() (metricNames []string, err error) { - metricNamesOp := &CollectMetricNamesOp{} +func (l *LevelDBMetricPersistence) GetAllValuesForLabel(labelName model.LabelName) (values model.LabelValues, err error) { + filter := &LabelNameFilter{ + labelName: labelName, + } + labelValuesOp := &CollectLabelValuesOp{} - _, err = l.labelSetToFingerprints.ForEach(&MetricKeyDecoder{}, &MetricNamesFilter{}, metricNamesOp) + _, err = l.labelSetToFingerprints.ForEach(&MetricKeyDecoder{}, filter, labelValuesOp) if err != nil { return } - metricNames = metricNamesOp.metricNames + values = labelValuesOp.labelValues return } diff --git a/storage/metric/memory.go b/storage/metric/memory.go index c1d67083c..b7372d672 100644 --- a/storage/metric/memory.go +++ b/storage/metric/memory.go @@ -348,19 +348,17 @@ func (s memorySeriesStorage) Close() (err error) { return } -func (s memorySeriesStorage) GetAllMetricNames() (metrics []string, err error) { - metricSet := map[string]bool{} +func (s memorySeriesStorage) GetAllValuesForLabel(labelName model.LabelName) (values model.LabelValues, err error) { + valueSet := map[model.LabelValue]bool{} for _, series := range s.fingerprintToSeries { - if metricName, ok := series.metric["name"]; !ok { - err = fmt.Errorf("Found timeseries without metric name label: %v", series.metric) - } else { - metricSet[string(metricName)] = true + if value, ok := series.metric[labelName]; ok { + valueSet[value] = true } } - for metricName := range metricSet { - metrics = append(metrics, metricName) + for value := range valueSet { + values = append(values, value) } - sort.Strings(metrics) + sort.Sort(values) return } diff --git a/storage/metric/tiered.go b/storage/metric/tiered.go index 28517f572..a5212aa57 100644 --- a/storage/metric/tiered.go +++ b/storage/metric/tiered.go @@ -64,7 +64,7 @@ type Storage interface { Close() // MetricPersistence proxy methods. - GetAllMetricNames() ([]string, error) + GetAllValuesForLabel(model.LabelName) (model.LabelValues, error) GetFingerprintsForLabelSet(model.LabelSet) (model.Fingerprints, error) GetMetricForFingerprint(model.Fingerprint) (m *model.Metric, err error) } @@ -518,24 +518,24 @@ func (t *tieredStorage) loadChunkAroundTime(iterator leveldb.Iterator, frontier return } -func (t *tieredStorage) GetAllMetricNames() (metrics []string, err error) { - diskMetrics, err := t.diskStorage.GetAllMetricNames() +func (t *tieredStorage) GetAllValuesForLabel(labelName model.LabelName) (values model.LabelValues, err error) { + diskValues, err := t.diskStorage.GetAllValuesForLabel(labelName) if err != nil { return } - memoryMetrics, err := t.memoryArena.GetAllMetricNames() + memoryValues, err := t.memoryArena.GetAllValuesForLabel(labelName) if err != nil { return } - metricSet := map[string]bool{} - for _, metricName := range append(diskMetrics, memoryMetrics...) { - metricSet[metricName] = true + valueSet := map[model.LabelValue]bool{} + for _, value := range append(diskValues, memoryValues...) { + valueSet[value] = true } - for metricName := range metricSet { - metrics = append(metrics, metricName) + for value := range valueSet { + values = append(values, value) } - sort.Strings(metrics) + sort.Sort(values) return } diff --git a/storage/metric/tiered_test.go b/storage/metric/tiered_test.go index e5a8c36d1..ab01f7c71 100644 --- a/storage/metric/tiered_test.go +++ b/storage/metric/tiered_test.go @@ -431,7 +431,7 @@ func BenchmarkMakeView(b *testing.B) { } } -func TestGetAllMetricNames(t *testing.T) { +func TestGetAllValuesForLabel(t *testing.T) { type in struct { metricName string appendToMemory bool @@ -510,7 +510,7 @@ func TestGetAllMetricNames(t *testing.T) { } } } - metricNames, err := tiered.GetAllMetricNames() + metricNames, err := tiered.GetAllValuesForLabel("name") if err != nil { t.Fatalf("%d. Error getting metric names: %s", i, err) } @@ -519,7 +519,7 @@ func TestGetAllMetricNames(t *testing.T) { } for j, expected := range scenario.out { - if expected != metricNames[j] { + if expected != string(metricNames[j]) { t.Fatalf("%d.%d. Expected metric %s, got %s", i, j, expected, metricNames[j]) } } diff --git a/web/api/query.go b/web/api/query.go index eb9e27dcc..b65f9bd9d 100644 --- a/web/api/query.go +++ b/web/api/query.go @@ -86,7 +86,7 @@ func (serv MetricsService) QueryRange(expr string, end int64, duration int64, st } func (serv MetricsService) Metrics() string { - metricNames, err := serv.appState.Storage.GetAllMetricNames() + metricNames, err := serv.appState.Storage.GetAllValuesForLabel("name") rb := serv.ResponseBuilder() rb.SetContentType(gorest.Application_Json) if err != nil { @@ -94,7 +94,7 @@ func (serv MetricsService) Metrics() string { rb.SetResponseCode(http.StatusInternalServerError) return err.Error() } - sort.Strings(metricNames) + sort.Sort(metricNames) resultBytes, err := json.Marshal(metricNames) if err != nil { log.Printf("Error marshalling metric names: %v", err)