Преглед изворни кода

TestData: attach labels to series results (#18653)

Ryan McKinley пре 6 година
родитељ
комит
e6fbf358c8

+ 44 - 0
pkg/tsdb/testdata/scenarios.go

@@ -423,6 +423,7 @@ func getPredictablePulse(query *tsdb.Query, context *tsdb.TsdbQuery) *tsdb.Query
 	series := newSeriesForQuery(query)
 	series.Points = *points
 	queryRes.Series = append(queryRes.Series, series)
+	attachLabels(query, queryRes)
 	return queryRes
 }
 
@@ -472,6 +473,7 @@ func getPredictableCSVWave(query *tsdb.Query, context *tsdb.TsdbQuery) *tsdb.Que
 	series := newSeriesForQuery(query)
 	series.Points = *points
 	queryRes.Series = append(queryRes.Series, series)
+	attachLabels(query, queryRes)
 	return queryRes
 }
 
@@ -517,9 +519,51 @@ func getRandomWalk(query *tsdb.Query, tsdbQuery *tsdb.TsdbQuery) *tsdb.QueryResu
 
 	queryRes := tsdb.NewQueryResult()
 	queryRes.Series = append(queryRes.Series, series)
+	attachLabels(query, queryRes)
 	return queryRes
 }
 
+/**
+ * Looks for a labels request and adds them as tags
+ *
+ * '{job="foo", instance="bar"} => {job: "foo", instance: "bar"}`
+ */
+func attachLabels(query *tsdb.Query, queryRes *tsdb.QueryResult) {
+	labelText := query.Model.Get("labels").MustString("")
+	if labelText == "" {
+		return
+	}
+
+	tags := parseLabels(labelText)
+	for _, series := range queryRes.Series {
+		series.Tags = tags
+	}
+}
+
+// generous parser:
+// {job="foo", instance="bar"}
+// job="foo", instance="bar"
+// job=foo, instance=bar
+// should all equal {job=foo, instance=bar}
+
+func parseLabels(text string) map[string]string {
+	var tags map[string]string
+	text = strings.Trim(text, `{}`)
+	if len(text) < 2 {
+		return tags
+	}
+	tags = make(map[string]string)
+
+	for _, keyval := range strings.Split(text, ",") {
+		idx := strings.Index(keyval, "=")
+		key := strings.TrimSpace(keyval[:idx])
+		val := strings.TrimSpace(keyval[idx+1:])
+		tags[key] = val
+	}
+
+	return tags
+}
+
 func getRandomWalkTable(query *tsdb.Query, tsdbQuery *tsdb.TsdbQuery) *tsdb.QueryResult {
 	timeWalkerMs := tsdbQuery.TimeRange.GetFromAsMsEpoch()
 	to := tsdbQuery.TimeRange.GetToAsMsEpoch()

+ 13 - 0
pkg/tsdb/testdata/scenarios_test.go

@@ -92,3 +92,16 @@ func TestTestdataScenarios(t *testing.T) {
 		})
 	})
 }
+
+func TestToLabels(t *testing.T) {
+	Convey("read labels", t, func() {
+		tags := make(map[string]string)
+		tags["job"] = "foo"
+		tags["instance"] = "bar"
+
+		So(parseLabels(`{job="foo", instance="bar"}`), ShouldEqual, tags)
+		So(parseLabels(`job="foo", instance="bar"`), ShouldEqual, tags)
+		So(parseLabels(`job=foo, instance=bar`), ShouldEqual, tags)
+		So(parseLabels(`job = foo,instance = bar`), ShouldEqual, tags)
+	})
+}

+ 13 - 1
public/app/plugins/datasource/testdata/partials/query.editor.html

@@ -14,7 +14,19 @@
 			<label class="gf-form-label query-keyword">Alias</label>
 			<input type="text" class="gf-form-input max-width-7" placeholder="optional" ng-model="ctrl.target.alias" ng-change="ctrl.refresh()" ng-model-onblur>
 		</div>
-		<div class="gf-form gf-form--grow">
+		<div ng-if="ctrl.showLabels" class="gf-form gf-form--grow">
+			<label class="gf-form-label query-keyword">
+				Labels
+				<info-popover mode="right-normal">
+					Set labels using a key=value syntax:<br/>
+					{key="value", key2="value"}<br/>
+					key="value", key2="value"<br/>
+					key=value, key2=value<br/>
+				</info-popover>
+			</label>
+			<input type="text" class="gf-form-input gf-form--grow" placeholder='key=value, key2=value2' ng-model="ctrl.target.labels" ng-change="ctrl.refresh()" ng-model-onblur>
+		</div>
+		<div ng-if="!ctrl.showLabels" class="gf-form gf-form--grow">
 			<div class="gf-form-label gf-form-label--grow"></div>
 		</div>
 	</div>

+ 6 - 0
public/app/plugins/datasource/testdata/query_ctrl.ts

@@ -18,6 +18,8 @@ export const defaultCSVWave: any = {
   valuesCSV: '0,0,2,2,1,1',
 };
 
+const showLabelsFor = ['random_walk', 'predictable_pulse', 'predictable_csv_wave'];
+
 export class TestDataQueryCtrl extends QueryCtrl {
   static templateUrl = 'partials/query.editor.html';
 
@@ -27,6 +29,8 @@ export class TestDataQueryCtrl extends QueryCtrl {
   newPointTime: any;
   selectedPoint: any;
 
+  showLabels = false;
+
   /** @ngInject */
   constructor($scope: any, $injector: any) {
     super($scope, $injector);
@@ -35,6 +39,7 @@ export class TestDataQueryCtrl extends QueryCtrl {
     this.scenarioList = [];
     this.newPointTime = dateTime();
     this.selectedPoint = { text: 'Select point', value: null };
+    this.showLabels = showLabelsFor.includes(this.target.scenarioId);
   }
 
   getPoints() {
@@ -75,6 +80,7 @@ export class TestDataQueryCtrl extends QueryCtrl {
   scenarioChanged() {
     this.scenario = _.find(this.scenarioList, { id: this.target.scenarioId });
     this.target.stringInput = this.scenario.stringInput;
+    this.showLabels = showLabelsFor.includes(this.target.scenarioId);
 
     if (this.target.scenarioId === 'manual_entry') {
       this.target.points = this.target.points || [];