فهرست منبع

feat(testdata): added csv test data scenario

Torkel Ödegaard 9 سال پیش
والد
کامیت
a4648607bb

+ 1 - 0
pkg/api/metrics.go

@@ -48,6 +48,7 @@ func GetTestDataScenarios(c *middleware.Context) Response {
 			"id":          scenario.Id,
 			"id":          scenario.Id,
 			"name":        scenario.Name,
 			"name":        scenario.Name,
 			"description": scenario.Description,
 			"description": scenario.Description,
+			"stringInput": scenario.StringInput,
 		})
 		})
 	}
 	}
 
 

+ 1 - 1
pkg/tsdb/graphite/graphite.go

@@ -79,7 +79,7 @@ func (e *GraphiteExecutor) Execute(queries tsdb.QuerySlice, context *tsdb.QueryC
 	}
 	}
 
 
 	result.QueryResults = make(map[string]*tsdb.QueryResult)
 	result.QueryResults = make(map[string]*tsdb.QueryResult)
-	queryRes := &tsdb.QueryResult{}
+	queryRes := tsdb.NewQueryResult()
 
 
 	for _, series := range data {
 	for _, series := range data {
 		queryRes.Series = append(queryRes.Series, &tsdb.TimeSeries{
 		queryRes.Series = append(queryRes.Series, &tsdb.TimeSeries{

+ 6 - 0
pkg/tsdb/models.go

@@ -66,6 +66,12 @@ type TimePoint [2]null.Float
 type TimeSeriesPoints []TimePoint
 type TimeSeriesPoints []TimePoint
 type TimeSeriesSlice []*TimeSeries
 type TimeSeriesSlice []*TimeSeries
 
 
+func NewQueryResult() *QueryResult {
+	return &QueryResult{
+		Series: make(TimeSeriesSlice, 0),
+	}
+}
+
 func NewTimePoint(value float64, timestamp float64) TimePoint {
 func NewTimePoint(value float64, timestamp float64) TimePoint {
 	return TimePoint{null.FloatFrom(value), null.FloatFrom(timestamp)}
 	return TimePoint{null.FloatFrom(value), null.FloatFrom(timestamp)}
 }
 }

+ 1 - 1
pkg/tsdb/prometheus/prometheus.go

@@ -132,7 +132,7 @@ func parseQuery(queries tsdb.QuerySlice, queryContext *tsdb.QueryContext) (*Prom
 
 
 func parseResponse(value pmodel.Value, query *PrometheusQuery) (map[string]*tsdb.QueryResult, error) {
 func parseResponse(value pmodel.Value, query *PrometheusQuery) (map[string]*tsdb.QueryResult, error) {
 	queryResults := make(map[string]*tsdb.QueryResult)
 	queryResults := make(map[string]*tsdb.QueryResult)
-	queryRes := &tsdb.QueryResult{}
+	queryRes := tsdb.NewQueryResult()
 
 
 	data, ok := value.(pmodel.Matrix)
 	data, ok := value.(pmodel.Matrix)
 	if !ok {
 	if !ok {

+ 47 - 8
pkg/tsdb/testdata/scenarios.go

@@ -2,8 +2,11 @@ package testdata
 
 
 import (
 import (
 	"math/rand"
 	"math/rand"
+	"strconv"
+	"strings"
 	"time"
 	"time"
 
 
+	"github.com/grafana/grafana/pkg/log"
 	"github.com/grafana/grafana/pkg/tsdb"
 	"github.com/grafana/grafana/pkg/tsdb"
 )
 )
 
 
@@ -12,6 +15,7 @@ type ScenarioHandler func(query *tsdb.Query, context *tsdb.QueryContext) *tsdb.Q
 type Scenario struct {
 type Scenario struct {
 	Id          string          `json:"id"`
 	Id          string          `json:"id"`
 	Name        string          `json:"name"`
 	Name        string          `json:"name"`
+	StringInput string          `json:"stringOption"`
 	Description string          `json:"description"`
 	Description string          `json:"description"`
 	Handler     ScenarioHandler `json:"-"`
 	Handler     ScenarioHandler `json:"-"`
 }
 }
@@ -20,15 +24,17 @@ var ScenarioRegistry map[string]*Scenario
 
 
 func init() {
 func init() {
 	ScenarioRegistry = make(map[string]*Scenario)
 	ScenarioRegistry = make(map[string]*Scenario)
-	//logger := log.New("tsdb.testdata")
+	logger := log.New("tsdb.testdata")
+
+	logger.Debug("Initializing TestData Scenario")
 
 
 	registerScenario(&Scenario{
 	registerScenario(&Scenario{
 		Id:   "random_walk",
 		Id:   "random_walk",
 		Name: "Random Walk",
 		Name: "Random Walk",
 
 
 		Handler: func(query *tsdb.Query, context *tsdb.QueryContext) *tsdb.QueryResult {
 		Handler: func(query *tsdb.Query, context *tsdb.QueryContext) *tsdb.QueryResult {
-			to := context.TimeRange.MustGetTo().UnixNano() / int64(time.Millisecond)
-			timeWalkerMs := context.TimeRange.MustGetFrom().UnixNano() / int64(time.Millisecond)
+			timeWalkerMs := context.TimeRange.GetFromAsMsEpoch()
+			to := context.TimeRange.GetToAsMsEpoch()
 
 
 			series := newSeriesForQuery(query)
 			series := newSeriesForQuery(query)
 
 
@@ -44,7 +50,7 @@ func init() {
 
 
 			series.Points = points
 			series.Points = points
 
 
-			queryRes := &tsdb.QueryResult{}
+			queryRes := tsdb.NewQueryResult()
 			queryRes.Series = append(queryRes.Series, series)
 			queryRes.Series = append(queryRes.Series, series)
 			return queryRes
 			return queryRes
 		},
 		},
@@ -54,9 +60,7 @@ func init() {
 		Id:   "no_data_points",
 		Id:   "no_data_points",
 		Name: "No Data Points",
 		Name: "No Data Points",
 		Handler: func(query *tsdb.Query, context *tsdb.QueryContext) *tsdb.QueryResult {
 		Handler: func(query *tsdb.Query, context *tsdb.QueryContext) *tsdb.QueryResult {
-			return &tsdb.QueryResult{
-				Series: make(tsdb.TimeSeriesSlice, 0),
-			}
+			return tsdb.NewQueryResult()
 		},
 		},
 	})
 	})
 
 
@@ -64,7 +68,7 @@ func init() {
 		Id:   "datapoints_outside_range",
 		Id:   "datapoints_outside_range",
 		Name: "Datapoints Outside Range",
 		Name: "Datapoints Outside Range",
 		Handler: func(query *tsdb.Query, context *tsdb.QueryContext) *tsdb.QueryResult {
 		Handler: func(query *tsdb.Query, context *tsdb.QueryContext) *tsdb.QueryResult {
-			queryRes := &tsdb.QueryResult{}
+			queryRes := tsdb.NewQueryResult()
 
 
 			series := newSeriesForQuery(query)
 			series := newSeriesForQuery(query)
 			outsideTime := context.TimeRange.MustGetFrom().Add(-1*time.Hour).Unix() * 1000
 			outsideTime := context.TimeRange.MustGetFrom().Add(-1*time.Hour).Unix() * 1000
@@ -75,6 +79,41 @@ func init() {
 			return queryRes
 			return queryRes
 		},
 		},
 	})
 	})
+
+	registerScenario(&Scenario{
+		Id:          "csv_metric_values",
+		Name:        "CSV Metric Values",
+		StringInput: "1,20,90,30,5,0",
+		Handler: func(query *tsdb.Query, context *tsdb.QueryContext) *tsdb.QueryResult {
+			queryRes := tsdb.NewQueryResult()
+
+			stringInput := query.Model.Get("stringInput").MustString()
+			values := []float64{}
+			for _, strVal := range strings.Split(stringInput, ",") {
+				if val, err := strconv.ParseFloat(strVal, 64); err == nil {
+					values = append(values, val)
+				}
+			}
+
+			if len(values) == 0 {
+				return queryRes
+			}
+
+			series := newSeriesForQuery(query)
+			startTime := context.TimeRange.GetFromAsMsEpoch()
+			endTime := context.TimeRange.GetToAsMsEpoch()
+			step := (endTime - startTime) / int64(len(values)-1)
+
+			for _, val := range values {
+				series.Points = append(series.Points, tsdb.NewTimePoint(val, float64(startTime)))
+				startTime += step
+			}
+
+			queryRes.Series = append(queryRes.Series, series)
+
+			return queryRes
+		},
+	})
 }
 }
 
 
 func registerScenario(scenario *Scenario) {
 func registerScenario(scenario *Scenario) {

+ 8 - 0
pkg/tsdb/time_range.go

@@ -21,6 +21,14 @@ type TimeRange struct {
 	Now  time.Time
 	Now  time.Time
 }
 }
 
 
+func (tr *TimeRange) GetFromAsMsEpoch() int64 {
+	return tr.MustGetFrom().UnixNano() / int64(time.Millisecond)
+}
+
+func (tr *TimeRange) GetToAsMsEpoch() int64 {
+	return tr.MustGetTo().UnixNano() / int64(time.Millisecond)
+}
+
 func (tr *TimeRange) MustGetFrom() time.Time {
 func (tr *TimeRange) MustGetFrom() time.Time {
 	if res, err := tr.ParseFrom(); err != nil {
 	if res, err := tr.ParseFrom(); err != nil {
 		return time.Unix(0, 0)
 		return time.Unix(0, 0)

+ 286 - 0
public/app/plugins/app/testdata/dashboards/alerts.json

@@ -0,0 +1,286 @@
+{
+  "title": "TestData - Alerts",
+  "tags": [
+    "grafana-test"
+  ],
+  "style": "dark",
+  "timezone": "browser",
+  "editable": true,
+  "hideControls": false,
+  "sharedCrosshair": false,
+  "rows": [
+    {
+      "collapse": false,
+      "editable": true,
+      "height": 255.625,
+      "panels": [
+        {
+          "alert": {
+            "conditions": [
+              {
+                "evaluator": {
+                  "params": [
+                    111
+                  ],
+                  "type": "gt"
+                },
+                "query": {
+                  "params": [
+                    "A",
+                    "5m",
+                    "now"
+                  ]
+                },
+                "reducer": {
+                  "params": [],
+                  "type": "avg"
+                },
+                "type": "query"
+              }
+            ],
+            "enabled": true,
+            "frequency": "60s",
+            "handler": 1,
+            "name": "Should always be green",
+            "noDataState": "no_data",
+            "notifications": []
+          },
+          "aliasColors": {},
+          "bars": false,
+          "datasource": "Grafana TestData",
+          "editable": true,
+          "error": false,
+          "fill": 1,
+          "id": 3,
+          "isNew": true,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 2,
+          "links": [],
+          "nullPointMode": "connected",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "span": 6,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "refId": "A",
+              "scenario": "random_walk",
+              "scenarioId": "csv_metric_values",
+              "target": "",
+              "stringInput": "1,20,90,30,5,0"
+            }
+          ],
+          "thresholds": [
+            {
+              "colorMode": "critical",
+              "fill": true,
+              "line": true,
+              "op": "gt",
+              "value": 111
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Always OK",
+          "tooltip": {
+            "msResolution": false,
+            "shared": true,
+            "sort": 0,
+            "value_type": "cumulative"
+          },
+          "type": "graph",
+          "xaxis": {
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": "",
+              "logBase": 1,
+              "max": "125",
+              "min": "0",
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ]
+        },
+        {
+          "alert": {
+            "conditions": [
+              {
+                "evaluator": {
+                  "params": [
+                    177
+                  ],
+                  "type": "gt"
+                },
+                "query": {
+                  "params": [
+                    "A",
+                    "5m",
+                    "now"
+                  ]
+                },
+                "reducer": {
+                  "params": [],
+                  "type": "avg"
+                },
+                "type": "query"
+              }
+            ],
+            "enabled": true,
+            "frequency": "60s",
+            "handler": 1,
+            "name": "Always Alerting",
+            "noDataState": "no_data",
+            "notifications": []
+          },
+          "aliasColors": {},
+          "bars": false,
+          "datasource": "Grafana TestData",
+          "editable": true,
+          "error": false,
+          "fill": 1,
+          "id": 4,
+          "isNew": true,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 2,
+          "links": [],
+          "nullPointMode": "connected",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "span": 6,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "refId": "A",
+              "scenario": "random_walk",
+              "scenarioId": "csv_metric_values",
+              "target": "",
+              "stringInput": "200,445,100,150,200,220,190"
+            }
+          ],
+          "thresholds": [
+            {
+              "value": 177,
+              "op": "gt",
+              "fill": true,
+              "line": true,
+              "colorMode": "critical"
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Always Alerting",
+          "tooltip": {
+            "msResolution": false,
+            "shared": true,
+            "sort": 0,
+            "value_type": "cumulative"
+          },
+          "type": "graph",
+          "xaxis": {
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": "0",
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ]
+        }
+      ],
+      "title": "New row"
+    }
+  ],
+  "time": {
+    "from": "now-6h",
+    "to": "now"
+  },
+  "timepicker": {
+    "refresh_intervals": [
+      "5s",
+      "10s",
+      "30s",
+      "1m",
+      "5m",
+      "15m",
+      "30m",
+      "1h",
+      "2h",
+      "1d"
+    ],
+    "time_options": [
+      "5m",
+      "15m",
+      "1h",
+      "6h",
+      "12h",
+      "24h",
+      "2d",
+      "7d",
+      "30d"
+    ]
+  },
+  "templating": {
+    "list": []
+  },
+  "annotations": {
+    "list": []
+  },
+  "schemaVersion": 13,
+  "version": 10,
+  "links": [],
+  "gnetId": null
+}

+ 120 - 3
public/app/plugins/app/testdata/dashboards/graph_last_1h.json

@@ -1,5 +1,5 @@
 {
 {
-  "revision": 3,
+  "revision": 4,
   "title": "TestData - Graph Panel Last 1h",
   "title": "TestData - Graph Panel Last 1h",
   "tags": [
   "tags": [
     "grafana-test"
     "grafana-test"
@@ -284,7 +284,7 @@
             }
             }
           ],
           ],
           "thresholds": [],
           "thresholds": [],
-          "timeFrom": "5d",
+          "timeFrom": "2s",
           "timeShift": null,
           "timeShift": null,
           "title": "Millisecond res x-axis and tooltip",
           "title": "Millisecond res x-axis and tooltip",
           "tooltip": {
           "tooltip": {
@@ -318,9 +318,126 @@
               "show": true
               "show": true
             }
             }
           ]
           ]
+        },
+        {
+          "title": "",
+          "error": false,
+          "span": 4,
+          "editable": true,
+          "type": "text",
+          "isNew": true,
+          "id": 6,
+          "mode": "markdown",
+          "content": "Just verify that the tooltip time has millisecond resolution ",
+          "links": []
         }
         }
       ],
       ],
       "title": "New row"
       "title": "New row"
+    },
+    {
+      "title": "New row",
+      "height": 336,
+      "editable": true,
+      "collapse": false,
+      "panels": [
+        {
+          "title": "2 yaxis and axis lables",
+          "error": false,
+          "span": 7.99561403508772,
+          "editable": true,
+          "type": "graph",
+          "isNew": true,
+          "id": 5,
+          "targets": [
+            {
+              "target": "",
+              "refId": "A",
+              "scenarioId": "csv_metric_values",
+              "stringInput": "1,20,90,30,5,0"
+            },
+            {
+              "target": "",
+              "refId": "B",
+              "scenarioId": "csv_metric_values",
+              "stringInput": "2000,3000,4000,1000,3000,10000"
+            }
+          ],
+          "datasource": "Grafana TestData",
+          "renderer": "flot",
+          "yaxes": [
+            {
+              "label": "Perecent",
+              "show": true,
+              "logBase": 1,
+              "min": null,
+              "max": null,
+              "format": "percent"
+            },
+            {
+              "label": "Pressure",
+              "show": true,
+              "logBase": 1,
+              "min": null,
+              "max": null,
+              "format": "short"
+            }
+          ],
+          "xaxis": {
+            "show": true,
+            "mode": "time",
+            "name": null,
+            "values": []
+          },
+          "lines": true,
+          "fill": 1,
+          "linewidth": 2,
+          "points": false,
+          "pointradius": 5,
+          "bars": false,
+          "stack": false,
+          "percentage": false,
+          "legend": {
+            "show": true,
+            "values": false,
+            "min": false,
+            "max": false,
+            "current": false,
+            "total": false,
+            "avg": false
+          },
+          "nullPointMode": "connected",
+          "steppedLine": false,
+          "tooltip": {
+            "value_type": "cumulative",
+            "shared": true,
+            "sort": 0,
+            "msResolution": false
+          },
+          "timeFrom": null,
+          "timeShift": null,
+          "aliasColors": {},
+          "seriesOverrides": [
+            {
+              "alias": "B-series",
+              "yaxis": 2
+            }
+          ],
+          "thresholds": [],
+          "links": []
+        },
+        {
+          "title": "",
+          "error": false,
+          "span": 4.00438596491228,
+          "editable": true,
+          "type": "text",
+          "isNew": true,
+          "id": 7,
+          "mode": "markdown",
+          "content": "Verify that axis labels look ok",
+          "links": []
+        }
+      ]
     }
     }
   ],
   ],
   "time": {
   "time": {
@@ -360,7 +477,7 @@
   },
   },
   "refresh": false,
   "refresh": false,
   "schemaVersion": 13,
   "schemaVersion": 13,
-  "version": 4,
+  "version": 3,
   "links": [],
   "links": [],
   "gnetId": null
   "gnetId": null
 }
 }

+ 3 - 0
public/app/plugins/app/testdata/datasource/datasource.ts

@@ -1,6 +1,7 @@
 ///<reference path="../../../../headers/common.d.ts" />
 ///<reference path="../../../../headers/common.d.ts" />
 
 
 import _ from 'lodash';
 import _ from 'lodash';
+import angular from 'angular';
 
 
 class TestDataDatasource {
 class TestDataDatasource {
 
 
@@ -16,6 +17,8 @@ class TestDataDatasource {
         scenarioId: item.scenarioId,
         scenarioId: item.scenarioId,
         intervalMs: options.intervalMs,
         intervalMs: options.intervalMs,
         maxDataPoints: options.maxDataPoints,
         maxDataPoints: options.maxDataPoints,
+        stringInput: item.stringInput,
+        jsonInput: angular.fromJson(item.jsonInput),
       };
       };
     });
     });
 
 

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

@@ -1,5 +1,7 @@
 ///<reference path="../../../../headers/common.d.ts" />
 ///<reference path="../../../../headers/common.d.ts" />
 
 
+import _ from 'lodash';
+
 import {TestDataDatasource} from './datasource';
 import {TestDataDatasource} from './datasource';
 import {QueryCtrl} from 'app/plugins/sdk';
 import {QueryCtrl} from 'app/plugins/sdk';
 
 
@@ -7,6 +9,7 @@ export class TestDataQueryCtrl extends QueryCtrl {
   static templateUrl = 'partials/query.editor.html';
   static templateUrl = 'partials/query.editor.html';
 
 
   scenarioList: any;
   scenarioList: any;
+  scenario: any;
 
 
   /** @ngInject **/
   /** @ngInject **/
   constructor($scope, $injector, private backendSrv) {
   constructor($scope, $injector, private backendSrv) {
@@ -19,7 +22,14 @@ export class TestDataQueryCtrl extends QueryCtrl {
   $onInit() {
   $onInit() {
     return this.backendSrv.get('/api/tsdb/testdata/scenarios').then(res => {
     return this.backendSrv.get('/api/tsdb/testdata/scenarios').then(res => {
       this.scenarioList = res;
       this.scenarioList = res;
+      this.scenario = _.find(this.scenarioList, {id: this.target.scenarioId});
     });
     });
   }
   }
+
+  scenarioChanged() {
+    this.scenario = _.find(this.scenarioList, {id: this.target.scenarioId});
+    this.target.stringInput = this.scenario.stringInput;
+    this.refresh();
+  }
 }
 }
 
 

+ 6 - 6
public/app/plugins/app/testdata/partials/query.editor.html

@@ -2,17 +2,17 @@
 	<div class="gf-form-inline">
 	<div class="gf-form-inline">
 		<div class="gf-form">
 		<div class="gf-form">
 			<label class="gf-form-label query-keyword">Scenario</label>
 			<label class="gf-form-label query-keyword">Scenario</label>
-			<div class="gf-form-select-wrapper width-25">
-				<select class="gf-form-input width-25" ng-model="ctrl.target.scenarioId" ng-options="v.id as v.name for v in ctrl.scenarioList" ng-change="ctrl.refresh()"></select>
+			<div class="gf-form-select-wrapper">
+				<select class="gf-form-input" ng-model="ctrl.target.scenarioId" ng-options="v.id as v.name for v in ctrl.scenarioList" ng-change="ctrl.scenarioChanged()"></select>
 			</div>
 			</div>
 		</div>
 		</div>
-		<div class="gf-form">
-			<label class="gf-form-label query-keyword">With Options</label>
-			<input type="text" class="gf-form-input max-width-7" placeholder="optional" ng-model="target.param1" ng-change="ctrl.refresh()" ng-model-onblur>
+		<div class="gf-form gf-form gf-form--grow" ng-if="ctrl.scenario.stringInput">
+			<label class="gf-form-label query-keyword">String Input</label>
+      <input type="text" class="gf-form-input" placeholder="{{ctrl.scenario.stringInput}}" ng-model="ctrl.target.stringInput" ng-change="ctrl.refresh()" ng-model-onblur>
 		</div>
 		</div>
 		<div class="gf-form">
 		<div class="gf-form">
 			<label class="gf-form-label query-keyword">Alias</label>
 			<label class="gf-form-label query-keyword">Alias</label>
-			<input type="text" class="gf-form-input max-width-7" placeholder="optional" ng-model="target.alias" ng-change="ctrl.refresh()" ng-model-onblur>
+			<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>
 		<div class="gf-form gf-form--grow">
 		<div class="gf-form gf-form--grow">
 			<div class="gf-form-label gf-form-label--grow"></div>
 			<div class="gf-form-label gf-form-label--grow"></div>

+ 1 - 1
public/app/plugins/app/testdata/plugin.json

@@ -9,7 +9,7 @@
       "name": "Grafana Project",
       "name": "Grafana Project",
       "url": "http://grafana.org"
       "url": "http://grafana.org"
     },
     },
-    "version": "1.0.6",
+    "version": "1.0.7",
     "updated": "2016-09-26"
     "updated": "2016-09-26"
   },
   },