浏览代码

stackdriver: populate alignment and aggregation dropdowns based on metric type and value type

Erik Sundell 7 年之前
父节点
当前提交
b700c6b0e4

+ 3 - 0
pkg/tsdb/stackdriver/stackdriver.go

@@ -299,6 +299,9 @@ func (e *StackdriverExecutor) parseResponse(queryRes *tsdb.QueryResult, data Sta
 			Name:   metricName,
 			Points: points,
 		})
+
+		queryRes.Meta.Set("metricKind", series.MetricKind)
+		queryRes.Meta.Set("valueType", series.ValueType)
 	}
 
 	queryRes.Meta.Set("resourceLabels", resourceLabels)

+ 238 - 30
public/app/plugins/datasource/stackdriver/constants.ts

@@ -1,37 +1,245 @@
+export enum MetricKind {
+  METRIC_KIND_UNSPECIFIED = 'METRIC_KIND_UNSPECIFIED',
+  GAUGE = 'GAUGE',
+  DELTA = 'DELTA',
+  CUMULATIVE = 'CUMULATIVE',
+}
+
+export enum ValueTypes {
+  VALUE_TYPE_UNSPECIFIED = 'VALUE_TYPE_UNSPECIFIED',
+  BOOL = 'BOOL',
+  INT64 = 'INT64',
+  DOUBLE = 'DOUBLE',
+  STRING = 'STRING',
+  DISTRIBUTION = 'DISTRIBUTION',
+  MONEY = 'MONEY',
+}
+
 export const alignOptions = [
-  { text: 'none', value: 'ALIGN_NONE' },
-  { text: 'delta', value: 'ALIGN_DELTA' },
-  { text: 'rate', value: 'ALIGN_RATE' },
-  { text: 'interpolate', value: 'ALIGN_INTERPOLATE' },
-  { text: 'next older', value: 'ALIGN_NEXT_OLDER' },
-  { text: 'min', value: 'ALIGN_MIN' },
-  { text: 'max', value: 'ALIGN_MAX' },
-  { text: 'mean', value: 'ALIGN_MEAN' },
-  { text: 'count', value: 'ALIGN_COUNT' },
-  { text: 'sum', value: 'ALIGN_SUM' },
-  { text: 'stddev', value: 'ALIGN_STDDEV' },
-  { text: 'count true', value: 'ALIGN_COUNT_TRUE' },
-  { text: 'count false', value: 'ALIGN_COUNT_FALSE' },
-  { text: 'fraction true', value: 'ALIGN_FRACTION_TRUE' },
-  { text: 'percentile 99', value: 'ALIGN_PERCENTILE_99' },
-  { text: 'percentile 95', value: 'ALIGN_PERCENTILE_95' },
-  { text: 'percentile 50', value: 'ALIGN_PERCENTILE_50' },
-  { text: 'percentile 05', value: 'ALIGN_PERCENTILE_05' },
-  { text: 'percent change', value: 'ALIGN_PERCENT_CHANGE' },
+  {
+    text: 'none',
+    value: 'ALIGN_NONE',
+    valueTypes: [
+      ValueTypes.INT64,
+      ValueTypes.DOUBLE,
+      ValueTypes.MONEY,
+      ValueTypes.DISTRIBUTION,
+      ValueTypes.BOOL,
+      ValueTypes.STRING,
+    ],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE, MetricKind.METRIC_KIND_UNSPECIFIED],
+  },
+  {
+    text: 'delta',
+    value: 'ALIGN_DELTA',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.CUMULATIVE, MetricKind.DELTA],
+  },
+  {
+    text: 'rate',
+    value: 'ALIGN_RATE',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.CUMULATIVE, MetricKind.DELTA],
+  },
+  {
+    text: 'interpolate',
+    value: 'ALIGN_INTERPOLATE',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.GAUGE],
+  },
+  {
+    text: 'next older',
+    value: 'ALIGN_NEXT_OLDER',
+    valueTypes: [
+      ValueTypes.INT64,
+      ValueTypes.DOUBLE,
+      ValueTypes.MONEY,
+      ValueTypes.DISTRIBUTION,
+      ValueTypes.STRING,
+      ValueTypes.VALUE_TYPE_UNSPECIFIED,
+      ValueTypes.BOOL,
+    ],
+    metricKinds: [MetricKind.GAUGE],
+  },
+  {
+    text: 'min',
+    value: 'ALIGN_MIN',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'max',
+    value: 'ALIGN_MAX',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'mean',
+    value: 'ALIGN_MEAN',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'count',
+    value: 'ALIGN_COUNT',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.BOOL],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'sum',
+    value: 'ALIGN_SUM',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'stddev',
+    value: 'ALIGN_STDDEV',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'count true',
+    value: 'ALIGN_COUNT_TRUE',
+    valueTypes: [ValueTypes.BOOL],
+    metricKinds: [MetricKind.GAUGE],
+  },
+  {
+    text: 'count false',
+    value: 'ALIGN_COUNT_FALSE',
+    valueTypes: [ValueTypes.BOOL],
+    metricKinds: [MetricKind.GAUGE],
+  },
+  {
+    text: 'fraction true',
+    value: 'ALIGN_FRACTION_TRUE',
+    valueTypes: [ValueTypes.BOOL],
+    metricKinds: [MetricKind.GAUGE],
+  },
+  {
+    text: 'percentile 99',
+    value: 'ALIGN_PERCENTILE_99',
+    valueTypes: [ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'percentile 95',
+    value: 'ALIGN_PERCENTILE_95',
+    valueTypes: [ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'percentile 50',
+    value: 'ALIGN_PERCENTILE_50',
+    valueTypes: [ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'percentile 05',
+    value: 'ALIGN_PERCENTILE_05',
+    valueTypes: [ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'percent change',
+    value: 'ALIGN_PERCENT_CHANGE',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
 ];
 
 export const aggOptions = [
-  { text: 'none', value: 'REDUCE_NONE' },
-  { text: 'mean', value: 'REDUCE_MEAN' },
-  { text: 'min', value: 'REDUCE_MIN' },
-  { text: 'max', value: 'REDUCE_MAX' },
-  { text: 'sum', value: 'REDUCE_SUM' },
-  { text: 'std. dev.', value: 'REDUCE_STDDEV' },
-  { text: 'count', value: 'REDUCE_COUNT' },
-  { text: '99th percentile', value: 'REDUCE_PERCENTILE_99' },
-  { text: '95th percentile', value: 'REDUCE_PERCENTILE_95' },
-  { text: '50th percentile', value: 'REDUCE_PERCENTILE_50' },
-  { text: '5th percentile', value: 'REDUCE_PERCENTILE_05' },
+  {
+    text: 'none',
+    value: 'REDUCE_NONE',
+    valueTypes: [
+      ValueTypes.INT64,
+      ValueTypes.DOUBLE,
+      ValueTypes.MONEY,
+      ValueTypes.DISTRIBUTION,
+      ValueTypes.BOOL,
+      ValueTypes.STRING,
+    ],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA, MetricKind.CUMULATIVE, MetricKind.METRIC_KIND_UNSPECIFIED],
+  },
+  {
+    text: 'mean',
+    value: 'REDUCE_MEAN',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'min',
+    value: 'REDUCE_MIN',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'max',
+    value: 'REDUCE_MAX',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'sum',
+    value: 'REDUCE_SUM',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'std. dev.',
+    value: 'REDUCE_STDDEV',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'count',
+    value: 'REDUCE_COUNT',
+    valueTypes: [
+      ValueTypes.INT64,
+      ValueTypes.DOUBLE,
+      ValueTypes.MONEY,
+      ValueTypes.DISTRIBUTION,
+      ValueTypes.BOOL,
+      ValueTypes.STRING,
+    ],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'count',
+    value: 'REDUCE_COUNT_TRUE',
+    valueTypes: [ValueTypes.BOOL],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: 'count',
+    value: 'REDUCE_COUNT_FALSE',
+    valueTypes: [ValueTypes.BOOL],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: '99th percentile',
+    value: 'REDUCE_PERCENTILE_99',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: '95th percentile',
+    value: 'REDUCE_PERCENTILE_95',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: '50th percentile',
+    value: 'REDUCE_PERCENTILE_50',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
+  {
+    text: '5th percentile',
+    value: 'REDUCE_PERCENTILE_05',
+    valueTypes: [ValueTypes.INT64, ValueTypes.DOUBLE, ValueTypes.MONEY, ValueTypes.DISTRIBUTION],
+    metricKinds: [MetricKind.GAUGE, MetricKind.DELTA],
+  },
 ];
 
 export const alignmentPeriods = [

+ 7 - 7
public/app/plugins/datasource/stackdriver/partials/query.editor.html

@@ -2,8 +2,8 @@
   <div class="gf-form-inline">
     <div class="gf-form">
       <span class="gf-form-label width-9">Metric Type</span>
-      <gf-form-dropdown model="ctrl.target.metricType" get-options="ctrl.getMetricTypes($query)" class="min-width-20" disabled
-        type="text" allow-custom="true" lookup-text="true" css-class="min-width-12" on-change="ctrl.onMetricTypeChange()"></gf-form-dropdown>
+      <gf-form-dropdown model="ctrl.target.metricType" get-options="ctrl.getMetricTypes($query)" class="min-width-20"
+        disabled type="text" allow-custom="true" lookup-text="true" css-class="min-width-12" on-change="ctrl.onMetricTypeChange()"></gf-form-dropdown>
     </div>
     <div class="gf-form gf-form--grow">
       <div class="gf-form-label gf-form-label--grow"></div>
@@ -35,7 +35,7 @@
     <div class="gf-form">
       <label class="gf-form-label query-keyword width-9">Aggregation</label>
       <div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent">
-        <select class="gf-form-input width-12" ng-model="ctrl.target.aggregation.crossSeriesReducer" ng-options="f.value as f.text for f in ctrl.stackdriverConstants.aggOptions"
+        <select class="gf-form-input width-12" ng-model="ctrl.target.aggregation.crossSeriesReducer" ng-options="f.value as f.text for f in ctrl.getAggOptions()"
           ng-change="ctrl.refresh()"></select>
       </div>
     </div>
@@ -53,7 +53,7 @@
     <div class="gf-form offset-width-9">
       <label class="gf-form-label query-keyword width-12">Aligner</label>
       <div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent">
-        <select class="gf-form-input width-14" ng-model="ctrl.target.aggregation.perSeriesAligner" ng-options="f.value as f.text for f in ctrl.stackdriverConstants.alignOptions"
+        <select class="gf-form-input width-14" ng-model="ctrl.target.aggregation.perSeriesAligner" ng-options="f.value as f.text for f in ctrl.getAlignOptions()"
           ng-change="ctrl.refresh()"></select>
       </div>
 
@@ -85,8 +85,8 @@
   <div class="gf-form-inline">
     <div class="gf-form">
       <span class="gf-form-label width-9">Project</span>
-      <input class="gf-form-input" disabled type="text" ng-model='ctrl.target.project.name' get-options="ctrl.getProjects()" css-class="min-width-12"
-      />
+      <input class="gf-form-input" disabled type="text" ng-model='ctrl.target.project.name' get-options="ctrl.getProjects()"
+        css-class="min-width-12" />
     </div>
     <div class="gf-form">
       <label class="gf-form-label query-keyword" ng-click="ctrl.showHelp = !ctrl.showHelp">
@@ -130,4 +130,4 @@
   <div class="gf-form" ng-show="ctrl.lastQueryError">
     <pre class="gf-form-pre alert alert-error">{{ctrl.lastQueryError}}</pre>
   </div>
-</query-editor-row>
+</query-editor-row>

+ 35 - 1
public/app/plugins/datasource/stackdriver/query_ctrl.ts

@@ -28,6 +28,8 @@ export class StackdriverQueryCtrl extends QueryCtrl {
     };
     filters: string[];
     aliasBy: string;
+    metricKind: any;
+    valueType: any;
   };
   defaultDropdownValue = 'select metric';
   defaultRemoveGroupByValue = '-- remove group by --';
@@ -49,8 +51,12 @@ export class StackdriverQueryCtrl extends QueryCtrl {
     filters: [],
     showAggregationOptions: false,
     aliasBy: '',
+    metricKind: '',
+    valueType: '',
   };
 
+  alignOptions: any[];
+  aggOptions: any[];
   groupBySegments: any[];
   removeSegment: any;
   showHelp: boolean;
@@ -69,6 +75,8 @@ export class StackdriverQueryCtrl extends QueryCtrl {
     this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope);
     this.panelCtrl.events.on('data-error', this.onDataError.bind(this), $scope);
     this.stackdriverConstants = options;
+    this.aggOptions = options.aggOptions;
+    this.alignOptions = options.alignOptions;
 
     this.getCurrentProject()
       .then(this.getMetricTypes.bind(this))
@@ -256,6 +264,31 @@ export class StackdriverQueryCtrl extends QueryCtrl {
     }
   }
 
+  getAlignOptions() {
+    return !this.target.valueType
+      ? options.alignOptions
+      : options.alignOptions.filter(i => {
+          return (
+            i.valueTypes.indexOf(this.target.valueType) !== -1 && i.metricKinds.indexOf(this.target.metricKind) !== -1
+          );
+        });
+  }
+
+  getAggOptions() {
+    if (this.target.aggregation.perSeriesAligner === 'ALIGN_NONE') {
+      this.target.aggregation.crossSeriesReducer = options.aggOptions[0].value;
+      return options.aggOptions.slice(0, 1);
+    }
+
+    return !this.target.metricKind
+      ? options.aggOptions
+      : options.aggOptions.filter(i => {
+          return (
+            i.valueTypes.indexOf(this.target.valueType) !== -1 && i.metricKinds.indexOf(this.target.metricKind) !== -1
+          );
+        });
+  }
+
   onDataReceived(dataList) {
     this.lastQueryError = null;
     this.lastQueryMeta = null;
@@ -264,7 +297,8 @@ export class StackdriverQueryCtrl extends QueryCtrl {
     if (anySeriesFromQuery) {
       this.lastQueryMeta = anySeriesFromQuery.meta;
       this.lastQueryMeta.rawQueryString = decodeURIComponent(this.lastQueryMeta.rawQuery);
-    } else {
+      this.target.valueType = anySeriesFromQuery.meta.valueType;
+      this.target.metricKind = anySeriesFromQuery.meta.metricKind;
     }
   }