mirror of https://github.com/grafana/grafana.git
				
				
				
			Improvement and polish to the OpenTSDB query editor (Issue #492)
This commit is contained in:
		
						commit
						6885cea0fd
					
				|  | @ -14,6 +14,9 @@ | |||
| - Improvement to InfluxDB query editor and function/value column selection (Issue #473) | ||||
| - Initial support for filtering (templated queries) for InfluxDB (PR #375) - thx @mavimo | ||||
| - Row editing and adding new panel is now a lot quicker and easier with the new row menu (Issue #475) | ||||
| - New datasource! Initial support for OpenTSDB (PR #211) - thx @mpage | ||||
| - Improvement and polish to the OpenTSDB query editor (Issue #492) | ||||
| 
 | ||||
| 
 | ||||
| #### Changes | ||||
| - Graphite panel is now renamed graph (Existing dashboards will still work) | ||||
|  |  | |||
|  | @ -11,4 +11,5 @@ define([ | |||
|   './influxTargetCtrl', | ||||
|   './playlistCtrl', | ||||
|   './inspectCtrl', | ||||
|   './opentsdbTargetCtrl', | ||||
| ], function () {}); | ||||
|  |  | |||
|  | @ -0,0 +1,118 @@ | |||
| define([ | ||||
|   'angular', | ||||
|   'underscore', | ||||
|   'kbn' | ||||
| ], | ||||
| function (angular, _, kbn) { | ||||
|   'use strict'; | ||||
| 
 | ||||
|   var module = angular.module('kibana.controllers'); | ||||
| 
 | ||||
|   module.controller('OpenTSDBTargetCtrl', function($scope, $timeout) { | ||||
| 
 | ||||
|     $scope.init = function() { | ||||
|       $scope.target.errors = validateTarget($scope.target); | ||||
|       $scope.aggregators = ['avg', 'sum', 'min', 'max', 'dev', 'zimsum', 'mimmin', 'mimmax']; | ||||
| 
 | ||||
|       if (!$scope.target.aggregator) { | ||||
|         $scope.target.aggregator = 'sum'; | ||||
|       } | ||||
| 
 | ||||
|       if (!$scope.target.downsampleAggregator) { | ||||
|         $scope.target.downsampleAggregator = 'sum'; | ||||
|       } | ||||
| 
 | ||||
|       $scope.$on('typeahead-updated', function() { | ||||
|         $timeout($scope.targetBlur); | ||||
|       }); | ||||
|     }; | ||||
| 
 | ||||
|     $scope.targetBlur = function() { | ||||
|       $scope.target.errors = validateTarget($scope.target); | ||||
| 
 | ||||
|       // this does not work so good
 | ||||
|       if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) { | ||||
|         $scope.oldTarget = angular.copy($scope.target); | ||||
|         $scope.get_data(); | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     $scope.duplicate = function() { | ||||
|       var clone = angular.copy($scope.target); | ||||
|       $scope.panel.targets.push(clone); | ||||
|     }; | ||||
| 
 | ||||
|     $scope.suggestMetrics = function(query, callback) { | ||||
|       $scope.datasource | ||||
|         .performSuggestQuery(query, 'metrics') | ||||
|         .then(callback); | ||||
|     }; | ||||
| 
 | ||||
|     $scope.suggestTagKeys = function(query, callback) { | ||||
|       $scope.datasource | ||||
|         .performSuggestQuery(query, 'tagk') | ||||
|         .then(callback); | ||||
|     }; | ||||
| 
 | ||||
|     $scope.suggestTagValues = function(query, callback) { | ||||
|       $scope.datasource | ||||
|         .performSuggestQuery(query, 'tagv') | ||||
|         .then(callback); | ||||
|     }; | ||||
| 
 | ||||
|     $scope.addTag = function() { | ||||
|       if (!$scope.addTagMode) { | ||||
|         $scope.addTagMode = true; | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       if (!$scope.target.tags) { | ||||
|         $scope.target.tags = {}; | ||||
|       } | ||||
| 
 | ||||
|       $scope.target.errors = validateTarget($scope.target); | ||||
| 
 | ||||
|       if (!$scope.target.errors.tags) { | ||||
|         $scope.target.tags[$scope.target.currentTagKey] = $scope.target.currentTagValue; | ||||
|         $scope.target.currentTagKey = ''; | ||||
|         $scope.target.currentTagValue = ''; | ||||
|         $scope.targetBlur(); | ||||
|       } | ||||
| 
 | ||||
|       $scope.addTagMode = false; | ||||
|     }; | ||||
| 
 | ||||
|     $scope.removeTag = function(key) { | ||||
|       delete $scope.target.tags[key]; | ||||
|       $scope.targetBlur(); | ||||
|     }; | ||||
| 
 | ||||
|     function validateTarget(target) { | ||||
|       var errs = {}; | ||||
| 
 | ||||
|       if (!target.metric) { | ||||
|         errs.metric = "You must supply a metric name."; | ||||
|       } | ||||
| 
 | ||||
|       if (target.shouldDownsample) { | ||||
|         try { | ||||
|           if (target.downsampleInterval) { | ||||
|             kbn.describe_interval(target.downsampleInterval); | ||||
|           } else { | ||||
|             errs.downsampleInterval = "You must supply a downsample interval (e.g. '1m' or '1h')."; | ||||
|           } | ||||
|         } catch(err) { | ||||
|           errs.downsampleInterval = err.message; | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       if (target.tags && _.has(target.tags, target.currentTagKey)) { | ||||
|         errs.tags = "Duplicate tag key '" + target.currentTagKey + "'."; | ||||
|       } | ||||
| 
 | ||||
|       return errs; | ||||
|     } | ||||
| 
 | ||||
|   }); | ||||
| 
 | ||||
| }); | ||||
|  | @ -0,0 +1,322 @@ | |||
| <div class="editor-row" style="margin-top: 10px;"> | ||||
|   <div  ng-repeat="target in panel.targets" | ||||
|         class="grafana-target" | ||||
|         ng-class="{'grafana-target-hidden': target.hide}" | ||||
|         ng-controller="OpenTSDBTargetCtrl" | ||||
|         ng-init="init()"> | ||||
| 
 | ||||
|     <div class="grafana-target-inner-wrapper"> | ||||
|       <div class="grafana-target-inner"> | ||||
|         <ul class="grafana-target-controls"> | ||||
|           <li class="dropdown"> | ||||
|             <a  class="pointer dropdown-toggle" | ||||
|                 data-toggle="dropdown" | ||||
|                 tabindex="1"> | ||||
|               <i class="icon-cog"></i> | ||||
|             </a> | ||||
|             <ul class="dropdown-menu pull-right" role="menu"> | ||||
|               <li role="menuitem"> | ||||
|                 <a  tabindex="1" | ||||
|                     ng-click="duplicate()"> | ||||
|                   Duplicate | ||||
|                 </a> | ||||
|               </li> | ||||
|             </ul> | ||||
|           </li> | ||||
|           <li> | ||||
|             <a class="pointer" tabindex="1" ng-click="removeTarget(target)"> | ||||
|               <i class="icon-remove"></i> | ||||
|             </a> | ||||
|           </li> | ||||
|         </ul> | ||||
| 
 | ||||
|         <ul class="grafana-target-controls-left"> | ||||
|           <li> | ||||
|             <a  class="grafana-target-segment" | ||||
|                 ng-click="target.hide = !target.hide; get_data();" | ||||
|                 role="menuitem"> | ||||
|               <i class="icon-eye-open"></i> | ||||
|             </a> | ||||
|           </li> | ||||
|         </ul> | ||||
| 
 | ||||
|         <ul class="grafana-segment-list" role="menu"> | ||||
|           <li> | ||||
|             <input type="text" | ||||
|                    class="input-xxlarge grafana-target-segment-input" | ||||
|                    ng-model="target.metric" | ||||
|                    spellcheck='false' | ||||
|                    bs-typeahead="suggestMetrics" | ||||
|                    placeholder="metric name" | ||||
|                    data-min-length=0 data-items=100 | ||||
|                    ng-blur="targetBlur()" | ||||
|                    > | ||||
|             <a bs-tooltip="target.errors.metric" | ||||
|                style="color: rgb(229, 189, 28)" | ||||
|                ng-show="target.errors.metric"> | ||||
|               <i class="icon-warning-sign"></i> | ||||
|             </a> | ||||
|           </li> | ||||
|           <li class="grafana-target-segment"> | ||||
|             Aggregator | ||||
|           <li> | ||||
|             <select ng-model="target.aggregator" | ||||
|                     class="grafana-target-segment-input input-small" | ||||
|                     ng-options="agg for agg in aggregators" | ||||
|                     ng-change="targetBlur()"> | ||||
|             </select> | ||||
|             <a bs-tooltip="target.errors.aggregator" | ||||
|                style="color: rgb(229, 189, 28)" | ||||
|                ng-show="target.errors.aggregator"> | ||||
|               <i class="icon-warning-sign"></i> | ||||
|             </a> | ||||
|           </li> | ||||
| 
 | ||||
|           <li class="grafana-target-segment"> | ||||
|               Rate: | ||||
|               <input type="checkbox" | ||||
|                      class="grafana-target-option-checkbox" | ||||
|                      ng-model="target.shouldComputeRate" | ||||
|                      ng-change="targetBlur()" | ||||
|                      > | ||||
|           </li> | ||||
|           <li class="grafana-target-segment" ng-hide="!target.shouldComputeRate"> | ||||
|             Counter: | ||||
|             <input type="checkbox" | ||||
|                    class="grafana-target-option-checkbox" | ||||
|                    ng-disabled="!target.shouldComputeRate" | ||||
|                    ng-model="target.isCounter" | ||||
|                    ng-change="targetBlur()"> | ||||
|           </li> | ||||
|         </ul> | ||||
| 
 | ||||
|         <div class="clearfix"></div> | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="grafana-target-inner"> | ||||
|         <ul class="grafana-segment-list" role="menu"> | ||||
| 
 | ||||
|           <li class="grafana-target-segment"> | ||||
|             Downsample: | ||||
|             <input type="checkbox" | ||||
|                    class="grafana-target-option-checkbox" | ||||
|                    ng-model="target.shouldDownsample" | ||||
|                    ng-change="targetBlur(target)" | ||||
|                    > | ||||
|           </li> | ||||
| 
 | ||||
|           <li ng-hide="!target.shouldDownsample"> | ||||
|             <input type="text" | ||||
|                    class="input-small grafana-target-segment-input" | ||||
|                    ng-disabled="!target.shouldDownsample" | ||||
|                    ng-model="target.downsampleInterval" | ||||
|                    ng-change="targetBlur()" | ||||
|                    placeholder="interval" | ||||
|                    > | ||||
|           </li> | ||||
| 
 | ||||
|           <li class="grafana-target-segment" ng-hide="!target.shouldDownsample"> | ||||
|             Aggregator | ||||
|           </li> | ||||
| 
 | ||||
|           <li ng-hide="!target.shouldDownsample"> | ||||
|             <select ng-model="target.downsampleAggregator" | ||||
|                     class="grafana-target-segment-input input-small" | ||||
|                     ng-options="agg for agg in aggregators" | ||||
|                     ng-change="targetBlur()"> | ||||
|             </select> | ||||
|           </li> | ||||
| 
 | ||||
|           <li class="grafana-target-segment"> | ||||
|               Tags: | ||||
|           </li> | ||||
|           <li ng-repeat="(key, value) in target.tags track by $index" class="grafana-target-segment"> | ||||
|             {{key}} = {{value}} | ||||
|             <a ng-click="removeTag(key)"> | ||||
|               <i class="icon-remove"></i> | ||||
|             </a> | ||||
|           </li> | ||||
| 
 | ||||
|           <li class="grafana-target-segment" ng-hide="addTagMode"> | ||||
|             <a ng-click="addTag()"> | ||||
|               <i class="icon-plus-sign"></i> | ||||
|             </a> | ||||
|           </li> | ||||
| 
 | ||||
|           <li ng-show="addTagMode"> | ||||
|               <input type="text" | ||||
|                      class="input-small grafana-target-segment-input" | ||||
|                      spellcheck='false' | ||||
|                      bs-typeahead="suggestTagKeys" | ||||
|                      data-min-length=0 data-items=100 | ||||
|                      ng-model="target.currentTagKey" | ||||
|                      placeholder="key"> | ||||
|               <input type="text" | ||||
|                      class="input-small grafana-target-segment-input" | ||||
|                      spellcheck='false' | ||||
|                      bs-typeahead="suggestTagValues" | ||||
|                      data-min-length=0 data-items=100 | ||||
|                      ng-model="target.currentTagValue" | ||||
|                      placeholder="value"> | ||||
|               <a ng-click="addTag()"> | ||||
|                 <i class="icon-plus-sign"></i> | ||||
|               </a> | ||||
|               <a bs-tooltip="target.errors.tags" | ||||
|                  style="color: rgb(229, 189, 28)" | ||||
|                  ng-show="target.errors.tags"> | ||||
|                 <i class="icon-warning-sign"></i> | ||||
|               </a> | ||||
|           </li> | ||||
|         </ul> | ||||
| 
 | ||||
|         <!-- <ul class="grafana-segment-list" role="menu"> | ||||
|           <li> | ||||
|             <input type="text" | ||||
|                    class="input-xlarge grafana-target-segment-input" | ||||
|                    ng-model="target.metric" | ||||
|                    spellcheck='false' | ||||
|                    bs-typeahead="suggestMetrics" | ||||
|                    placeholder="metric name" | ||||
|                    data-min-length=0 data-items=100 | ||||
|                    ng-blur="targetBlur()" | ||||
|                    > | ||||
|             <a bs-tooltip="target.errors.metric" | ||||
|                style="color: rgb(229, 189, 28)" | ||||
|                ng-show="target.errors.metric"> | ||||
|               <i class="icon-warning-sign"></i> | ||||
|             </a> | ||||
|           </li> | ||||
| 
 | ||||
|           <li> | ||||
|             <select ng-model="target.aggregator" | ||||
|                     class="grafana-target-segment-input input-small" | ||||
|                     ng-options="agg for agg in aggregators" | ||||
|                     ng-change="targetBlur()"> | ||||
|             </select> | ||||
|             <a bs-tooltip="target.errors.aggregator" | ||||
|                style="color: rgb(229, 189, 28)" | ||||
|                ng-show="target.errors.aggregator"> | ||||
|               <i class="icon-warning-sign"></i> | ||||
|             </a> | ||||
|           </li> | ||||
| 
 | ||||
|           <li class="grafana-target-segment"> | ||||
|               Rate: | ||||
|               <input type="checkbox" | ||||
|                      class="grafana-target-option-checkbox" | ||||
|                      ng-model="target.shouldComputeRate" | ||||
|                      ng-change="targetBlur()" | ||||
|                      > | ||||
|               <span ng-hide="!target.shouldComputeRate"> | ||||
|                 Counter: | ||||
|                 <input type="checkbox" | ||||
|                        class="grafana-target-option-checkbox" | ||||
|                        ng-disabled="!target.shouldComputeRate" | ||||
|                        ng-model="target.isCounter" | ||||
|                        ng-change="targetBlur()" | ||||
|                        > | ||||
|               </span> | ||||
|           </li> | ||||
| 
 | ||||
|           <li class="grafana-target-segment"> | ||||
|             Downsample: | ||||
|             <input type="checkbox" | ||||
|                    class="grafana-target-option-checkbox" | ||||
|                    ng-model="target.shouldDownsample" | ||||
|                    ng-change="targetBlur(target)" | ||||
|                    > | ||||
|             <div ng-hide="!target.shouldDownsample"> | ||||
|               <table> | ||||
|                 <tr> | ||||
|                   <td> | ||||
|                     Interval: | ||||
|                   </td> | ||||
|                   <td> | ||||
|                     <input type="text" | ||||
|                            class="input-small" | ||||
|                            ng-disabled="!target.shouldDownsample" | ||||
|                            ng-model="target.downsampleInterval" | ||||
|                            ng-change="targetBlur()"> | ||||
|                   </td> | ||||
|                   <td> | ||||
|                     <a bs-tooltip="target.errors.downsampleInterval" | ||||
|                        style="color: rgb(229, 189, 28)" | ||||
|                        ng-show="target.errors.downsampleInterval"> | ||||
|                       <i class="icon-warning-sign"></i> | ||||
|                     </a> | ||||
|                   </td> | ||||
|                 </tr> | ||||
|                 <tr> | ||||
|                   <td>Aggregator:</td> | ||||
|                   <td> | ||||
|                     <select ng-model="target.downsampleAggregator" | ||||
|                             class="grafana-target-segment-input input-small" | ||||
|                             ng-options="agg for agg in aggregators" | ||||
|                             ng-change="targetBlur()" | ||||
|                             > | ||||
|                       <option value="">Pick one</option> | ||||
|                     </select> | ||||
|                   </td> | ||||
|                   <td> | ||||
|                     <a bs-tooltip="target.errors.downsampleAggregator" | ||||
|                        style="color: rgb(229, 189, 28)" | ||||
|                        ng-show="target.errors.downsampleAggregator"> | ||||
|                       <i class="icon-warning-sign"></i> | ||||
|                     </a> | ||||
|                   </td> | ||||
|                 </tr> | ||||
|               </table> | ||||
|             </div> | ||||
|           </li> | ||||
| 
 | ||||
|           <li class="grafana-target-segment"> | ||||
|               Tags: | ||||
|           </li> | ||||
| 
 | ||||
|           <li> | ||||
|             <div> | ||||
|               <input type="text" | ||||
|                      class="input-small grafana-target-segment-input" | ||||
|                      spellcheck='false' | ||||
|                      bs-typeahead="suggestTagKeys" | ||||
|                      data-min-length=0 data-items=100 | ||||
|                      ng-model="target.currentTagKey" | ||||
|                      placeholder="key"> | ||||
|               <input type="text" | ||||
|                      class="input-small grafana-target-segment-input" | ||||
|                      spellcheck='false' | ||||
|                      bs-typeahead="suggestTagValues" | ||||
|                      data-min-length=0 data-items=100 | ||||
|                      ng-model="target.currentTagValue" | ||||
|                      placeholder="value"> | ||||
|               <a ng-click="addTag()"> | ||||
|                 <i class="icon-plus-sign"></i> | ||||
|               </a> | ||||
|               <a bs-tooltip="target.errors.tags" | ||||
|                  style="color: rgb(229, 189, 28)" | ||||
|                  ng-show="target.errors.tags"> | ||||
|                 <i class="icon-warning-sign"></i> | ||||
|               </a> | ||||
|             </div> | ||||
|             <table ng-hide="_.isEmpty(target.tags)"> | ||||
|               <tr> | ||||
|                 <th>Key</th> | ||||
|                 <th>Value</td> | ||||
|               <tr ng-repeat="(key, value) in target.tags track by $index"> | ||||
|                 <td>{{ key }}</td> | ||||
|                 <td>{{ value }}</td> | ||||
|                 <td> | ||||
|                   <a ng-click="removeTag(key)"> | ||||
|                     <i class="icon-remove"></i> | ||||
|                   </a> | ||||
|                 </td> | ||||
|               </tr> | ||||
|             </table> | ||||
|           </li> | ||||
|         </ul> --> | ||||
| 
 | ||||
|         <div class="clearfix"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | @ -4,13 +4,14 @@ define([ | |||
|   'config', | ||||
|   './graphite/graphiteDatasource', | ||||
|   './influxdb/influxdbDatasource', | ||||
|   './opentsdb/opentsdbDatasource', | ||||
| ], | ||||
| function (angular, _, config) { | ||||
|   'use strict'; | ||||
| 
 | ||||
|   var module = angular.module('kibana.services'); | ||||
| 
 | ||||
|   module.service('datasourceSrv', function($q, $http, GraphiteDatasource, InfluxDatasource) { | ||||
|   module.service('datasourceSrv', function($q, filterSrv, $http, GraphiteDatasource, InfluxDatasource, OpenTSDBDatasource) { | ||||
| 
 | ||||
|     this.init = function() { | ||||
|       var defaultDatasource = _.findWhere(_.values(config.datasources), { default: true }); | ||||
|  | @ -23,6 +24,8 @@ function (angular, _, config) { | |||
|         return new GraphiteDatasource(ds); | ||||
|       case 'influxdb': | ||||
|         return new InfluxDatasource(ds); | ||||
|       case 'opentsdb': | ||||
|         return new OpenTSDBDatasource(ds); | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,155 @@ | |||
| define([ | ||||
|   'angular', | ||||
|   'underscore', | ||||
|   'kbn' | ||||
| ], | ||||
| function (angular, _, kbn) { | ||||
|   'use strict'; | ||||
| 
 | ||||
|   var module = angular.module('kibana.services'); | ||||
| 
 | ||||
|   module.factory('OpenTSDBDatasource', function($q, $http) { | ||||
| 
 | ||||
|     function OpenTSDBDatasource(datasource) { | ||||
|       this.type = 'opentsdb'; | ||||
|       this.editorSrc = 'app/partials/opentsdb/editor.html'; | ||||
|       this.url = datasource.url; | ||||
|       this.name = datasource.name; | ||||
|     } | ||||
| 
 | ||||
|     // Called once per panel (graph)
 | ||||
|     OpenTSDBDatasource.prototype.query = function(filterSrv, options) { | ||||
|       var start = convertToTSDBTime(options.range.from); | ||||
|       var end = convertToTSDBTime(options.range.to); | ||||
|       var queries = _.compact(_.map(options.targets, convertTargetToQuery)); | ||||
| 
 | ||||
|       // No valid targets, return the empty result to save a round trip.
 | ||||
|       if (_.isEmpty(queries)) { | ||||
|         var d = $q.defer(); | ||||
|         d.resolve({ data: [] }); | ||||
|         return d.promise; | ||||
|       } | ||||
| 
 | ||||
|       var groupByTags = {}; | ||||
|       _.each(queries, function(query) { | ||||
|         _.each(query.tags, function(val, key) { | ||||
|           if (val === "*") { | ||||
|             groupByTags[key] = true; | ||||
|           } | ||||
|         }); | ||||
|       }); | ||||
| 
 | ||||
|       return this.performTimeSeriesQuery(queries, start, end) | ||||
|         .then(function(response) { | ||||
|           var result = _.map(response.data, function(metricData) { | ||||
|             return transformMetricData(metricData, groupByTags); | ||||
|           }); | ||||
|           return { data: result }; | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     OpenTSDBDatasource.prototype.performTimeSeriesQuery = function(queries, start, end) { | ||||
|       var reqBody = { | ||||
|         start: start, | ||||
|         queries: queries | ||||
|       }; | ||||
| 
 | ||||
|       // Relative queries (e.g. last hour) don't include an end time
 | ||||
|       if (end) { | ||||
|         reqBody.end = end; | ||||
|       } | ||||
| 
 | ||||
|       var options = { | ||||
|         method: 'POST', | ||||
|         url: this.url + '/api/query', | ||||
|         data: reqBody | ||||
|       }; | ||||
| 
 | ||||
|       return $http(options); | ||||
|     }; | ||||
| 
 | ||||
|     OpenTSDBDatasource.prototype.performSuggestQuery = function(query, type) { | ||||
|       var options = { | ||||
|         method: 'GET', | ||||
|         url: this.url + '/api/suggest', | ||||
|         params: { | ||||
|           type: type, | ||||
|           q: query | ||||
|         } | ||||
|       }; | ||||
|       return $http(options).then(function(result) { | ||||
|         return result.data; | ||||
|       }); | ||||
|     }; | ||||
| 
 | ||||
|     function transformMetricData(md, groupByTags) { | ||||
|       var dps = []; | ||||
| 
 | ||||
|       // TSDB returns datapoints has a hash of ts => value.
 | ||||
|       // Can't use _.pairs(invert()) because it stringifies keys/values
 | ||||
|       _.each(md.dps, function (v, k) { | ||||
|         dps.push([v, k]); | ||||
|       }); | ||||
| 
 | ||||
|       var target = md.metric; | ||||
|       if (!_.isEmpty(md.tags)) { | ||||
|         var tagData = []; | ||||
| 
 | ||||
|         _.each(_.pairs(md.tags), function(tag) { | ||||
|           if (_.has(groupByTags, tag[0])) { | ||||
|             tagData.push(tag[0] + "=" + tag[1]); | ||||
|           } | ||||
|         }); | ||||
| 
 | ||||
|         if (!_.isEmpty(tagData)) { | ||||
|           target = target + "{" + tagData.join(", ") + "}"; | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       return { target: target, datapoints: dps }; | ||||
|     } | ||||
| 
 | ||||
|     function convertTargetToQuery(target) { | ||||
|       if (!target.metric) { | ||||
|         return null; | ||||
|       } | ||||
| 
 | ||||
|       var query = { | ||||
|         metric: target.metric, | ||||
|         aggregator: "avg" | ||||
|       }; | ||||
| 
 | ||||
|       if (target.aggregator) { | ||||
|         query.aggregator = target.aggregator; | ||||
|       } | ||||
| 
 | ||||
|       if (target.shouldComputeRate) { | ||||
|         query.rate = true; | ||||
|         query.rateOptions = { | ||||
|           counter: !!target.isCounter | ||||
|         }; | ||||
|       } | ||||
| 
 | ||||
|       if (target.shouldDownsample) { | ||||
|         query.downsample = target.downsampleInterval + "-" + target.downsampleAggregator; | ||||
|       } | ||||
| 
 | ||||
|       query.tags = angular.copy(target.tags); | ||||
| 
 | ||||
|       return query; | ||||
|     } | ||||
| 
 | ||||
|     function convertToTSDBTime(date) { | ||||
|       if (date === 'now') { | ||||
|         return null; | ||||
|       } | ||||
| 
 | ||||
|       date = kbn.parseDate(date); | ||||
| 
 | ||||
|       return date.getTime(); | ||||
|     } | ||||
| 
 | ||||
|     return OpenTSDBDatasource; | ||||
|   }); | ||||
| 
 | ||||
| }); | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -371,6 +371,10 @@ input[type=text].grafana-target-segment-input { | |||
|   padding: 8px 4px; | ||||
| } | ||||
| 
 | ||||
| input[type=checkbox].grafana-target-option-checkbox { | ||||
|   margin: 0; | ||||
| } | ||||
| 
 | ||||
| select.grafana-target-segment-input { | ||||
|   border: none; | ||||
|   border-right: 1px solid @grafanaTargetSegmentBorder; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue