From bd4d665d54f41b9341f89bfe1baa5694c74f806a Mon Sep 17 00:00:00 2001 From: THIERRY SALLE Date: Tue, 21 Nov 2017 10:56:34 +0100 Subject: [PATCH 01/13] Elasticsearch max_concurrent_shard_requests parameter for es 5.6+ --- .../datasource/elasticsearch/config_ctrl.ts | 2 ++ .../datasource/elasticsearch/datasource.ts | 16 +++++++++++----- .../elasticsearch/partials/config.html | 4 ++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/public/app/plugins/datasource/elasticsearch/config_ctrl.ts b/public/app/plugins/datasource/elasticsearch/config_ctrl.ts index 2a3803db998..67a82c681d4 100644 --- a/public/app/plugins/datasource/elasticsearch/config_ctrl.ts +++ b/public/app/plugins/datasource/elasticsearch/config_ctrl.ts @@ -8,6 +8,7 @@ export class ElasticConfigCtrl { constructor($scope) { this.current.jsonData.timeField = this.current.jsonData.timeField || '@timestamp'; this.current.jsonData.esVersion = this.current.jsonData.esVersion || 5; + this.current.jsonData.maxConcurrentShardRequests = this.current.jsonData.maxConcurrentShardRequests || 256; } indexPatternTypes = [ @@ -22,6 +23,7 @@ export class ElasticConfigCtrl { esVersions = [ {name: '2.x', value: 2}, {name: '5.x', value: 5}, + {name: '5.6+', value: 56}, ]; indexPatternTypeChanged() { diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index 814b6c72da6..9b9de22eb5e 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -16,6 +16,7 @@ export class ElasticDatasource { timeField: string; esVersion: number; interval: string; + maxConcurrentShardRequests: number; queryBuilder: ElasticQueryBuilder; indexPattern: IndexPattern; @@ -30,6 +31,7 @@ export class ElasticDatasource { this.esVersion = instanceSettings.jsonData.esVersion; this.indexPattern = new IndexPattern(instanceSettings.index, instanceSettings.jsonData.interval); this.interval = instanceSettings.jsonData.timeInterval; + this.maxConcurrentShardRequests = instanceSettings.jsonData.maxConcurrentShardRequests; this.queryBuilder = new ElasticQueryBuilder({ timeField: this.timeField, esVersion: this.esVersion, @@ -213,11 +215,15 @@ export class ElasticDatasource { } getQueryHeader(searchType, timeFrom, timeTo) { - return angular.toJson({ - search_type: searchType, - "ignore_unavailable": true, - index: this.indexPattern.getIndexList(timeFrom, timeTo), - }); + var query_header: any = { + search_type: searchType, + "ignore_unavailable": true, + index: this.indexPattern.getIndexList(timeFrom, timeTo), + }; + if (this.esVersion >= 56) { + query_header["max_concurrent_shard_requests"] = this.maxConcurrentShardRequests; + } + return angular.toJson(query_header); } query(options) { diff --git a/public/app/plugins/datasource/elasticsearch/partials/config.html b/public/app/plugins/datasource/elasticsearch/partials/config.html index 8b5f3ba8a8a..42ae4265371 100644 --- a/public/app/plugins/datasource/elasticsearch/partials/config.html +++ b/public/app/plugins/datasource/elasticsearch/partials/config.html @@ -25,6 +25,10 @@ Version +
+ Max concurrent Shard Requests + +
Min interval From 767b460ff1929d55b78287152feae48b9f432ddf Mon Sep 17 00:00:00 2001 From: saady Date: Mon, 20 Nov 2017 02:26:46 +0000 Subject: [PATCH 02/13] [GCS] Support for gcs path --- conf/defaults.ini | 1 + conf/sample.ini | 1 + docs/sources/installation/configuration.md | 3 +++ pkg/components/imguploader/gcsuploader.go | 8 ++++++-- pkg/components/imguploader/imguploader.go | 3 ++- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/conf/defaults.ini b/conf/defaults.ini index 2c3064ecf22..a145d57482b 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -495,3 +495,4 @@ public_url = [external_image_storage.gcs] key_file = bucket = +path = \ No newline at end of file diff --git a/conf/sample.ini b/conf/sample.ini index 85e74451fef..233a97deef8 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -438,3 +438,4 @@ log_queries = [external_image_storage.gcs] ;key_file = ;bucket = +;path = \ No newline at end of file diff --git a/docs/sources/installation/configuration.md b/docs/sources/installation/configuration.md index c044b3d73dc..483774f94f5 100644 --- a/docs/sources/installation/configuration.md +++ b/docs/sources/installation/configuration.md @@ -778,6 +778,9 @@ Service Account should have "Storage Object Writer" role. ### bucket name Bucket Name on Google Cloud Storage. +### path +Optional extra path inside bucket + ## [alerting] ### enabled diff --git a/pkg/components/imguploader/gcsuploader.go b/pkg/components/imguploader/gcsuploader.go index 2271cec7db0..cb1ae19059d 100644 --- a/pkg/components/imguploader/gcsuploader.go +++ b/pkg/components/imguploader/gcsuploader.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "net/http" "os" + "path" "github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/util" @@ -20,19 +21,22 @@ const ( type GCSUploader struct { keyFile string bucket string + path string log log.Logger } -func NewGCSUploader(keyFile, bucket string) *GCSUploader { +func NewGCSUploader(keyFile, bucket, path string) *GCSUploader { return &GCSUploader{ keyFile: keyFile, bucket: bucket, + path: path, log: log.New("gcsuploader"), } } func (u *GCSUploader) Upload(ctx context.Context, imageDiskPath string) (string, error) { - key := util.GetRandomString(20) + ".png" + fileName := util.GetRandomString(20) + ".png" + key := path.Join(u.path, fileName) u.log.Debug("Opening key file ", u.keyFile) data, err := ioutil.ReadFile(u.keyFile) diff --git a/pkg/components/imguploader/imguploader.go b/pkg/components/imguploader/imguploader.go index 728614735d0..fd14b5d6739 100644 --- a/pkg/components/imguploader/imguploader.go +++ b/pkg/components/imguploader/imguploader.go @@ -73,8 +73,9 @@ func NewImageUploader() (ImageUploader, error) { keyFile := gcssec.Key("key_file").MustString("") bucketName := gcssec.Key("bucket").MustString("") + path := gcssec.Key("path").MustString("") - return NewGCSUploader(keyFile, bucketName), nil + return NewGCSUploader(keyFile, bucketName, path), nil } return NopImageUploader{}, nil From 3f2a510568792cb6502770f31cfeba188a93d989 Mon Sep 17 00:00:00 2001 From: Matt Toback Date: Tue, 21 Nov 2017 17:16:35 -0500 Subject: [PATCH 03/13] Delete LICENSE.txt --- LICENSE.txt | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index c64b0d85c42..00000000000 --- a/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013-2016 Nathan Hopkins - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 400bd205a874ffaf693e3a6c27ac88d086b9b5ca Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Wed, 22 Nov 2017 09:30:49 +0100 Subject: [PATCH 04/13] Removing file that got committed by accident --- Dockerfile | 109 ----------------------------------------------------- 1 file changed, 109 deletions(-) delete mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 277ed149d13..00000000000 --- a/Dockerfile +++ /dev/null @@ -1,109 +0,0 @@ -FROM phusion/baseimage:0.9.22 -MAINTAINER Denys Zhdanov - -RUN apt-get -y update \ - && apt-get -y upgrade \ - && apt-get -y install vim \ - nginx \ - python-dev \ - python-flup \ - python-pip \ - python-ldap \ - expect \ - git \ - memcached \ - sqlite3 \ - libffi-dev \ - libcairo2 \ - libcairo2-dev \ - python-cairo \ - python-rrdtool \ - pkg-config \ - nodejs \ - && rm -rf /var/lib/apt/lists/* - -# choose a timezone at build-time -# use `--build-arg CONTAINER_TIMEZONE=Europe/Brussels` in `docker build` -ARG CONTAINER_TIMEZONE -ENV DEBIAN_FRONTEND noninteractive - -RUN if [ ! -z "${CONTAINER_TIMEZONE}" ]; \ - then ln -sf /usr/share/zoneinfo/$CONTAINER_TIMEZONE /etc/localtime && \ - dpkg-reconfigure -f noninteractive tzdata; \ - fi - -# fix python dependencies (LTS Django and newer memcached/txAMQP) -RUN pip install --upgrade pip && \ - pip install django==1.8.18 \ - python-memcached==1.53 \ - txAMQP==0.6.2 - -ARG version=1.0.2 -ARG whisper_version=${version} -ARG carbon_version=${version} -ARG graphite_version=${version} - -ARG statsd_version=v0.7.2 - -# install whisper -RUN git clone -b ${whisper_version} --depth 1 https://github.com/graphite-project/whisper.git /usr/local/src/whisper -WORKDIR /usr/local/src/whisper -RUN python ./setup.py install - -# install carbon -RUN git clone -b ${carbon_version} --depth 1 https://github.com/graphite-project/carbon.git /usr/local/src/carbon -WORKDIR /usr/local/src/carbon -RUN pip install -r requirements.txt \ - && python ./setup.py install - -# install graphite -RUN git clone -b ${graphite_version} --depth 1 https://github.com/graphite-project/graphite-web.git /usr/local/src/graphite-web -WORKDIR /usr/local/src/graphite-web -RUN pip install -r requirements.txt \ - && python ./setup.py install -ADD conf/opt/graphite/conf/*.conf /opt/graphite/conf/ -ADD conf/opt/graphite/webapp/graphite/local_settings.py /opt/graphite/webapp/graphite/local_settings.py -# ADD conf/opt/graphite/webapp/graphite/app_settings.py /opt/graphite/webapp/graphite/app_settings.py -WORKDIR /opt/graphite/webapp -RUN mkdir -p /var/log/graphite/ \ - && PYTHONPATH=/opt/graphite/webapp django-admin.py collectstatic --noinput --settings=graphite.settings - -# install statsd -RUN git clone -b ${statsd_version} https://github.com/etsy/statsd.git /opt/statsd -ADD conf/opt/statsd/config.js /opt/statsd/config.js - -# config nginx -RUN rm /etc/nginx/sites-enabled/default -ADD conf/etc/nginx/nginx.conf /etc/nginx/nginx.conf -ADD conf/etc/nginx/sites-enabled/graphite-statsd.conf /etc/nginx/sites-enabled/graphite-statsd.conf - -# init django admin -ADD conf/usr/local/bin/django_admin_init.exp /usr/local/bin/django_admin_init.exp -ADD conf/usr/local/bin/manage.sh /usr/local/bin/manage.sh -RUN chmod +x /usr/local/bin/manage.sh && /usr/local/bin/django_admin_init.exp - -# logging support -RUN mkdir -p /var/log/carbon /var/log/graphite /var/log/nginx -ADD conf/etc/logrotate.d/graphite-statsd /etc/logrotate.d/graphite-statsd - -# daemons -ADD conf/etc/service/carbon/run /etc/service/carbon/run -ADD conf/etc/service/carbon-aggregator/run /etc/service/carbon-aggregator/run -ADD conf/etc/service/graphite/run /etc/service/graphite/run -ADD conf/etc/service/statsd/run /etc/service/statsd/run -ADD conf/etc/service/nginx/run /etc/service/nginx/run - -# default conf setup -ADD conf /etc/graphite-statsd/conf -ADD conf/etc/my_init.d/01_conf_init.sh /etc/my_init.d/01_conf_init.sh - -# cleanup -RUN apt-get clean\ - && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -# defaults -EXPOSE 80 2003-2004 2023-2024 8125/udp 8126 -VOLUME ["/opt/graphite/conf", "/opt/graphite/storage", "/etc/nginx", "/opt/statsd", "/etc/logrotate.d", "/var/log"] -WORKDIR / -ENV HOME /root -CMD ["/sbin/my_init"] From ca940c2ae5293c600981860158390b57eed607e7 Mon Sep 17 00:00:00 2001 From: bergquist Date: Wed, 22 Nov 2017 09:30:03 +0100 Subject: [PATCH 05/13] docs: adds docs for pausing all alerts --- docs/sources/http_api/alerting.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docs/sources/http_api/alerting.md b/docs/sources/http_api/alerting.md index c5172c64203..e66218bb066 100644 --- a/docs/sources/http_api/alerting.md +++ b/docs/sources/http_api/alerting.md @@ -133,6 +133,37 @@ Content-Type: application/json } ``` +## Pause all alerts + +`POST /api/admin/pause-all-alerts` + +```http +POST /api/admin/pause-all-alerts HTTP/1.1 +Accept: application/json +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk + +{ + "paused": true +} +``` + +JSON Body Schema: + +- **paused** – Can be `true` or `false`. True to pause an alert. False to unpause an alert. + +**Example Response**: + +```http +HTTP/1.1 200 +Content-Type: application/json +{ + "state": "Paused", + "message": "alert paused", + "alertsAffected": 1 +} +``` + ## Get alert notifications `GET /api/alert-notifications` From 27e486d678f0f66b302e7dd4e9d6930435b95145 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Wed, 22 Nov 2017 10:11:50 +0100 Subject: [PATCH 06/13] converted 3 .js files to .ts (#9958) * converted files from .js to .ts --- ...ameter_ctrl.js => query_parameter_ctrl.ts} | 29 ++-- .../prometheus/metric_find_query.js | 136 ---------------- .../prometheus/metric_find_query.ts | 147 ++++++++++++++++++ ...rides_ctrl.js => series_overrides_ctrl.ts} | 49 +++--- 4 files changed, 185 insertions(+), 176 deletions(-) rename public/app/plugins/datasource/cloudwatch/{query_parameter_ctrl.js => query_parameter_ctrl.ts} (92%) delete mode 100644 public/app/plugins/datasource/prometheus/metric_find_query.js create mode 100644 public/app/plugins/datasource/prometheus/metric_find_query.ts rename public/app/plugins/panel/graph/{series_overrides_ctrl.js => series_overrides_ctrl.ts} (75%) diff --git a/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.js b/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts similarity index 92% rename from public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.js rename to public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts index 211c46bf855..57a5fba443b 100644 --- a/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.js +++ b/public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts @@ -1,13 +1,9 @@ -define([ - 'angular', - 'lodash', -], -function (angular, _) { - 'use strict'; +import angular from 'angular'; +import _ from 'lodash'; - var module = angular.module('grafana.controllers'); +export class CloudWatchQueryParameter { - module.directive('cloudwatchQueryParameter', function() { + constructor() { return { templateUrl: 'public/app/plugins/datasource/cloudwatch/partials/query.parameter.html', controller: 'CloudWatchQueryParameterCtrl', @@ -18,9 +14,12 @@ function (angular, _) { onChange: "&", } }; - }); + } +} - module.controller('CloudWatchQueryParameterCtrl', function($scope, templateSrv, uiSegmentSrv, datasourceSrv, $q) { +export class CloudWatchQueryParameterCtrl { + + constructor($scope, templateSrv, uiSegmentSrv, datasourceSrv, $q) { $scope.init = function() { var target = $scope.target; @@ -120,8 +119,7 @@ function (angular, _) { if (segment.value === $scope.removeDimSegment.value) { $scope.dimSegments.splice(index, 3); - } - else if (segment.type === 'plus-button') { + } else if (segment.type === 'plus-button') { $scope.dimSegments.push(uiSegmentSrv.newOperator('=')); $scope.dimSegments.push(uiSegmentSrv.newFake('select dimension value', 'value', 'query-segment-value')); segment.type = 'key'; @@ -195,7 +193,8 @@ function (angular, _) { }; $scope.init(); + } +} - }); - -}); +angular.module('grafana.controllers').directive('cloudwatchQueryParameter', CloudWatchQueryParameter); +angular.module('grafana.controllers').controller('CloudWatchQueryParameterCtrl', CloudWatchQueryParameterCtrl); diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.js b/public/app/plugins/datasource/prometheus/metric_find_query.js deleted file mode 100644 index 6bfd324cd6e..00000000000 --- a/public/app/plugins/datasource/prometheus/metric_find_query.js +++ /dev/null @@ -1,136 +0,0 @@ -define([ - 'lodash' -], -function (_) { - 'use strict'; - - function PrometheusMetricFindQuery(datasource, query, timeSrv) { - this.datasource = datasource; - this.query = query; - this.range = timeSrv.timeRange(); - } - - PrometheusMetricFindQuery.prototype.process = function() { - var label_values_regex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)$/; - var metric_names_regex = /^metrics\((.+)\)$/; - var query_result_regex = /^query_result\((.+)\)$/; - - var label_values_query = this.query.match(label_values_regex); - if (label_values_query) { - if (label_values_query[1]) { - return this.labelValuesQuery(label_values_query[2], label_values_query[1]); - } else { - return this.labelValuesQuery(label_values_query[2], null); - } - } - - var metric_names_query = this.query.match(metric_names_regex); - if (metric_names_query) { - return this.metricNameQuery(metric_names_query[1]); - } - - var query_result_query = this.query.match(query_result_regex); - if (query_result_query) { - return this.queryResultQuery(query_result_query[1]); - } - - // if query contains full metric name, return metric name and label list - return this.metricNameAndLabelsQuery(this.query); - }; - - PrometheusMetricFindQuery.prototype.labelValuesQuery = function(label, metric) { - var url; - - if (!metric) { - // return label values globally - url = '/api/v1/label/' + label + '/values'; - - return this.datasource._request('GET', url).then(function(result) { - return _.map(result.data.data, function(value) { - return {text: value}; - }); - }); - } else { - var start = this.datasource.getPrometheusTime(this.range.from, false); - var end = this.datasource.getPrometheusTime(this.range.to, true); - url = '/api/v1/series?match[]=' + encodeURIComponent(metric) - + '&start=' + start - + '&end=' + end; - - return this.datasource._request('GET', url) - .then(function(result) { - var _labels = _.map(result.data.data, function(metric) { - return metric[label]; - }); - - return _.uniq(_labels).map(function(metric) { - return { - text: metric, - expandable: true - }; - }); - }); - } - }; - - PrometheusMetricFindQuery.prototype.metricNameQuery = function(metricFilterPattern) { - var url = '/api/v1/label/__name__/values'; - - return this.datasource._request('GET', url) - .then(function(result) { - return _.chain(result.data.data) - .filter(function(metricName) { - var r = new RegExp(metricFilterPattern); - return r.test(metricName); - }) - .map(function(matchedMetricName) { - return { - text: matchedMetricName, - expandable: true - }; - }) - .value(); - }); - }; - - PrometheusMetricFindQuery.prototype.queryResultQuery = function(query) { - var end = this.datasource.getPrometheusTime(this.range.to, true); - return this.datasource.performInstantQuery({ expr: query }, end) - .then(function(result) { - return _.map(result.data.data.result, function(metricData) { - var text = metricData.metric.__name__ || ''; - delete metricData.metric.__name__; - text += '{' + - _.map(metricData.metric, function(v, k) { return k + '="' + v + '"'; }).join(',') + - '}'; - text += ' ' + metricData.value[1] + ' ' + metricData.value[0] * 1000; - - return { - text: text, - expandable: true - }; - }); - }); - }; - - PrometheusMetricFindQuery.prototype.metricNameAndLabelsQuery = function(query) { - var start = this.datasource.getPrometheusTime(this.range.from, false); - var end = this.datasource.getPrometheusTime(this.range.to, true); - var url = '/api/v1/series?match[]=' + encodeURIComponent(query) - + '&start=' + start - + '&end=' + end; - - var self = this; - return this.datasource._request('GET', url) - .then(function(result) { - return _.map(result.data.data, function(metric) { - return { - text: self.datasource.getOriginalMetricName(metric), - expandable: true - }; - }); - }); - }; - - return PrometheusMetricFindQuery; -}); diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.ts b/public/app/plugins/datasource/prometheus/metric_find_query.ts new file mode 100644 index 00000000000..7a82a428939 --- /dev/null +++ b/public/app/plugins/datasource/prometheus/metric_find_query.ts @@ -0,0 +1,147 @@ +import _ from "lodash"; + +export default class PrometheusMetricFindQuery { + datasource: any; + query: any; + range: any; + + constructor(datasource, query, timeSrv) { + this.datasource = datasource; + this.query = query; + this.range = timeSrv.timeRange(); + } + + process() { + var label_values_regex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]+)\)$/; + var metric_names_regex = /^metrics\((.+)\)$/; + var query_result_regex = /^query_result\((.+)\)$/; + + var label_values_query = this.query.match(label_values_regex); + if (label_values_query) { + if (label_values_query[1]) { + return this.labelValuesQuery( + label_values_query[2], + label_values_query[1] + ); + } else { + return this.labelValuesQuery(label_values_query[2], null); + } + } + + var metric_names_query = this.query.match(metric_names_regex); + if (metric_names_query) { + return this.metricNameQuery(metric_names_query[1]); + } + + var query_result_query = this.query.match(query_result_regex); + if (query_result_query) { + return this.queryResultQuery(query_result_query[1]); + } + + // if query contains full metric name, return metric name and label list + return this.metricNameAndLabelsQuery(this.query); + } + + labelValuesQuery(label, metric) { + var url; + + if (!metric) { + // return label values globally + url = "/api/v1/label/" + label + "/values"; + + return this.datasource._request("GET", url).then(function(result) { + return _.map(result.data.data, function(value) { + return { text: value }; + }); + }); + } else { + var start = this.datasource.getPrometheusTime(this.range.from, false); + var end = this.datasource.getPrometheusTime(this.range.to, true); + url = + "/api/v1/series?match[]=" + + encodeURIComponent(metric) + + "&start=" + + start + + "&end=" + + end; + + return this.datasource._request("GET", url).then(function(result) { + var _labels = _.map(result.data.data, function(metric) { + return metric[label]; + }); + + return _.uniq(_labels).map(function(metric) { + return { + text: metric, + expandable: true + }; + }); + }); + } + } + + metricNameQuery(metricFilterPattern) { + var url = "/api/v1/label/__name__/values"; + + return this.datasource._request("GET", url).then(function(result) { + return _.chain(result.data.data) + .filter(function(metricName) { + var r = new RegExp(metricFilterPattern); + return r.test(metricName); + }) + .map(function(matchedMetricName) { + return { + text: matchedMetricName, + expandable: true + }; + }) + .value(); + }); + } + + queryResultQuery(query) { + var end = this.datasource.getPrometheusTime(this.range.to, true); + return this.datasource + .performInstantQuery({ expr: query }, end) + .then(function(result) { + return _.map(result.data.data.result, function(metricData) { + var text = metricData.metric.__name__ || ""; + delete metricData.metric.__name__; + text += + "{" + + _.map(metricData.metric, function(v, k) { + return k + '="' + v + '"'; + }).join(",") + + "}"; + text += " " + metricData.value[1] + " " + metricData.value[0] * 1000; + + return { + text: text, + expandable: true + }; + }); + }); + } + + metricNameAndLabelsQuery(query) { + var start = this.datasource.getPrometheusTime(this.range.from, false); + var end = this.datasource.getPrometheusTime(this.range.to, true); + var url = + "/api/v1/series?match[]=" + + encodeURIComponent(query) + + "&start=" + + start + + "&end=" + + end; + + var self = this; + return this.datasource._request("GET", url).then(function(result) { + return _.map(result.data.data, function(metric) { + return { + text: self.datasource.getOriginalMetricName(metric), + expandable: true + }; + }); + }); + } +} diff --git a/public/app/plugins/panel/graph/series_overrides_ctrl.js b/public/app/plugins/panel/graph/series_overrides_ctrl.ts similarity index 75% rename from public/app/plugins/panel/graph/series_overrides_ctrl.js rename to public/app/plugins/panel/graph/series_overrides_ctrl.ts index 5ee5b5e8e47..245b822e879 100644 --- a/public/app/plugins/panel/graph/series_overrides_ctrl.js +++ b/public/app/plugins/panel/graph/series_overrides_ctrl.ts @@ -1,27 +1,24 @@ -define([ - 'angular', - 'jquery', - 'lodash', -], function(angular, jquery, _) { - 'use strict'; +import _ from 'lodash'; +import angular from 'angular'; - var module = angular.module('grafana.controllers'); +export class SeriesOverridesCtrl { - module.controller('SeriesOverridesCtrl', function($scope, $element, popoverSrv) { + /** @ngInject */ + constructor($scope, $element, popoverSrv) { $scope.overrideMenu = []; $scope.currentOverrides = []; $scope.override = $scope.override || {}; $scope.addOverrideOption = function(name, propertyName, values) { - var option = {}; - option.text = name; - option.propertyName = propertyName; - option.index = $scope.overrideMenu.length; - option.values = values; - - option.submenu = _.map(values, function(value) { - return { text: String(value), value: value }; - }); + var option = { + text: name, + propertyName: propertyName, + index: $scope.overrideMenu.lenght, + values: values, + submenu: _.map(values, function(value) { + return { text: String(value), value: value }; + }) + }; $scope.overrideMenu.push(option); }; @@ -97,22 +94,24 @@ define([ $scope.addOverrideOption('Bars', 'bars', [true, false]); $scope.addOverrideOption('Lines', 'lines', [true, false]); - $scope.addOverrideOption('Line fill', 'fill', [0,1,2,3,4,5,6,7,8,9,10]); - $scope.addOverrideOption('Line width', 'linewidth', [0,1,2,3,4,5,6,7,8,9,10]); + $scope.addOverrideOption('Line fill', 'fill', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + $scope.addOverrideOption('Line width', 'linewidth', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); $scope.addOverrideOption('Null point mode', 'nullPointMode', ['connected', 'null', 'null as zero']); $scope.addOverrideOption('Fill below to', 'fillBelowTo', $scope.getSeriesNames()); $scope.addOverrideOption('Staircase line', 'steppedLine', [true, false]); $scope.addOverrideOption('Dashes', 'dashes', [true, false]); - $scope.addOverrideOption('Dash Length', 'dashLength', [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]); - $scope.addOverrideOption('Dash Space', 'spaceLength', [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]); + $scope.addOverrideOption('Dash Length', 'dashLength', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]); + $scope.addOverrideOption('Dash Space', 'spaceLength', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]); $scope.addOverrideOption('Points', 'points', [true, false]); - $scope.addOverrideOption('Points Radius', 'pointradius', [1,2,3,4,5]); + $scope.addOverrideOption('Points Radius', 'pointradius', [1, 2, 3, 4, 5]); $scope.addOverrideOption('Stack', 'stack', [true, false, 'A', 'B', 'C', 'D']); $scope.addOverrideOption('Color', 'color', ['change']); $scope.addOverrideOption('Y-axis', 'yaxis', [1, 2]); - $scope.addOverrideOption('Z-index', 'zindex', [-3,-2,-1,0,1,2,3]); + $scope.addOverrideOption('Z-index', 'zindex', [-3, -2, -1, 0, 1, 2, 3]); $scope.addOverrideOption('Transform', 'transform', ['negative-Y']); $scope.addOverrideOption('Legend', 'legend', [true, false]); $scope.updateCurrentOverrides(); - }); -}); + } +} + +angular.module('grafana.controllers').controller('SeriesOverridesCtrl', SeriesOverridesCtrl); From 658109e0d686b9b73c7cf09c59be8b1cdb231313 Mon Sep 17 00:00:00 2001 From: THIERRY SALLE Date: Tue, 21 Nov 2017 11:37:06 +0100 Subject: [PATCH 07/13] Optimized number of lines fetching in log file initialisation Added unit tests for file logging line counting Remove file after unit test --- pkg/log/file.go | 31 ++++++++++++++++++++++++++++--- pkg/log/file_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 pkg/log/file_test.go diff --git a/pkg/log/file.go b/pkg/log/file.go index a8d35ba6b81..721db1e55b3 100644 --- a/pkg/log/file.go +++ b/pkg/log/file.go @@ -5,9 +5,10 @@ package log import ( + "bytes" "errors" "fmt" - "io/ioutil" + "io" "os" "path/filepath" "strings" @@ -124,6 +125,30 @@ func (w *FileLogWriter) createLogFile() (*os.File, error) { return os.OpenFile(w.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) } +func (w *FileLogWriter) lineCounter() (int, error) { + r, err := os.OpenFile(w.Filename, os.O_RDONLY, 0644) + if err != nil { + return 0, fmt.Errorf("lineCounter Open File : %s", err) + } + buf := make([]byte, 32*1024) + count := 0 + + for { + c, err := r.Read(buf) + count += bytes.Count(buf[:c], []byte{'\n'}) + switch { + case err == io.EOF: + if err := r.Close(); err != nil { + return count, err + } + return count, nil + + case err != nil: + return count, err + } + } +} + func (w *FileLogWriter) initFd() error { fd := w.mw.fd finfo, err := fd.Stat() @@ -133,11 +158,11 @@ func (w *FileLogWriter) initFd() error { w.maxsize_cursize = int(finfo.Size()) w.daily_opendate = time.Now().Day() if finfo.Size() > 0 { - content, err := ioutil.ReadFile(w.Filename) + count, err := w.lineCounter() if err != nil { return err } - w.maxlines_curlines = len(strings.Split(string(content), "\n")) + w.maxlines_curlines = count } else { w.maxlines_curlines = 0 } diff --git a/pkg/log/file_test.go b/pkg/log/file_test.go new file mode 100644 index 00000000000..458a39d754b --- /dev/null +++ b/pkg/log/file_test.go @@ -0,0 +1,44 @@ +package log + +import ( + "os" + "testing" + + . "github.com/smartystreets/goconvey/convey" +) + +func (w *FileLogWriter) WriteLine(line string) error { + n, err := w.mw.Write([]byte(line)) + if err != nil { + return err + } + w.docheck(n) + return nil +} + +func TestLogFile(t *testing.T) { + + Convey("When logging to file", t, func() { + fileLogWrite := NewFileWriter() + So(fileLogWrite, ShouldNotBeNil) + + fileLogWrite.Filename = "grafana_test.log" + err := fileLogWrite.Init() + So(err, ShouldBeNil) + + Convey("Log file is empty", func() { + So(fileLogWrite.maxlines_curlines, ShouldEqual, 0) + }) + + Convey("Logging should add lines", func() { + err := fileLogWrite.WriteLine("test1\n") + err = fileLogWrite.WriteLine("test2\n") + err = fileLogWrite.WriteLine("test3\n") + So(err, ShouldBeNil) + So(fileLogWrite.maxlines_curlines, ShouldEqual, 3) + }) + + err = os.Remove(fileLogWrite.Filename) + So(err, ShouldBeNil) + }) +} From 5ab72f48fc34ca9293f0e77b2bb4e6235d5cbff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 22 Nov 2017 14:44:18 +0100 Subject: [PATCH 08/13] Update latest.json --- latest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/latest.json b/latest.json index fa72bc4fadf..a746e92c3b3 100644 --- a/latest.json +++ b/latest.json @@ -1,4 +1,4 @@ { - "stable": "4.5.2", - "testing": "4.5.2" + "stable": "4.6.2", + "testing": "4.6.2" } From 5b05941dece292ac1ec58f7aa6402d3043fc3f6e Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Thu, 23 Nov 2017 13:08:44 +0100 Subject: [PATCH 09/13] docs: Improve delete snapshot documentation --- docs/sources/http_api/snapshot.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/http_api/snapshot.md b/docs/sources/http_api/snapshot.md index 5cecdb85fc3..dce3b0a9160 100644 --- a/docs/sources/http_api/snapshot.md +++ b/docs/sources/http_api/snapshot.md @@ -140,9 +140,9 @@ Content-Type: application/json } ``` -## Delete Snapshot by Id +## Delete Snapshot by deleteKey -`GET /api/snapshots-delete/:key` +`GET /api/snapshots-delete/:deleteKey` **Example Request**: From b7956ef4999995dd70b7898cfdf48a3e1736d52e Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Thu, 23 Nov 2017 14:53:23 +0100 Subject: [PATCH 10/13] More js to ts (#9966) * four files js to ts, fixed ng_model_on_blur * added /** @ngInject */ --- public/app/core/directives/misc.js | 163 ------------- public/app/core/directives/misc.ts | 226 ++++++++++++++++++ .../app/core/directives/ng_model_on_blur.ts | 109 ++++----- public/app/core/directives/tags.js | 135 ----------- public/app/core/directives/tags.ts | 131 ++++++++++ .../dashlinks/{module.js => module.ts} | 170 ++++++------- public/app/features/panellinks/module.js | 56 ----- public/app/features/panellinks/module.ts | 57 +++++ tslint.json | 2 +- 9 files changed, 553 insertions(+), 496 deletions(-) delete mode 100644 public/app/core/directives/misc.js create mode 100644 public/app/core/directives/misc.ts delete mode 100644 public/app/core/directives/tags.js create mode 100644 public/app/core/directives/tags.ts rename public/app/features/dashlinks/{module.js => module.ts} (50%) delete mode 100644 public/app/features/panellinks/module.js create mode 100644 public/app/features/panellinks/module.ts diff --git a/public/app/core/directives/misc.js b/public/app/core/directives/misc.js deleted file mode 100644 index f8c18ca847c..00000000000 --- a/public/app/core/directives/misc.js +++ /dev/null @@ -1,163 +0,0 @@ -define([ - 'angular', - 'require', - '../core_module', - 'app/core/utils/kbn', -], -function (angular, require, coreModule, kbn) { - 'use strict'; - - kbn = kbn.default; - - coreModule.default.directive('tip', function($compile) { - return { - restrict: 'E', - link: function(scope, elem, attrs) { - var _t = ''; - _t = _t.replace(/{/g, '\\{').replace(/}/g, '\\}'); - elem.replaceWith($compile(angular.element(_t))(scope)); - } - }; - }); - - coreModule.default.directive('clipboardButton', function() { - return { - scope: { - getText: '&clipboardButton' - }, - link: function(scope, elem) { - require(['clipboard'], function(Clipboard) { - scope.clipboard = new Clipboard(elem[0], { - text: function() { - return scope.getText(); - } - }); - }); - - scope.$on('$destroy', function() { - if (scope.clipboard) { - scope.clipboard.destroy(); - } - }); - } - }; - }); - - coreModule.default.directive('compile', function($compile) { - return { - restrict: 'A', - link: function(scope, element, attrs) { - scope.$watch(function(scope) { - return scope.$eval(attrs.compile); - }, function(value) { - element.html(value); - $compile(element.contents())(scope); - }); - } - }; - }); - - coreModule.default.directive('watchChange', function() { - return { - scope: { onchange: '&watchChange' }, - link: function(scope, element) { - element.on('input', function() { - scope.$apply(function () { - scope.onchange({ inputValue: element.val() }); - }); - }); - } - }; - }); - - coreModule.default.directive('editorOptBool', function($compile) { - return { - restrict: 'E', - link: function(scope, elem, attrs) { - var ngchange = attrs.change ? (' ng-change="' + attrs.change + '"') : ''; - var tip = attrs.tip ? (' ' + attrs.tip + '') : ''; - var showIf = attrs.showIf ? (' ng-show="' + attrs.showIf + '" ') : ''; - - var template = '
' + - ' ' + - '' + - ' '; - elem.replaceWith($compile(angular.element(template))(scope)); - } - }; - }); - - coreModule.default.directive('editorCheckbox', function($compile, $interpolate) { - return { - restrict: 'E', - link: function(scope, elem, attrs) { - var text = $interpolate(attrs.text)(scope); - var model = $interpolate(attrs.model)(scope); - var ngchange = attrs.change ? (' ng-change="' + attrs.change + '"') : ''; - var tip = attrs.tip ? (' ' + attrs.tip + '') : ''; - var label = ''; - - var template = - '' + - ' '; - - template = template + label; - elem.addClass('gf-form-checkbox'); - elem.html($compile(angular.element(template))(scope)); - } - }; - }); - - coreModule.default.directive('gfDropdown', function ($parse, $compile, $timeout) { - function buildTemplate(items, placement) { - var upclass = placement === 'top' ? 'dropup' : ''; - var ul = [ - '' - ]; - - angular.forEach(items, function (item, index) { - if (item.divider) { - return ul.splice(index + 1, 0, '
  • '); - } - - var li = '' + - '' + (item.text || '') + ''; - - if (item.submenu && item.submenu.length) { - li += buildTemplate(item.submenu).join('\n'); - } - - li += ''; - ul.splice(index + 1, 0, li); - }); - return ul; - } - - return { - restrict: 'EA', - scope: true, - link: function postLink(scope, iElement, iAttrs) { - var getter = $parse(iAttrs.gfDropdown), items = getter(scope); - $timeout(function () { - var placement = iElement.data('placement'); - var dropdown = angular.element(buildTemplate(items, placement).join('')); - dropdown.insertAfter(iElement); - $compile(iElement.next('ul.dropdown-menu'))(scope); - }); - - iElement.addClass('dropdown-toggle').attr('data-toggle', 'dropdown'); - } - }; - }); - -}); diff --git a/public/app/core/directives/misc.ts b/public/app/core/directives/misc.ts new file mode 100644 index 00000000000..3ec5add0c35 --- /dev/null +++ b/public/app/core/directives/misc.ts @@ -0,0 +1,226 @@ +import angular from "angular"; +import Clipboard from "clipboard"; +import coreModule from "../core_module"; +import kbn from "app/core/utils/kbn"; + +/** @ngInject */ +function tip($compile) { + return { + restrict: "E", + link: function(scope, elem, attrs) { + var _t = + '"; + _t = _t.replace(/{/g, "\\{").replace(/}/g, "\\}"); + elem.replaceWith($compile(angular.element(_t))(scope)); + } + }; +} + +function clipboardButton() { + return { + scope: { + getText: "&clipboardButton" + }, + link: function(scope, elem) { + scope.clipboard = new Clipboard(elem[0], { + text: function() { + return scope.getText(); + } + }); + + scope.$on("$destroy", function() { + if (scope.clipboard) { + scope.clipboard.destroy(); + } + }); + } + }; +} + +/** @ngInject */ +function compile($compile) { + return { + restrict: "A", + link: function(scope, element, attrs) { + scope.$watch( + function(scope) { + return scope.$eval(attrs.compile); + }, + function(value) { + element.html(value); + $compile(element.contents())(scope); + } + ); + } + }; +} + +function watchChange() { + return { + scope: { onchange: "&watchChange" }, + link: function(scope, element) { + element.on("input", function() { + scope.$apply(function() { + scope.onchange({ inputValue: element.val() }); + }); + }); + } + }; +} + +/** @ngInject */ +function editorOptBool($compile) { + return { + restrict: "E", + link: function(scope, elem, attrs) { + var ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : ""; + var tip = attrs.tip ? " " + attrs.tip + "" : ""; + var showIf = attrs.showIf ? ' ng-show="' + attrs.showIf + '" ' : ""; + + var template = + '
    " + + ' " + + '' + + ' '; + elem.replaceWith($compile(angular.element(template))(scope)); + } + }; +} + +/** @ngInject */ +function editorCheckbox($compile, $interpolate) { + return { + restrict: "E", + link: function(scope, elem, attrs) { + var text = $interpolate(attrs.text)(scope); + var model = $interpolate(attrs.model)(scope); + var ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : ""; + var tip = attrs.tip ? " " + attrs.tip + "" : ""; + var label = + '"; + + var template = + '' + + ' '; + + template = template + label; + elem.addClass("gf-form-checkbox"); + elem.html($compile(angular.element(template))(scope)); + } + }; +} + +/** @ngInject */ +function gfDropdown($parse, $compile, $timeout) { + function buildTemplate(items, placement?) { + var upclass = placement === "top" ? "dropup" : ""; + var ul = [ + '" + ]; + + for (let index = 0; index < items.length; index++) { + let item = items[index]; + + if (item.divider) { + ul.splice(index + 1, 0, '
  • '); + continue; + } + + var li = + "" + + '" + + (item.text || "") + + ""; + + if (item.submenu && item.submenu.length) { + li += buildTemplate(item.submenu).join("\n"); + } + + li += ""; + ul.splice(index + 1, 0, li); + } + + return ul; + } + + return { + restrict: "EA", + scope: true, + link: function postLink(scope, iElement, iAttrs) { + var getter = $parse(iAttrs.gfDropdown), + items = getter(scope); + $timeout(function() { + var placement = iElement.data("placement"); + var dropdown = angular.element( + buildTemplate(items, placement).join("") + ); + dropdown.insertAfter(iElement); + $compile(iElement.next("ul.dropdown-menu"))(scope); + }); + + iElement.addClass("dropdown-toggle").attr("data-toggle", "dropdown"); + } + }; +} + +coreModule.directive("tip", tip); +coreModule.directive("clipboardButton", clipboardButton); +coreModule.directive("compile", compile); +coreModule.directive("watchChange", watchChange); +coreModule.directive("editorOptBool", editorOptBool); +coreModule.directive("editorCheckbox", editorCheckbox); +coreModule.directive("gfDropdown", gfDropdown); diff --git a/public/app/core/directives/ng_model_on_blur.ts b/public/app/core/directives/ng_model_on_blur.ts index 383d04e3961..2f7de3bf20c 100644 --- a/public/app/core/directives/ng_model_on_blur.ts +++ b/public/app/core/directives/ng_model_on_blur.ts @@ -1,64 +1,57 @@ import coreModule from '../core_module'; import * as rangeUtil from 'app/core/utils/rangeutil'; -export class NgModelOnBlur { - constructor() { - return { - restrict: 'A', - priority: 1, - require: 'ngModel', - link: function(scope, elm, attr, ngModelCtrl) { - if (attr.type === 'radio' || attr.type === 'checkbox') { - return; +function ngModelOnBlur() { + return { + restrict: 'A', + priority: 1, + require: 'ngModel', + link: function(scope, elm, attr, ngModelCtrl) { + if (attr.type === 'radio' || attr.type === 'checkbox') { + return; + } + + elm.off('input keydown change'); + elm.bind('blur', function() { + scope.$apply(function() { + ngModelCtrl.$setViewValue(elm.val()); + }); + }); + } + }; +} + +function emptyToNull() { + return { + restrict: 'A', + require: 'ngModel', + link: function (scope, elm, attrs, ctrl) { + ctrl.$parsers.push(function (viewValue) { + if (viewValue === "") { return null; } + return viewValue; + }); + } + }; +} + +function validTimeSpan() { + return { + require: 'ngModel', + link: function(scope, elm, attrs, ctrl) { + ctrl.$validators.integer = function(modelValue, viewValue) { + if (ctrl.$isEmpty(modelValue)) { + return true; } - - elm.off('input keydown change'); - elm.bind('blur', function() { - scope.$apply(function() { - ngModelCtrl.$setViewValue(elm.val()); - }); - }); - } - }; - } + if (viewValue.indexOf('$') === 0 || viewValue.indexOf('+$') === 0) { + return true; // allow template variable + } + var info = rangeUtil.describeTextRange(viewValue); + return info.invalid !== true; + }; + } + }; } - -export class EmptyToNull { - constructor() { - return { - restrict: 'A', - require: 'ngModel', - link: function (scope, elm, attrs, ctrl) { - ctrl.$parsers.push(function (viewValue) { - if (viewValue === "") { return null; } - return viewValue; - }); - } - }; - } -} - -export class ValidTimeSpan { - constructor() { - return { - require: 'ngModel', - link: function(scope, elm, attrs, ctrl) { - ctrl.$validators.integer = function(modelValue, viewValue) { - if (ctrl.$isEmpty(modelValue)) { - return true; - } - if (viewValue.indexOf('$') === 0 || viewValue.indexOf('+$') === 0) { - return true; // allow template variable - } - var info = rangeUtil.describeTextRange(viewValue); - return info.invalid !== true; - }; - } - }; - } -} - -coreModule.directive('ngModelOnblur', NgModelOnBlur); -coreModule.directive('emptyToNull', EmptyToNull); -coreModule.directive('validTimeSpan', ValidTimeSpan); +coreModule.directive('ngModelOnblur', ngModelOnBlur); +coreModule.directive('emptyToNull', emptyToNull); +coreModule.directive('validTimeSpan', validTimeSpan); diff --git a/public/app/core/directives/tags.js b/public/app/core/directives/tags.js deleted file mode 100644 index a322673a342..00000000000 --- a/public/app/core/directives/tags.js +++ /dev/null @@ -1,135 +0,0 @@ -define([ - 'angular', - 'jquery', - '../core_module', - 'vendor/tagsinput/bootstrap-tagsinput.js', -], -function (angular, $, coreModule) { - 'use strict'; - - function djb2(str) { - var hash = 5381; - for (var i = 0; i < str.length; i++) { - hash = ((hash << 5) + hash) + str.charCodeAt(i); /* hash * 33 + c */ - } - return hash; - } - - function setColor(name, element) { - var hash = djb2(name.toLowerCase()); - var colors = [ - "#E24D42","#1F78C1","#BA43A9","#705DA0","#466803", - "#508642","#447EBC","#C15C17","#890F02","#757575", - "#0A437C","#6D1F62","#584477","#629E51","#2F4F4F", - "#BF1B00","#806EB7","#8a2eb8", "#699e00","#000000", - "#3F6833","#2F575E","#99440A","#E0752D","#0E4AB4", - "#58140C","#052B51","#511749","#3F2B5B", - ]; - var borderColors = [ - "#FF7368","#459EE7","#E069CF","#9683C6","#6C8E29", - "#76AC68","#6AA4E2","#E7823D","#AF3528","#9B9B9B", - "#3069A2","#934588","#7E6A9D","#88C477","#557575", - "#E54126","#A694DD","#B054DE", "#8FC426","#262626", - "#658E59","#557D84","#BF6A30","#FF9B53","#3470DA", - "#7E3A32","#2B5177","#773D6F","#655181", - ]; - var color = colors[Math.abs(hash % colors.length)]; - var borderColor = borderColors[Math.abs(hash % borderColors.length)]; - element.css("background-color", color); - element.css("border-color", borderColor); - } - - coreModule.default.directive('tagColorFromName', function() { - return { - scope: { tagColorFromName: "=" }, - link: function (scope, element) { - setColor(scope.tagColorFromName, element); - } - }; - }); - - coreModule.default.directive('bootstrapTagsinput', function() { - - function getItemProperty(scope, property) { - if (!property) { - return undefined; - } - - if (angular.isFunction(scope.$parent[property])) { - return scope.$parent[property]; - } - - return function(item) { - return item[property]; - }; - } - - return { - restrict: 'EA', - scope: { - model: '=ngModel', - onTagsUpdated: "&", - }, - template: '', - replace: false, - link: function(scope, element, attrs) { - - if (!angular.isArray(scope.model)) { - scope.model = []; - } - - var select = $('select', element); - - if (attrs.placeholder) { - select.attr('placeholder', attrs.placeholder); - } - - select.tagsinput({ - typeahead: { - source: angular.isFunction(scope.$parent[attrs.typeaheadSource]) ? scope.$parent[attrs.typeaheadSource] : null - }, - widthClass: attrs.widthClass, - itemValue: getItemProperty(scope, attrs.itemvalue), - itemText : getItemProperty(scope, attrs.itemtext), - tagClass : angular.isFunction(scope.$parent[attrs.tagclass]) ? - scope.$parent[attrs.tagclass] : function() { return attrs.tagclass; } - }); - - select.on('itemAdded', function(event) { - if (scope.model.indexOf(event.item) === -1) { - scope.model.push(event.item); - if (scope.onTagsUpdated) { - scope.onTagsUpdated(); - } - } - var tagElement = select.next().children("span").filter(function() { return $(this).text() === event.item; }); - setColor(event.item, tagElement); - }); - - select.on('itemRemoved', function(event) { - var idx = scope.model.indexOf(event.item); - if (idx !== -1) { - scope.model.splice(idx, 1); - if (scope.onTagsUpdated) { - scope.onTagsUpdated(); - } - } - }); - - scope.$watch("model", function() { - if (!angular.isArray(scope.model)) { - scope.model = []; - } - - select.tagsinput('removeAll'); - - for (var i = 0; i < scope.model.length; i++) { - select.tagsinput('add', scope.model[i]); - } - - }, true); - } - }; - }); - -}); diff --git a/public/app/core/directives/tags.ts b/public/app/core/directives/tags.ts new file mode 100644 index 00000000000..0f4d0990d47 --- /dev/null +++ b/public/app/core/directives/tags.ts @@ -0,0 +1,131 @@ +import angular from 'angular'; +import $ from 'jquery'; +import coreModule from '../core_module'; +import 'vendor/tagsinput/bootstrap-tagsinput.js'; + +function djb2(str) { + var hash = 5381; + for (var i = 0; i < str.length; i++) { + hash = ((hash << 5) + hash) + str.charCodeAt(i); /* hash * 33 + c */ + } + return hash; +} + +function setColor(name, element) { + var hash = djb2(name.toLowerCase()); + var colors = [ + "#E24D42","#1F78C1","#BA43A9","#705DA0","#466803", + "#508642","#447EBC","#C15C17","#890F02","#757575", + "#0A437C","#6D1F62","#584477","#629E51","#2F4F4F", + "#BF1B00","#806EB7","#8a2eb8", "#699e00","#000000", + "#3F6833","#2F575E","#99440A","#E0752D","#0E4AB4", + "#58140C","#052B51","#511749","#3F2B5B", + ]; + var borderColors = [ + "#FF7368","#459EE7","#E069CF","#9683C6","#6C8E29", + "#76AC68","#6AA4E2","#E7823D","#AF3528","#9B9B9B", + "#3069A2","#934588","#7E6A9D","#88C477","#557575", + "#E54126","#A694DD","#B054DE", "#8FC426","#262626", + "#658E59","#557D84","#BF6A30","#FF9B53","#3470DA", + "#7E3A32","#2B5177","#773D6F","#655181", + ]; + var color = colors[Math.abs(hash % colors.length)]; + var borderColor = borderColors[Math.abs(hash % borderColors.length)]; + element.css("background-color", color); + element.css("border-color", borderColor); +} + +function tagColorFromName() { + return { + scope: { tagColorFromName: "=" }, + link: function (scope, element) { + setColor(scope.tagColorFromName, element); + } + }; +} + +function bootstrapTagsinput() { + function getItemProperty(scope, property) { + if (!property) { + return undefined; + } + + if (angular.isFunction(scope.$parent[property])) { + return scope.$parent[property]; + } + + return function(item) { + return item[property]; + }; + } + + return { + restrict: 'EA', + scope: { + model: '=ngModel', + onTagsUpdated: "&", + }, + template: '', + replace: false, + link: function(scope, element, attrs) { + + if (!angular.isArray(scope.model)) { + scope.model = []; + } + + var select = $('select', element); + + if (attrs.placeholder) { + select.attr('placeholder', attrs.placeholder); + } + + select.tagsinput({ + typeahead: { + source: angular.isFunction(scope.$parent[attrs.typeaheadSource]) ? scope.$parent[attrs.typeaheadSource] : null + }, + widthClass: attrs.widthClass, + itemValue: getItemProperty(scope, attrs.itemvalue), + itemText : getItemProperty(scope, attrs.itemtext), + tagClass : angular.isFunction(scope.$parent[attrs.tagclass]) ? + scope.$parent[attrs.tagclass] : function() { return attrs.tagclass; } + }); + + select.on('itemAdded', function(event) { + if (scope.model.indexOf(event.item) === -1) { + scope.model.push(event.item); + if (scope.onTagsUpdated) { + scope.onTagsUpdated(); + } + } + var tagElement = select.next().children("span").filter(function() { return $(this).text() === event.item; }); + setColor(event.item, tagElement); + }); + + select.on('itemRemoved', function(event) { + var idx = scope.model.indexOf(event.item); + if (idx !== -1) { + scope.model.splice(idx, 1); + if (scope.onTagsUpdated) { + scope.onTagsUpdated(); + } + } + }); + + scope.$watch("model", function() { + if (!angular.isArray(scope.model)) { + scope.model = []; + } + + select.tagsinput('removeAll'); + + for (var i = 0; i < scope.model.length; i++) { + select.tagsinput('add', scope.model[i]); + } + + }, true); + } + }; +} + +coreModule.directive('tagColorFromName', tagColorFromName); +coreModule.directive('bootstrapTagsinput', bootstrapTagsinput); diff --git a/public/app/features/dashlinks/module.js b/public/app/features/dashlinks/module.ts similarity index 50% rename from public/app/features/dashlinks/module.js rename to public/app/features/dashlinks/module.ts index 620ad421e92..9f3b4055cee 100644 --- a/public/app/features/dashlinks/module.js +++ b/public/app/features/dashlinks/module.ts @@ -1,92 +1,89 @@ -define([ - 'angular', - 'lodash', -], -function (angular, _) { - 'use strict'; +import angular from 'angular'; +import _ from 'lodash'; - var module = angular.module('grafana.directives'); +var iconMap = { + "external link": "fa-external-link", + "dashboard": "fa-th-large", + "question": "fa-question", + "info": "fa-info", + "bolt": "fa-bolt", + "doc": "fa-file-text-o", + "cloud": "fa-cloud", +}; - var iconMap = { - "external link": "fa-external-link", - "dashboard": "fa-th-large", - "question": "fa-question", - "info": "fa-info", - "bolt": "fa-bolt", - "doc": "fa-file-text-o", - "cloud": "fa-cloud", +function dashLinksEditor() { + return { + restrict: 'E', + controller: 'DashLinkEditorCtrl', + templateUrl: 'public/app/features/dashlinks/editor.html', + link: function() { + } }; +} - module.directive('dashLinksEditor', function() { - return { - restrict: 'E', - controller: 'DashLinkEditorCtrl', - templateUrl: 'public/app/features/dashlinks/editor.html', - link: function() { +function dashLinksContainer() { + return { + scope: { + links: "=" + }, + restrict: 'E', + controller: 'DashLinksContainerCtrl', + template: '', + link: function() { } + }; +} + +/** @ngInject */ +function dashLink($compile, linkSrv) { + return { + restrict: 'E', + link: function(scope, elem) { + var link = scope.link; + var template = '
    ' + + '' + + ' '; + + if (link.asDropdown) { + template += ''; } - }; - }); - module.directive('dashLinksContainer', function() { - return { - scope: { - links: "=" - }, - restrict: 'E', - controller: 'DashLinksContainerCtrl', - template: '', - link: function() { } - }; - }); + template += '
    '; - module.directive('dashLink', function($compile, linkSrv) { - return { - restrict: 'E', - link: function(scope, elem) { - var link = scope.link; - var template = '
    ' + - '' + - ' '; + elem.html(template); + $compile(elem.contents())(scope); - if (link.asDropdown) { - template += ''; - } + var anchor = elem.find('a'); + var icon = elem.find('i'); + var span = elem.find('span'); - template += '
    '; - - elem.html(template); - $compile(elem.contents())(scope); - - var anchor = elem.find('a'); - var icon = elem.find('i'); - var span = elem.find('span'); - - function update() { - var linkInfo = linkSrv.getAnchorInfo(link); - span.text(linkInfo.title); - anchor.attr("href", linkInfo.href); - } - - // tooltip - elem.find('a').tooltip({ title: scope.link.tooltip, html: true, container: 'body' }); - icon.attr('class', 'fa fa-fw ' + scope.link.icon); - anchor.attr('target', scope.link.target); - - // fix for menus on the far right - if (link.asDropdown && scope.$last) { - elem.find('.dropdown-menu').addClass('pull-right'); - } - - update(); - scope.$on('refresh', update); + function update() { + var linkInfo = linkSrv.getAnchorInfo(link); + span.text(linkInfo.title); + anchor.attr("href", linkInfo.href); } - }; - }); - module.controller("DashLinksContainerCtrl", function($scope, $rootScope, $q, backendSrv, dashboardSrv, linkSrv) { + // tooltip + elem.find('a').tooltip({ title: scope.link.tooltip, html: true, container: 'body' }); + icon.attr('class', 'fa fa-fw ' + scope.link.icon); + anchor.attr('target', scope.link.target); + + // fix for menus on the far right + if (link.asDropdown && scope.$last) { + elem.find('.dropdown-menu').addClass('pull-right'); + } + + update(); + scope.$on('refresh', update); + } + }; +} + +export class DashLinksContainerCtrl { + /** @ngInject */ + constructor($scope, $rootScope, $q, backendSrv, dashboardSrv, linkSrv) { var currentDashId = dashboardSrv.getCurrent().id; function buildLinks(linkDef) { @@ -162,10 +159,12 @@ function (angular, _) { updateDashLinks(); $rootScope.onAppEvent('dash-links-updated', updateDashLinks, $scope); - }); - - module.controller('DashLinkEditorCtrl', function($scope, $rootScope) { + } +} +export class DashLinkEditorCtrl { + /** @ngInject */ + constructor($scope, $rootScope) { $scope.iconMap = iconMap; $scope.dashboard.links = $scope.dashboard.links || []; @@ -189,6 +188,11 @@ function (angular, _) { $scope.dashboard.updateSubmenuVisibility(); $scope.updated(); }; + } +} - }); -}); +angular.module('grafana.directives').directive('dashLinksEditor', dashLinksEditor); +angular.module('grafana.directives').directive('dashLinksContainer', dashLinksContainer); +angular.module('grafana.directives').directive('dashLink', dashLink); +angular.module('grafana.directives').controller("DashLinksContainerCtrl", DashLinksContainerCtrl); +angular.module('grafana.directives').controller('DashLinkEditorCtrl', DashLinkEditorCtrl); diff --git a/public/app/features/panellinks/module.js b/public/app/features/panellinks/module.js deleted file mode 100644 index a36317dc2b3..00000000000 --- a/public/app/features/panellinks/module.js +++ /dev/null @@ -1,56 +0,0 @@ -define([ - 'angular', - 'lodash', - './link_srv', -], -function (angular, _) { - 'use strict'; - - angular - .module('grafana.directives') - .directive('panelLinksEditor', function() { - return { - scope: { - panel: "=" - }, - restrict: 'E', - controller: 'PanelLinksEditorCtrl', - templateUrl: 'public/app/features/panellinks/module.html', - link: function() { - } - }; - }).controller('PanelLinksEditorCtrl', function($scope, backendSrv) { - - $scope.panel.links = $scope.panel.links || []; - - $scope.addLink = function() { - $scope.panel.links.push({ - type: 'dashboard', - }); - }; - - $scope.searchDashboards = function(queryStr, callback) { - backendSrv.search({query: queryStr}).then(function(hits) { - var dashboards = _.map(hits, function(dash) { - return dash.title; - }); - - callback(dashboards); - }); - }; - - $scope.dashboardChanged = function(link) { - backendSrv.search({query: link.dashboard}).then(function(hits) { - var dashboard = _.find(hits, {title: link.dashboard}); - if (dashboard) { - link.dashUri = dashboard.uri; - link.title = dashboard.title; - } - }); - }; - - $scope.deleteLink = function(link) { - $scope.panel.links = _.without($scope.panel.links, link); - }; - }); -}); diff --git a/public/app/features/panellinks/module.ts b/public/app/features/panellinks/module.ts new file mode 100644 index 00000000000..72debe2ffcf --- /dev/null +++ b/public/app/features/panellinks/module.ts @@ -0,0 +1,57 @@ +import angular from 'angular'; +import _ from 'lodash'; +import './link_srv'; + +function panelLinksEditor() { + return { + scope: { + panel: "=" + }, + restrict: 'E', + controller: 'PanelLinksEditorCtrl', + templateUrl: 'public/app/features/panellinks/module.html', + link: function() { + } + }; +} + +export class PanelLinksEditorCtrl { + /** @ngInject */ + constructor($scope, backendSrv) { + $scope.panel.links = $scope.panel.links || []; + + $scope.addLink = function() { + $scope.panel.links.push({ + type: 'dashboard', + }); + }; + + $scope.searchDashboards = function(queryStr, callback) { + backendSrv.search({query: queryStr}).then(function(hits) { + var dashboards = _.map(hits, function(dash) { + return dash.title; + }); + + callback(dashboards); + }); + }; + + $scope.dashboardChanged = function(link) { + backendSrv.search({query: link.dashboard}).then(function(hits) { + var dashboard = _.find(hits, {title: link.dashboard}); + if (dashboard) { + link.dashUri = dashboard.uri; + link.title = dashboard.title; + } + }); + }; + + $scope.deleteLink = function(link) { + $scope.panel.links = _.without($scope.panel.links, link); + }; + } +} + +angular.module('grafana.directives').directive('panelLinksEditor', panelLinksEditor) +.controller('PanelLinksEditorCtrl', PanelLinksEditorCtrl); + diff --git a/tslint.json b/tslint.json index f1b414c916e..789e83975db 100644 --- a/tslint.json +++ b/tslint.json @@ -17,7 +17,7 @@ "max-line-length": [true, 140], "member-access": false, "no-arg": true, - "no-bitwise": true, + "no-bitwise": false, "no-console": [true, "debug", "info", From b94839574c91219efe92716bc0e79fc35b9b4a22 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Thu, 23 Nov 2017 17:04:50 +0100 Subject: [PATCH 11/13] migration of org files from js to ts (#9974) * migration of org files from js to ts * more migration of org files to ts * minor fix to change_password * renamed files --- public/app/core/config.ts | 2 ++ public/app/features/org/all.js | 12 ----------- public/app/features/org/all.ts | 10 +++++++++ ...ssword_ctrl.js => change_password_ctrl.ts} | 21 +++++++------------ .../org/{newOrgCtrl.js => new_org_ctrl.ts} | 21 +++++++------------ ...orgApiKeysCtrl.js => org_api_keys_ctrl.ts} | 17 +++++++-------- ...{orgDetailsCtrl.js => org_details_ctrl.ts} | 17 +++++++-------- ...{select_org_ctrl.js => select_org_ctrl.ts} | 21 +++++++------------ ...{userInviteCtrl.js => user_invite_ctrl.ts} | 20 ++++++++---------- 9 files changed, 59 insertions(+), 82 deletions(-) delete mode 100644 public/app/features/org/all.js create mode 100644 public/app/features/org/all.ts rename public/app/features/org/{change_password_ctrl.js => change_password_ctrl.ts} (67%) rename public/app/features/org/{newOrgCtrl.js => new_org_ctrl.ts} (57%) rename public/app/features/org/{orgApiKeysCtrl.js => org_api_keys_ctrl.ts} (80%) rename public/app/features/org/{orgDetailsCtrl.js => org_details_ctrl.ts} (75%) rename public/app/features/org/{select_org_ctrl.js => select_org_ctrl.ts} (63%) rename public/app/features/org/{userInviteCtrl.js => user_invite_ctrl.ts} (80%) diff --git a/public/app/core/config.ts b/public/app/core/config.ts index f4898b4e08b..63f01bea458 100644 --- a/public/app/core/config.ts +++ b/public/app/core/config.ts @@ -15,6 +15,8 @@ class Settings { disableLoginForm: boolean; defaultDatasource: string; alertingEnabled: boolean; + authProxyEnabled: boolean; + ldapEnabled: boolean; constructor(options) { var defaults = { diff --git a/public/app/features/org/all.js b/public/app/features/org/all.js deleted file mode 100644 index e206583a8c7..00000000000 --- a/public/app/features/org/all.js +++ /dev/null @@ -1,12 +0,0 @@ -define([ - './org_users_ctrl', - './profile_ctrl', - './org_users_ctrl', - './select_org_ctrl', - './change_password_ctrl', - './newOrgCtrl', - './userInviteCtrl', - './orgApiKeysCtrl', - './orgDetailsCtrl', - './prefs_control', -], function () {}); diff --git a/public/app/features/org/all.ts b/public/app/features/org/all.ts new file mode 100644 index 00000000000..6b3eb67e7fb --- /dev/null +++ b/public/app/features/org/all.ts @@ -0,0 +1,10 @@ +import './org_users_ctrl'; +import './profile_ctrl'; +import './org_users_ctrl'; +import './select_org_ctrl'; +import './change_password_ctrl'; +import './new_org_ctrl'; +import './user_invite_ctrl'; +import './org_api_keys_ctrl'; +import './org_details_ctrl'; +import './prefs_control'; diff --git a/public/app/features/org/change_password_ctrl.js b/public/app/features/org/change_password_ctrl.ts similarity index 67% rename from public/app/features/org/change_password_ctrl.js rename to public/app/features/org/change_password_ctrl.ts index e1b9b8c9b37..9d4d1e9a770 100644 --- a/public/app/features/org/change_password_ctrl.js +++ b/public/app/features/org/change_password_ctrl.ts @@ -1,16 +1,10 @@ -define([ - 'angular', - 'app/core/config', -], -function (angular, config) { - 'use strict'; +import angular from 'angular'; +import config from 'app/core/config'; - config = config.default; - - var module = angular.module('grafana.controllers'); - - module.controller('ChangePasswordCtrl', function($scope, backendSrv, $location, navModelSrv) { +export class ChangePasswordCtrl { + /** @ngInject **/ + constructor($scope, backendSrv, $location, navModelSrv) { $scope.command = {}; $scope.authProxyEnabled = config.authProxyEnabled; $scope.ldapEnabled = config.ldapEnabled; @@ -28,6 +22,7 @@ function (angular, config) { $location.path("profile"); }); }; + } +} - }); -}); +angular.module('grafana.controllers').controller('ChangePasswordCtrl', ChangePasswordCtrl); diff --git a/public/app/features/org/newOrgCtrl.js b/public/app/features/org/new_org_ctrl.ts similarity index 57% rename from public/app/features/org/newOrgCtrl.js rename to public/app/features/org/new_org_ctrl.ts index cf8e239d065..72601df248f 100644 --- a/public/app/features/org/newOrgCtrl.js +++ b/public/app/features/org/new_org_ctrl.ts @@ -1,16 +1,10 @@ -define([ - 'angular', - 'app/core/config', -], -function (angular, config) { - 'use strict'; +import angular from 'angular'; +import config from 'app/core/config'; - config = config.default; - - var module = angular.module('grafana.controllers'); - - module.controller('NewOrgCtrl', function($scope, $http, backendSrv, navModelSrv) { +export class NewOrgCtrl { + /** @ngInject **/ + constructor($scope, $http, backendSrv, navModelSrv) { $scope.navModel = navModelSrv.getOrgNav(0); $scope.newOrg = {name: ''}; @@ -21,6 +15,7 @@ function (angular, config) { }); }); }; + } +} - }); -}); +angular.module('grafana.controllers').controller('NewOrgCtrl', NewOrgCtrl); diff --git a/public/app/features/org/orgApiKeysCtrl.js b/public/app/features/org/org_api_keys_ctrl.ts similarity index 80% rename from public/app/features/org/orgApiKeysCtrl.js rename to public/app/features/org/org_api_keys_ctrl.ts index 345f21cabfd..14b1b2b467d 100644 --- a/public/app/features/org/orgApiKeysCtrl.js +++ b/public/app/features/org/org_api_keys_ctrl.ts @@ -1,13 +1,9 @@ -define([ - 'angular', -], -function (angular) { - 'use strict'; +import angular from 'angular'; - var module = angular.module('grafana.controllers'); - - module.controller('OrgApiKeysCtrl', function($scope, $http, backendSrv, navModelSrv) { +export class OrgApiKeysCtrl { + /** @ngInject **/ + constructor ($scope, $http, backendSrv, navModelSrv) { $scope.navModel = navModelSrv.getOrgNav(0); $scope.roleTypes = ['Viewer', 'Editor', 'Admin']; $scope.token = { role: 'Viewer' }; @@ -43,6 +39,7 @@ function (angular) { }; $scope.init(); + } +} - }); -}); +angular.module('grafana.controllers').controller('OrgApiKeysCtrl', OrgApiKeysCtrl); diff --git a/public/app/features/org/orgDetailsCtrl.js b/public/app/features/org/org_details_ctrl.ts similarity index 75% rename from public/app/features/org/orgDetailsCtrl.js rename to public/app/features/org/org_details_ctrl.ts index 08c965fd333..b991b8a0b7c 100644 --- a/public/app/features/org/orgDetailsCtrl.js +++ b/public/app/features/org/org_details_ctrl.ts @@ -1,13 +1,9 @@ -define([ - 'angular', -], -function (angular) { - 'use strict'; +import angular from 'angular'; - var module = angular.module('grafana.controllers'); - - module.controller('OrgDetailsCtrl', function($scope, $http, backendSrv, contextSrv, navModelSrv) { +export class OrgDetailsCtrl { + /** @ngInject **/ + constructor($scope, $http, backendSrv, contextSrv, navModelSrv) { $scope.init = function() { $scope.getOrgInfo(); $scope.navModel = navModelSrv.getOrgNav(0); @@ -33,6 +29,7 @@ function (angular) { }; $scope.init(); + } +} - }); -}); +angular.module('grafana.controllers').controller('OrgDetailsCtrl', OrgDetailsCtrl); diff --git a/public/app/features/org/select_org_ctrl.js b/public/app/features/org/select_org_ctrl.ts similarity index 63% rename from public/app/features/org/select_org_ctrl.js rename to public/app/features/org/select_org_ctrl.ts index a6954dc2f9a..28a9b057e7f 100644 --- a/public/app/features/org/select_org_ctrl.js +++ b/public/app/features/org/select_org_ctrl.ts @@ -1,16 +1,10 @@ -define([ - 'angular', - 'app/core/config', -], -function (angular, config) { - 'use strict'; +import angular from 'angular'; +import config from 'app/core/config'; - config = config.default; - - var module = angular.module('grafana.controllers'); - - module.controller('SelectOrgCtrl', function($scope, backendSrv, contextSrv) { +export class SelectOrgCtrl { + /** @ngInject **/ + constructor($scope, backendSrv, contextSrv) { contextSrv.sidemenu = false; $scope.init = function() { @@ -30,6 +24,7 @@ function (angular, config) { }; $scope.init(); + } +} - }); -}); +angular.module('grafana.controllers').controller('SelectOrgCtrl', SelectOrgCtrl); diff --git a/public/app/features/org/userInviteCtrl.js b/public/app/features/org/user_invite_ctrl.ts similarity index 80% rename from public/app/features/org/userInviteCtrl.js rename to public/app/features/org/user_invite_ctrl.ts index 52b307612b3..cd6da83f10a 100644 --- a/public/app/features/org/userInviteCtrl.js +++ b/public/app/features/org/user_invite_ctrl.ts @@ -1,14 +1,10 @@ -define([ - 'angular', - 'lodash', -], -function (angular, _) { - 'use strict'; +import angular from 'angular'; +import _ from 'lodash'; - var module = angular.module('grafana.controllers'); - - module.controller('UserInviteCtrl', function($scope, backendSrv) { +export class UserInviteCtrl { + /** @ngInject **/ + constructor($scope, backendSrv) { $scope.invites = [ {name: '', email: '', role: 'Editor'}, ]; @@ -44,5 +40,7 @@ function (angular, _) { } }); }; - }); -}); + } +} + +angular.module('grafana.controllers').controller('UserInviteCtrl', UserInviteCtrl); From 3acf1063032c5a86a3947457e1ca6930198f6e6f Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Thu, 23 Nov 2017 17:05:08 +0100 Subject: [PATCH 12/13] migrated admin files to ts (#9975) --- public/app/features/admin/admin.ts | 6 +++--- ...inEditOrgCtrl.js => admin_edit_org_ctrl.ts} | 18 +++++++----------- ...EditUserCtrl.js => admin_edit_user_ctrl.ts} | 18 ++++++++---------- ...ListOrgsCtrl.js => admin_list_orgs_ctrl.ts} | 18 +++++++----------- 4 files changed, 25 insertions(+), 35 deletions(-) rename public/app/features/admin/{adminEditOrgCtrl.js => admin_edit_org_ctrl.ts} (81%) rename public/app/features/admin/{adminEditUserCtrl.js => admin_edit_user_ctrl.ts} (91%) rename public/app/features/admin/{adminListOrgsCtrl.js => admin_list_orgs_ctrl.ts} (76%) diff --git a/public/app/features/admin/admin.ts b/public/app/features/admin/admin.ts index 669e4a9c982..5f640754aef 100644 --- a/public/app/features/admin/admin.ts +++ b/public/app/features/admin/admin.ts @@ -1,7 +1,7 @@ import AdminListUsersCtrl from './admin_list_users_ctrl'; -import './adminListOrgsCtrl'; -import './adminEditOrgCtrl'; -import './adminEditUserCtrl'; +import './admin_list_orgs_ctrl'; +import './admin_edit_org_ctrl'; +import './admin_edit_user_ctrl'; import coreModule from 'app/core/core_module'; diff --git a/public/app/features/admin/adminEditOrgCtrl.js b/public/app/features/admin/admin_edit_org_ctrl.ts similarity index 81% rename from public/app/features/admin/adminEditOrgCtrl.js rename to public/app/features/admin/admin_edit_org_ctrl.ts index 3121f5eb27b..d7e8a5109d5 100644 --- a/public/app/features/admin/adminEditOrgCtrl.js +++ b/public/app/features/admin/admin_edit_org_ctrl.ts @@ -1,13 +1,9 @@ -define([ - 'angular', -], -function (angular) { - 'use strict'; +import angular from 'angular'; - var module = angular.module('grafana.controllers'); - - module.controller('AdminEditOrgCtrl', function($scope, $routeParams, backendSrv, $location, navModelSrv) { +export class AdminEditOrgCtrl { + /** @ngInject */ + constructor($scope, $routeParams, backendSrv, $location, navModelSrv) { $scope.init = function() { $scope.navModel = navModelSrv.getAdminNav(); @@ -48,7 +44,7 @@ function (angular) { }; $scope.init(); + } +} - }); - -}); +angular.module('grafana.controllers').controller('AdminEditOrgCtrl', AdminEditOrgCtrl); diff --git a/public/app/features/admin/adminEditUserCtrl.js b/public/app/features/admin/admin_edit_user_ctrl.ts similarity index 91% rename from public/app/features/admin/adminEditUserCtrl.js rename to public/app/features/admin/admin_edit_user_ctrl.ts index 007a5d79153..0e56584aed1 100644 --- a/public/app/features/admin/adminEditUserCtrl.js +++ b/public/app/features/admin/admin_edit_user_ctrl.ts @@ -1,13 +1,10 @@ -define([ - 'angular', - 'lodash', -], -function (angular, _) { - 'use strict'; +import angular from 'angular'; +import _ from 'lodash'; - var module = angular.module('grafana.controllers'); +export class AdminEditUserCtrl { - module.controller('AdminEditUserCtrl', function($scope, $routeParams, backendSrv, $location, navModelSrv) { + /** @ngInject */ + constructor($scope, $routeParams, backendSrv, $location, navModelSrv) { $scope.user = {}; $scope.newOrg = { name: '', role: 'Editor' }; $scope.permissions = {}; @@ -106,6 +103,7 @@ function (angular, _) { }; $scope.init(); + } +} - }); -}); +angular.module('grafana.controllers').controller('AdminEditUserCtrl', AdminEditUserCtrl); diff --git a/public/app/features/admin/adminListOrgsCtrl.js b/public/app/features/admin/admin_list_orgs_ctrl.ts similarity index 76% rename from public/app/features/admin/adminListOrgsCtrl.js rename to public/app/features/admin/admin_list_orgs_ctrl.ts index c7f8225ea7e..34d1eca0f2f 100644 --- a/public/app/features/admin/adminListOrgsCtrl.js +++ b/public/app/features/admin/admin_list_orgs_ctrl.ts @@ -1,13 +1,9 @@ -define([ - 'angular', -], -function (angular) { - 'use strict'; +import angular from 'angular'; - var module = angular.module('grafana.controllers'); - - module.controller('AdminListOrgsCtrl', function($scope, backendSrv, navModelSrv) { +export class AdminListOrgsCtrl { + /** @ngInject */ + constructor($scope, backendSrv, navModelSrv) { $scope.init = function() { $scope.navModel = navModelSrv.getAdminNav(); $scope.getOrgs(); @@ -35,7 +31,7 @@ function (angular) { }; $scope.init(); + } +} - }); - -}); +angular.module('grafana.controllers').controller('AdminListOrgsCtrl', AdminListOrgsCtrl); From 4ce1ee4120b929de8d6196f635bc126a193e2920 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Thu, 23 Nov 2017 17:05:27 +0100 Subject: [PATCH 13/13] Migrate gfunc to ts (#9973) * migrated gfunc from js to ts * deleted gfunc.js, small fixes in gfunc.ts --- .../app/plugins/datasource/graphite/gfunc.js | 981 -------------- .../app/plugins/datasource/graphite/gfunc.ts | 1143 ++++++++++------- 2 files changed, 656 insertions(+), 1468 deletions(-) delete mode 100644 public/app/plugins/datasource/graphite/gfunc.js diff --git a/public/app/plugins/datasource/graphite/gfunc.js b/public/app/plugins/datasource/graphite/gfunc.js deleted file mode 100644 index 94f4ca4c988..00000000000 --- a/public/app/plugins/datasource/graphite/gfunc.js +++ /dev/null @@ -1,981 +0,0 @@ -define([ - 'lodash', - 'jquery', - 'app/core/utils/version' -], -function (_, $, version) { - 'use strict'; - - var index = []; - var categories = { - Combine: [], - Transform: [], - Calculate: [], - Filter: [], - Special: [] - }; - - function addFuncDef(funcDef) { - funcDef.params = funcDef.params || []; - funcDef.defaultParams = funcDef.defaultParams || []; - - if (funcDef.category) { - funcDef.category.push(funcDef); - } - index[funcDef.name] = funcDef; - index[funcDef.shortName || funcDef.name] = funcDef; - } - - var optionalSeriesRefArgs = [ - { name: 'other', type: 'value_or_series', optional: true }, - { name: 'other', type: 'value_or_series', optional: true }, - { name: 'other', type: 'value_or_series', optional: true }, - { name: 'other', type: 'value_or_series', optional: true }, - { name: 'other', type: 'value_or_series', optional: true } - ]; - - addFuncDef({ - name: 'scaleToSeconds', - category: categories.Transform, - params: [{ name: 'seconds', type: 'int' }], - defaultParams: [1], - }); - - addFuncDef({ - name: 'perSecond', - category: categories.Transform, - params: [{ name: "max value", type: "int", optional: true }], - defaultParams: [], - }); - - addFuncDef({ - name: "holtWintersForecast", - category: categories.Calculate, - }); - - addFuncDef({ - name: "holtWintersConfidenceBands", - category: categories.Calculate, - params: [{ name: "delta", type: 'int' }], - defaultParams: [3] - }); - - addFuncDef({ - name: "holtWintersAberration", - category: categories.Calculate, - params: [{ name: "delta", type: 'int' }], - defaultParams: [3] - }); - - addFuncDef({ - name: "nPercentile", - category: categories.Calculate, - params: [{ name: "Nth percentile", type: 'int' }], - defaultParams: [95] - }); - - addFuncDef({ - name: 'diffSeries', - params: optionalSeriesRefArgs, - defaultParams: ['#A'], - category: categories.Calculate, - }); - - addFuncDef({ - name: 'stddevSeries', - params: optionalSeriesRefArgs, - defaultParams: [''], - category: categories.Calculate, - }); - - addFuncDef({ - name: 'divideSeries', - params: optionalSeriesRefArgs, - defaultParams: ['#A'], - category: categories.Calculate, - }); - - addFuncDef({ - name: 'multiplySeries', - params: optionalSeriesRefArgs, - defaultParams: ['#A'], - category: categories.Calculate, - }); - - addFuncDef({ - name: 'asPercent', - params: optionalSeriesRefArgs, - defaultParams: ['#A'], - category: categories.Calculate, - }); - - addFuncDef({ - name: 'group', - params: optionalSeriesRefArgs, - defaultParams: ['#A', '#B'], - category: categories.Combine, - }); - - addFuncDef({ - name: 'sumSeries', - shortName: 'sum', - category: categories.Combine, - params: optionalSeriesRefArgs, - defaultParams: [''], - }); - - addFuncDef({ - name: 'averageSeries', - shortName: 'avg', - category: categories.Combine, - params: optionalSeriesRefArgs, - defaultParams: [''], - }); - - addFuncDef({ - name: 'rangeOfSeries', - category: categories.Combine - }); - - addFuncDef({ - name: 'percentileOfSeries', - category: categories.Combine, - params: [{ name: 'n', type: 'int' }, { name: 'interpolate', type: 'boolean', options: ['true', 'false'] }], - defaultParams: [95, 'false'] - }); - - addFuncDef({ - name: 'sumSeriesWithWildcards', - category: categories.Combine, - params: [ - { name: "node", type: "int" }, - { name: "node", type: "int", optional: true }, - { name: "node", type: "int", optional: true }, - { name: "node", type: "int", optional: true } - ], - defaultParams: [3] - }); - - addFuncDef({ - name: 'maxSeries', - shortName: 'max', - category: categories.Combine, - }); - - addFuncDef({ - name: 'minSeries', - shortName: 'min', - category: categories.Combine, - }); - - addFuncDef({ - name: 'averageSeriesWithWildcards', - category: categories.Combine, - params: [ - { name: "node", type: "int" }, - { name: "node", type: "int", optional: true }, - ], - defaultParams: [3] - }); - - addFuncDef({ - name: "alias", - category: categories.Special, - params: [{ name: "alias", type: 'string' }], - defaultParams: ['alias'] - }); - - addFuncDef({ - name: "aliasSub", - category: categories.Special, - params: [{ name: "search", type: 'string' }, { name: "replace", type: 'string' }], - defaultParams: ['', '\\1'] - }); - - addFuncDef({ - name: "stacked", - category: categories.Special, - params: [{ name: "stack", type: 'string' }], - defaultParams: ['stacked'] - }); - - addFuncDef({ - name: "consolidateBy", - category: categories.Special, - params: [ - { - name: 'function', - type: 'string', - options: ['sum', 'average', 'min', 'max'] - } - ], - defaultParams: ['max'] - }); - - addFuncDef({ - name: "cumulative", - category: categories.Special, - params: [], - defaultParams: [] - }); - - addFuncDef({ - name: "groupByNode", - category: categories.Special, - params: [ - { - name: "node", - type: "int", - options: [0,1,2,3,4,5,6,7,8,9,10,12] - }, - { - name: "function", - type: "string", - options: ['sum', 'avg', 'maxSeries'] - } - ], - defaultParams: [3, "sum"] - }); - - addFuncDef({ - name: 'aliasByNode', - category: categories.Special, - params: [ - { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] }, - { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true }, - { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true }, - { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true }, - ], - defaultParams: [3] - }); - - addFuncDef({ - name: 'substr', - category: categories.Special, - params: [ - { name: "start", type: "int", options: [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,12] }, - { name: "stop", type: "int", options: [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,12] }, - ], - defaultParams: [0, 0] - }); - - addFuncDef({ - name: 'sortByName', - category: categories.Special, - params: [{ name: 'natural', type: 'boolean', options: ['true', 'false'], optional: true }], - defaultParams: ['false'] - }); - - addFuncDef({ - name: 'sortByMaxima', - category: categories.Special - }); - - addFuncDef({ - name: 'sortByMinima', - category: categories.Special - }); - - addFuncDef({ - name: 'sortByTotal', - category: categories.Special - }); - - addFuncDef({ - name: 'aliasByMetric', - category: categories.Special, - }); - - addFuncDef({ - name: 'randomWalk', - fake: true, - category: categories.Special, - params: [{ name: "name", type: "string", }], - defaultParams: ['randomWalk'] - }); - - addFuncDef({ - name: 'countSeries', - category: categories.Special - }); - - addFuncDef({ - name: 'constantLine', - category: categories.Special, - params: [{ name: "value", type: "int", }], - defaultParams: [10] - }); - - addFuncDef({ - name: 'cactiStyle', - category: categories.Special, - }); - - addFuncDef({ - name: 'keepLastValue', - category: categories.Special, - params: [{ name: "n", type: "int", }], - defaultParams: [100] - }); - - addFuncDef({ - name: "changed", - category: categories.Special, - params: [], - defaultParams: [] - }); - - addFuncDef({ - name: 'scale', - category: categories.Transform, - params: [{ name: "factor", type: "int", }], - defaultParams: [1] - }); - - addFuncDef({ - name: 'offset', - category: categories.Transform, - params: [{ name: "amount", type: "int", }], - defaultParams: [10] - }); - - addFuncDef({ - name: 'transformNull', - category: categories.Transform, - params: [{ name: "amount", type: "int", }], - defaultParams: [0] - }); - - addFuncDef({ - name: 'integral', - category: categories.Transform, - }); - - addFuncDef({ - name: 'derivative', - category: categories.Transform, - }); - - addFuncDef({ - name: 'nonNegativeDerivative', - category: categories.Transform, - params: [{ name: "max value or 0", type: "int", optional: true }], - defaultParams: [''] - }); - - addFuncDef({ - name: 'timeShift', - category: categories.Transform, - params: [{ name: "amount", type: "select", options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'] }], - defaultParams: ['1d'] - }); - - addFuncDef({ - name: 'timeStack', - category: categories.Transform, - params: [ - { name: "timeShiftUnit", type: "select", options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'] }, - { name: "timeShiftStart", type: "int" }, - { name: "timeShiftEnd", type: "int" } - ], - defaultParams: ['1d', 0, 7] - }); - - addFuncDef({ - name: 'summarize', - category: categories.Transform, - params: [ - { name: "interval", type: "string" }, - { name: "func", type: "select", options: ['sum', 'avg', 'min', 'max', 'last'] }, - { name: "alignToFrom", type: "boolean", optional: true, options: ['false', 'true'] }, - ], - defaultParams: ['1h', 'sum', 'false'] - }); - - addFuncDef({ - name: 'smartSummarize', - category: categories.Transform, - params: [{ name: "interval", type: "string" }, { name: "func", type: "select", options: ['sum', 'avg', 'min', 'max', 'last'] }], - defaultParams: ['1h', 'sum'] - }); - - addFuncDef({ - name: 'absolute', - category: categories.Transform, - }); - - addFuncDef({ - name: 'hitcount', - category: categories.Transform, - params: [{ name: "interval", type: "string" }], - defaultParams: ['10s'] - }); - - addFuncDef({ - name: 'log', - category: categories.Transform, - params: [{ name: "base", type: "int" }], - defaultParams: ['10'] - }); - - addFuncDef({ - name: 'averageAbove', - category: categories.Filter, - params: [{ name: "n", type: "int", }], - defaultParams: [25] - }); - - addFuncDef({ - name: 'averageBelow', - category: categories.Filter, - params: [{ name: "n", type: "int", }], - defaultParams: [25] - }); - - addFuncDef({ - name: 'currentAbove', - category: categories.Filter, - params: [{ name: "n", type: "int", }], - defaultParams: [25] - }); - - addFuncDef({ - name: 'currentBelow', - category: categories.Filter, - params: [{ name: "n", type: "int", }], - defaultParams: [25] - }); - - addFuncDef({ - name: 'maximumAbove', - category: categories.Filter, - params: [{ name: "value", type: "int" }], - defaultParams: [0] - }); - - addFuncDef({ - name: 'maximumBelow', - category: categories.Filter, - params: [{ name: "value", type: "int" }], - defaultParams: [0] - }); - - addFuncDef({ - name: 'minimumAbove', - category: categories.Filter, - params: [{ name: "value", type: "int" }], - defaultParams: [0] - }); - - addFuncDef({ - name: 'minimumBelow', - category: categories.Filter, - params: [{ name: "value", type: "int" }], - defaultParams: [0] - }); - - addFuncDef({ - name: 'limit', - category: categories.Filter, - params: [{ name: "n", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'mostDeviant', - category: categories.Filter, - params: [{ name: "n", type: "int" }], - defaultParams: [10] - }); - - addFuncDef({ - name: "exclude", - category: categories.Filter, - params: [{ name: "exclude", type: 'string' }], - defaultParams: ['exclude'] - }); - - addFuncDef({ - name: 'highestCurrent', - category: categories.Filter, - params: [{ name: "count", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'highestMax', - category: categories.Filter, - params: [{ name: "count", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'lowestCurrent', - category: categories.Filter, - params: [{ name: "count", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'movingAverage', - category: categories.Filter, - params: [{ name: "windowSize", type: "int_or_interval", options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }], - defaultParams: [10] - }); - - addFuncDef({ - name: 'movingMedian', - category: categories.Filter, - params: [{ name: "windowSize", type: "int_or_interval", options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }], - defaultParams: ['5'] - }); - - addFuncDef({ - name: 'stdev', - category: categories.Filter, - params: [{ name: "n", type: "int" }, { name: "tolerance", type: "int" }], - defaultParams: [5,0.1] - }); - - addFuncDef({ - name: 'highestAverage', - category: categories.Filter, - params: [{ name: "count", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'lowestAverage', - category: categories.Filter, - params: [{ name: "count", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'removeAbovePercentile', - category: categories.Filter, - params: [{ name: "n", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'removeAboveValue', - category: categories.Filter, - params: [{ name: "n", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'removeBelowPercentile', - category: categories.Filter, - params: [{ name: "n", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'removeBelowValue', - category: categories.Filter, - params: [{ name: "n", type: "int" }], - defaultParams: [5] - }); - - addFuncDef({ - name: 'useSeriesAbove', - category: categories.Filter, - params: [ - { name: "value", type: "int" }, - { name: "search", type: "string" }, - { name: "replace", type: "string" } - ], - defaultParams: [0, 'search', 'replace'] - }); - - //////////////////// - // Graphite 1.0.x // - //////////////////// - - addFuncDef({ - name: 'aggregateLine', - category: categories.Combine, - params: [{ name: "func", type: "select", options: ['sum', 'avg', 'min', 'max', 'last']}], - defaultParams: ['avg'], - version: '1.0' - }); - - addFuncDef({ - name: 'averageOutsidePercentile', - category: categories.Filter, - params: [{ name: "n", type: "int", }], - defaultParams: [95], - version: '1.0' - }); - - addFuncDef({ - name: 'delay', - category: categories.Transform, - params: [{ name: 'steps', type: 'int', }], - defaultParams: [1], - version: '1.0' - }); - - addFuncDef({ - name: 'exponentialMovingAverage', - category: categories.Calculate, - params: [{ name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }], - defaultParams: [10], - version: '1.0' - }); - - addFuncDef({ - name: 'fallbackSeries', - category: categories.Special, - params: [{ name: 'fallback', type: 'string' }], - defaultParams: ['constantLine(0)'], - version: '1.0' - }); - - addFuncDef({ - name: "grep", - category: categories.Filter, - params: [{ name: "grep", type: 'string' }], - defaultParams: ['grep'], - version: '1.0' - }); - - addFuncDef({ - name: "groupByNodes", - category: categories.Special, - params: [ - { - name: "function", - type: "string", - options: ['sum', 'avg', 'maxSeries'] - }, - { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] }, - { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true }, - { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true }, - { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true }, - ], - defaultParams: ["sum", 3], - version: '1.0' - }); - - addFuncDef({ - name: 'integralByInterval', - category: categories.Transform, - params: [{ name: "intervalUnit", type: "select", options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'] }], - defaultParams: ['1d'], - version: '1.0' - }); - - addFuncDef({ - name: 'interpolate', - category: categories.Transform, - params: [{ name: 'limit', type: 'int', optional: true}], - defaultParams: [], - version: '1.0' - }); - - addFuncDef({ - name: 'invert', - category: categories.Transform, - version: '1.0' - }); - - addFuncDef({ - name: 'isNonNull', - category: categories.Combine, - version: '1.0' - }); - - addFuncDef({ - name: 'linearRegression', - category: categories.Calculate, - params: [ - { name: "startSourceAt", type: "select", options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'], optional: true }, - { name: "endSourceAt", type: "select", options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'], optional: true } - ], - defaultParams: [], - version: '1.0' - }); - - addFuncDef({ - name: 'mapSeries', - shortName: 'map', - params: [{ name: "node", type: 'int' }], - defaultParams: [3], - category: categories.Combine, - version: '1.0' - }); - - addFuncDef({ - name: 'movingMin', - category: categories.Calculate, - params: [{ name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }], - defaultParams: [10], - version: '1.0' - }); - - addFuncDef({ - name: 'movingMax', - category: categories.Calculate, - params: [{ name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }], - defaultParams: [10], - version: '1.0' - }); - - addFuncDef({ - name: 'movingSum', - category: categories.Calculate, - params: [{ name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }], - defaultParams: [10], - version: '1.0' - }); - - addFuncDef({ - name: "multiplySeriesWithWildcards", - category: categories.Calculate, - params: [ - { name: "position", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] }, - { name: "position", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true }, - { name: "position", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true }, - { name: "position", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true }, - ], - defaultParams: [2], - version: '1.0' - }); - - addFuncDef({ - name: 'offsetToZero', - category: categories.Transform, - version: '1.0' - }); - - addFuncDef({ - name: 'pow', - category: categories.Transform, - params: [{ name: 'factor', type: 'int' }], - defaultParams: [10], - version: '1.0' - }); - - addFuncDef({ - name: 'powSeries', - category: categories.Transform, - params: optionalSeriesRefArgs, - defaultParams: [''], - version: '1.0' - }); - - addFuncDef({ - name: 'reduceSeries', - shortName: 'reduce', - params: [ - { name: "function", type: 'string', options: ['asPercent', 'diffSeries', 'divideSeries'] }, - { name: "reduceNode", type: 'int', options: [0,1,2,3,4,5,6,7,8,9,10,11,12,13] }, - { name: "reduceMatchers", type: 'string' }, - { name: "reduceMatchers", type: 'string' }, - ], - defaultParams: ['asPercent', 2, 'used_bytes', 'total_bytes'], - category: categories.Combine, - version: '1.0' - }); - - addFuncDef({ - name: 'removeBetweenPercentile', - category: categories.Filter, - params: [{ name: "n", type: "int", }], - defaultParams: [95], - version: '1.0' - }); - - addFuncDef({ - name: 'removeEmptySeries', - category: categories.Filter, - version: '1.0' - }); - - addFuncDef({ - name: 'squareRoot', - category: categories.Transform, - version: '1.0' - }); - - addFuncDef({ - name: 'timeSlice', - category: categories.Transform, - params: [ - { name: "startSliceAt", type: "select", options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d']}, - { name: "endSliceAt", type: "select", options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'], optional: true } - ], - defaultParams: ['-1h'], - version: '1.0' - }); - - addFuncDef({ - name: 'weightedAverage', - category: categories.Filter, - params: [ - { name: 'other', type: 'value_or_series', optional: true }, - { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] }, - ], - defaultParams: ['#A', 4], - version: '1.0' - }); - - addFuncDef({ - name: 'seriesByTag', - category: categories.Special, - params: [ - { name: "tagExpression", type: "string" }, - { name: "tagExpression", type: "string", optional: true }, - { name: "tagExpression", type: "string", optional: true }, - { name: "tagExpression", type: "string", optional: true }, - ], - version: '1.1' - }); - - addFuncDef({ - name: "groupByTags", - category: categories.Special, - params: [ - { - name: "function", - type: "string", - options: ['sum', 'avg', 'maxSeries'] - }, - { name: "tag", type: "string" }, - { name: "tag", type: "string", optional: true }, - { name: "tag", type: "string", optional: true }, - { name: "tag", type: "string", optional: true }, - ], - defaultParams: ["sum", "tag"], - version: '1.1' - }); - - addFuncDef({ - name: "aliasByTags", - category: categories.Special, - params: [ - { name: "tag", type: "string" }, - { name: "tag", type: "string", optional: true }, - { name: "tag", type: "string", optional: true }, - { name: "tag", type: "string", optional: true }, - ], - defaultParams: ["tag"], - version: '1.1' - }); - - _.each(categories, function(funcList, catName) { - categories[catName] = _.sortBy(funcList, 'name'); - }); - - function FuncInstance(funcDef, options) { - this.def = funcDef; - this.params = []; - - if (options && options.withDefaultParams) { - this.params = funcDef.defaultParams.slice(0); - } - - this.updateText(); - } - - FuncInstance.prototype.render = function(metricExp) { - var str = this.def.name + '('; - var parameters = _.map(this.params, function(value, index) { - - var paramType = this.def.params[index].type; - if (paramType === 'int' || paramType === 'value_or_series' || paramType === 'boolean') { - return value; - } - else if (paramType === 'int_or_interval' && $.isNumeric(value)) { - return value; - } - - return "'" + value + "'"; - - }.bind(this)); - - if (metricExp) { - parameters.unshift(metricExp); - } - - return str + parameters.join(', ') + ')'; - }; - - FuncInstance.prototype._hasMultipleParamsInString = function(strValue, index) { - if (strValue.indexOf(',') === -1) { - return false; - } - - return this.def.params[index + 1] && this.def.params[index + 1].optional; - }; - - FuncInstance.prototype.updateParam = function(strValue, index) { - // handle optional parameters - // if string contains ',' and next param is optional, split and update both - if (this._hasMultipleParamsInString(strValue, index)) { - _.each(strValue.split(','), function(partVal, idx) { - this.updateParam(partVal.trim(), index + idx); - }.bind(this)); - return; - } - - if (strValue === '' && this.def.params[index].optional) { - this.params.splice(index, 1); - } - else { - this.params[index] = strValue; - } - - this.updateText(); - }; - - FuncInstance.prototype.updateText = function () { - if (this.params.length === 0) { - this.text = this.def.name + '()'; - return; - } - - var text = this.def.name + '('; - text += this.params.join(', '); - text += ')'; - this.text = text; - }; - - function isVersionRelatedFunction(func, graphiteVersion) { - return version.isVersionGtOrEq(graphiteVersion, func.version) || !func.version; - } - - return { - createFuncInstance: function(funcDef, options) { - if (_.isString(funcDef)) { - if (!index[funcDef]) { - throw { message: 'Method not found ' + name }; - } - funcDef = index[funcDef]; - } - return new FuncInstance(funcDef, options); - }, - - getFuncDef: function(name) { - return index[name]; - }, - - getCategories: function(graphiteVersion) { - var filteredCategories = {}; - _.each(categories, function(functions, category) { - var filteredFuncs = _.filter(functions, function(func) { - return isVersionRelatedFunction(func, graphiteVersion); - }); - if (filteredFuncs.length) { - filteredCategories[category] = filteredFuncs; - } - }); - - return filteredCategories; - } - }; - -}); diff --git a/public/app/plugins/datasource/graphite/gfunc.ts b/public/app/plugins/datasource/graphite/gfunc.ts index 855a9184c7e..6d85cc1d0d5 100644 --- a/public/app/plugins/datasource/graphite/gfunc.ts +++ b/public/app/plugins/datasource/graphite/gfunc.ts @@ -1,6 +1,6 @@ -import _ from 'lodash'; -import {isVersionGtOrEq} from 'app/core/utils/version'; - +import _ from "lodash"; +import $ from "jquery"; +import {isVersionGtOrEq} from "app/core/utils/version"; var index = []; var categories = { @@ -8,7 +8,7 @@ var categories = { Transform: [], Calculate: [], Filter: [], - Special: [], + Special: [] }; function addFuncDef(funcDef) { @@ -23,567 +23,645 @@ function addFuncDef(funcDef) { } var optionalSeriesRefArgs = [ - { name: 'other', type: 'value_or_series', optional: true }, - { name: 'other', type: 'value_or_series', optional: true }, - { name: 'other', type: 'value_or_series', optional: true }, - { name: 'other', type: 'value_or_series', optional: true }, - { name: 'other', type: 'value_or_series', optional: true }, + { name: "other", type: "value_or_series", optional: true }, + { name: "other", type: "value_or_series", optional: true }, + { name: "other", type: "value_or_series", optional: true }, + { name: "other", type: "value_or_series", optional: true }, + { name: "other", type: "value_or_series", optional: true } ]; addFuncDef({ - name: 'scaleToSeconds', + name: "scaleToSeconds", category: categories.Transform, - params: [{ name: 'seconds', type: 'int' }], - defaultParams: [1], + params: [{ name: "seconds", type: "int" }], + defaultParams: [1] }); addFuncDef({ - name: 'perSecond', + name: "perSecond", category: categories.Transform, - params: [{ name: 'max value', type: 'int', optional: true }], - defaultParams: [], + params: [{ name: "max value", type: "int", optional: true }], + defaultParams: [] }); addFuncDef({ - name: 'holtWintersForecast', + name: "holtWintersForecast", + category: categories.Calculate +}); + +addFuncDef({ + name: "holtWintersConfidenceBands", category: categories.Calculate, + params: [{ name: "delta", type: "int" }], + defaultParams: [3] }); addFuncDef({ - name: 'holtWintersConfidenceBands', + name: "holtWintersAberration", category: categories.Calculate, - params: [{ name: 'delta', type: 'int' }], - defaultParams: [3], + params: [{ name: "delta", type: "int" }], + defaultParams: [3] }); addFuncDef({ - name: 'holtWintersAberration', + name: "nPercentile", category: categories.Calculate, - params: [{ name: 'delta', type: 'int' }], - defaultParams: [3], + params: [{ name: "Nth percentile", type: "int" }], + defaultParams: [95] }); addFuncDef({ - name: 'nPercentile', - category: categories.Calculate, - params: [{ name: 'Nth percentile', type: 'int' }], - defaultParams: [95], -}); - -addFuncDef({ - name: 'diffSeries', + name: "diffSeries", params: optionalSeriesRefArgs, - defaultParams: ['#A'], - category: categories.Calculate, + defaultParams: ["#A"], + category: categories.Calculate }); addFuncDef({ - name: 'stddevSeries', + name: "stddevSeries", params: optionalSeriesRefArgs, - defaultParams: [''], - category: categories.Calculate, + defaultParams: [""], + category: categories.Calculate }); addFuncDef({ - name: 'divideSeries', + name: "divideSeries", params: optionalSeriesRefArgs, - defaultParams: ['#A'], - category: categories.Calculate, + defaultParams: ["#A"], + category: categories.Calculate }); addFuncDef({ - name: 'multiplySeries', + name: "multiplySeries", params: optionalSeriesRefArgs, - defaultParams: ['#A'], - category: categories.Calculate, + defaultParams: ["#A"], + category: categories.Calculate }); addFuncDef({ - name: 'asPercent', + name: "asPercent", params: optionalSeriesRefArgs, - defaultParams: ['#A'], - category: categories.Calculate, + defaultParams: ["#A"], + category: categories.Calculate }); addFuncDef({ - name: 'group', + name: "group", params: optionalSeriesRefArgs, - defaultParams: ['#A', '#B'], - category: categories.Combine, + defaultParams: ["#A", "#B"], + category: categories.Combine }); addFuncDef({ - name: 'sumSeries', - shortName: 'sum', + name: "sumSeries", + shortName: "sum", category: categories.Combine, params: optionalSeriesRefArgs, - defaultParams: [''], + defaultParams: [""] }); addFuncDef({ - name: 'averageSeries', - shortName: 'avg', + name: "averageSeries", + shortName: "avg", category: categories.Combine, params: optionalSeriesRefArgs, - defaultParams: [''], + defaultParams: [""] }); addFuncDef({ - name: 'rangeOfSeries', - category: categories.Combine, + name: "rangeOfSeries", + category: categories.Combine }); addFuncDef({ - name: 'percentileOfSeries', - category: categories.Combine, - params: [{ name: 'n', type: 'int' }, { name: 'interpolate', type: 'boolean', options: ['true', 'false'] }], - defaultParams: [95, 'false'], -}); - -addFuncDef({ - name: 'sumSeriesWithWildcards', + name: "percentileOfSeries", category: categories.Combine, params: [ - { name: 'node', type: 'int' }, - { name: 'node', type: 'int', optional: true }, - { name: 'node', type: 'int', optional: true }, - { name: 'node', type: 'int', optional: true }, + { name: "n", type: "int" }, + { name: "interpolate", type: "boolean", options: ["true", "false"] } ], - defaultParams: [3], + defaultParams: [95, "false"] }); addFuncDef({ - name: 'maxSeries', - shortName: 'max', + name: "sumSeriesWithWildcards", category: categories.Combine, + params: [ + { name: "node", type: "int" }, + { name: "node", type: "int", optional: true }, + { name: "node", type: "int", optional: true }, + { name: "node", type: "int", optional: true } + ], + defaultParams: [3] }); addFuncDef({ - name: 'minSeries', - shortName: 'min', + name: "maxSeries", + shortName: "max", + category: categories.Combine +}); + +addFuncDef({ + name: "minSeries", + shortName: "min", + category: categories.Combine +}); + +addFuncDef({ + name: "averageSeriesWithWildcards", category: categories.Combine, + params: [ + { name: "node", type: "int" }, + { name: "node", type: "int", optional: true } + ], + defaultParams: [3] }); addFuncDef({ - name: 'averageSeriesWithWildcards', - category: categories.Combine, - params: [{ name: 'node', type: 'int' }, { name: 'node', type: 'int', optional: true }], - defaultParams: [3], -}); - -addFuncDef({ - name: 'alias', + name: "alias", category: categories.Special, - params: [{ name: 'alias', type: 'string' }], - defaultParams: ['alias'], + params: [{ name: "alias", type: "string" }], + defaultParams: ["alias"] }); addFuncDef({ - name: 'aliasSub', + name: "aliasSub", category: categories.Special, - params: [{ name: 'search', type: 'string' }, { name: 'replace', type: 'string' }], - defaultParams: ['', '\\1'], + params: [ + { name: "search", type: "string" }, + { name: "replace", type: "string" } + ], + defaultParams: ["", "\\1"] }); addFuncDef({ - name: 'stacked', + name: "stacked", category: categories.Special, - params: [{ name: 'stack', type: 'string' }], - defaultParams: ['stacked'], + params: [{ name: "stack", type: "string" }], + defaultParams: ["stacked"] }); addFuncDef({ - name: 'consolidateBy', + name: "consolidateBy", category: categories.Special, params: [ { - name: 'function', - type: 'string', - options: ['sum', 'average', 'min', 'max'], - }, + name: "function", + type: "string", + options: ["sum", "average", "min", "max"] + } ], - defaultParams: ['max'], + defaultParams: ["max"] }); addFuncDef({ - name: 'cumulative', + name: "cumulative", category: categories.Special, params: [], - defaultParams: [], + defaultParams: [] }); addFuncDef({ - name: 'groupByNode', + name: "groupByNode", category: categories.Special, params: [ { - name: 'node', - type: 'int', - options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12], + name: "node", + type: "int", + options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] }, { - name: 'function', - type: 'string', - options: ['sum', 'avg', 'maxSeries'], + name: "function", + type: "string", + options: ["sum", "avg", "maxSeries"] + } + ], + defaultParams: [3, "sum"] +}); + +addFuncDef({ + name: "aliasByNode", + category: categories.Special, + params: [ + { + name: "node", + type: "int", + options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] }, + { + name: "node", + type: "int", + options: [0, -1, -2, -3, -4, -5, -6, -7], + optional: true + }, + { + name: "node", + type: "int", + options: [0, -1, -2, -3, -4, -5, -6, -7], + optional: true + }, + { + name: "node", + type: "int", + options: [0, -1, -2, -3, -4, -5, -6, -7], + optional: true + } ], - defaultParams: [3, 'sum'], + defaultParams: [3] }); addFuncDef({ - name: 'aliasByNode', + name: "substr", category: categories.Special, params: [ - { name: 'node', type: 'int', options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] }, - { name: 'node', type: 'int', options: [0, -1, -2, -3, -4, -5, -6, -7], optional: true }, - { name: 'node', type: 'int', options: [0, -1, -2, -3, -4, -5, -6, -7], optional: true }, - { name: 'node', type: 'int', options: [0, -1, -2, -3, -4, -5, -6, -7], optional: true }, + { + name: "start", + type: "int", + options: [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] + }, + { + name: "stop", + type: "int", + options: [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] + } ], - defaultParams: [3], + defaultParams: [0, 0] }); addFuncDef({ - name: 'substr', + name: "sortByName", category: categories.Special, params: [ - { name: 'start', type: 'int', options: [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] }, - { name: 'stop', type: 'int', options: [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] }, + { + name: "natural", + type: "boolean", + options: ["true", "false"], + optional: true + } ], - defaultParams: [0, 0], + defaultParams: ["false"] }); addFuncDef({ - name: 'sortByName', - category: categories.Special, - params: [{ name: 'natural', type: 'boolean', options: ['true', 'false'], optional: true }], - defaultParams: ['false'], + name: "sortByMaxima", + category: categories.Special }); addFuncDef({ - name: 'sortByMaxima', - category: categories.Special, + name: "sortByMinima", + category: categories.Special }); addFuncDef({ - name: 'sortByMinima', - category: categories.Special, + name: "sortByTotal", + category: categories.Special }); addFuncDef({ - name: 'sortByTotal', - category: categories.Special, + name: "aliasByMetric", + category: categories.Special }); addFuncDef({ - name: 'aliasByMetric', - category: categories.Special, -}); - -addFuncDef({ - name: 'randomWalk', + name: "randomWalk", fake: true, category: categories.Special, - params: [{ name: 'name', type: 'string' }], - defaultParams: ['randomWalk'], + params: [{ name: "name", type: "string" }], + defaultParams: ["randomWalk"] }); addFuncDef({ - name: 'countSeries', + name: "countSeries", + category: categories.Special +}); + +addFuncDef({ + name: "constantLine", category: categories.Special, + params: [{ name: "value", type: "int" }], + defaultParams: [10] }); addFuncDef({ - name: 'constantLine', + name: "cactiStyle", + category: categories.Special +}); + +addFuncDef({ + name: "keepLastValue", category: categories.Special, - params: [{ name: 'value', type: 'int' }], - defaultParams: [10], + params: [{ name: "n", type: "int" }], + defaultParams: [100] }); addFuncDef({ - name: 'cactiStyle', - category: categories.Special, -}); - -addFuncDef({ - name: 'keepLastValue', - category: categories.Special, - params: [{ name: 'n', type: 'int' }], - defaultParams: [100], -}); - -addFuncDef({ - name: 'changed', + name: "changed", category: categories.Special, params: [], - defaultParams: [], + defaultParams: [] }); addFuncDef({ - name: 'scale', + name: "scale", category: categories.Transform, - params: [{ name: 'factor', type: 'int' }], - defaultParams: [1], + params: [{ name: "factor", type: "int" }], + defaultParams: [1] }); addFuncDef({ - name: 'offset', + name: "offset", category: categories.Transform, - params: [{ name: 'amount', type: 'int' }], - defaultParams: [10], + params: [{ name: "amount", type: "int" }], + defaultParams: [10] }); addFuncDef({ - name: 'transformNull', + name: "transformNull", category: categories.Transform, - params: [{ name: 'amount', type: 'int' }], - defaultParams: [0], + params: [{ name: "amount", type: "int" }], + defaultParams: [0] }); addFuncDef({ - name: 'integral', + name: "integral", + category: categories.Transform +}); + +addFuncDef({ + name: "derivative", + category: categories.Transform +}); + +addFuncDef({ + name: "nonNegativeDerivative", category: categories.Transform, + params: [{ name: "max value or 0", type: "int", optional: true }], + defaultParams: [""] }); addFuncDef({ - name: 'derivative', - category: categories.Transform, -}); - -addFuncDef({ - name: 'nonNegativeDerivative', - category: categories.Transform, - params: [{ name: 'max value or 0', type: 'int', optional: true }], - defaultParams: [''], -}); - -addFuncDef({ - name: 'timeShift', - category: categories.Transform, - params: [{ name: 'amount', type: 'select', options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'] }], - defaultParams: ['1d'], -}); - -addFuncDef({ - name: 'timeStack', + name: "timeShift", category: categories.Transform, params: [ - { name: 'timeShiftUnit', type: 'select', options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'] }, - { name: 'timeShiftStart', type: 'int' }, - { name: 'timeShiftEnd', type: 'int' }, + { + name: "amount", + type: "select", + options: ["1h", "6h", "12h", "1d", "2d", "7d", "14d", "30d"] + } ], - defaultParams: ['1d', 0, 7], + defaultParams: ["1d"] }); addFuncDef({ - name: 'summarize', + name: "timeStack", category: categories.Transform, params: [ - { name: 'interval', type: 'string' }, - { name: 'func', type: 'select', options: ['sum', 'avg', 'min', 'max', 'last'] }, - { name: 'alignToFrom', type: 'boolean', optional: true, options: ['false', 'true'] }, + { + name: "timeShiftUnit", + type: "select", + options: ["1h", "6h", "12h", "1d", "2d", "7d", "14d", "30d"] + }, + { name: "timeShiftStart", type: "int" }, + { name: "timeShiftEnd", type: "int" } ], - defaultParams: ['1h', 'sum', 'false'], + defaultParams: ["1d", 0, 7] }); addFuncDef({ - name: 'smartSummarize', + name: "summarize", category: categories.Transform, params: [ - { name: 'interval', type: 'string' }, - { name: 'func', type: 'select', options: ['sum', 'avg', 'min', 'max', 'last'] }, + { name: "interval", type: "string" }, + { + name: "func", + type: "select", + options: ["sum", "avg", "min", "max", "last"] + }, + { + name: "alignToFrom", + type: "boolean", + optional: true, + options: ["false", "true"] + } ], - defaultParams: ['1h', 'sum'], + defaultParams: ["1h", "sum", "false"] }); addFuncDef({ - name: 'absolute', + name: "smartSummarize", category: categories.Transform, + params: [ + { name: "interval", type: "string" }, + { + name: "func", + type: "select", + options: ["sum", "avg", "min", "max", "last"] + } + ], + defaultParams: ["1h", "sum"] }); addFuncDef({ - name: 'hitcount', + name: "absolute", + category: categories.Transform +}); + +addFuncDef({ + name: "hitcount", category: categories.Transform, - params: [{ name: 'interval', type: 'string' }], - defaultParams: ['10s'], + params: [{ name: "interval", type: "string" }], + defaultParams: ["10s"] }); addFuncDef({ - name: 'log', + name: "log", category: categories.Transform, - params: [{ name: 'base', type: 'int' }], - defaultParams: ['10'], + params: [{ name: "base", type: "int" }], + defaultParams: ["10"] }); addFuncDef({ - name: 'averageAbove', + name: "averageAbove", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [25], + params: [{ name: "n", type: "int" }], + defaultParams: [25] }); addFuncDef({ - name: 'averageBelow', + name: "averageBelow", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [25], + params: [{ name: "n", type: "int" }], + defaultParams: [25] }); addFuncDef({ - name: 'currentAbove', + name: "currentAbove", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [25], + params: [{ name: "n", type: "int" }], + defaultParams: [25] }); addFuncDef({ - name: 'currentBelow', + name: "currentBelow", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [25], + params: [{ name: "n", type: "int" }], + defaultParams: [25] }); addFuncDef({ - name: 'maximumAbove', + name: "maximumAbove", category: categories.Filter, - params: [{ name: 'value', type: 'int' }], - defaultParams: [0], + params: [{ name: "value", type: "int" }], + defaultParams: [0] }); addFuncDef({ - name: 'maximumBelow', + name: "maximumBelow", category: categories.Filter, - params: [{ name: 'value', type: 'int' }], - defaultParams: [0], + params: [{ name: "value", type: "int" }], + defaultParams: [0] }); addFuncDef({ - name: 'minimumAbove', + name: "minimumAbove", category: categories.Filter, - params: [{ name: 'value', type: 'int' }], - defaultParams: [0], + params: [{ name: "value", type: "int" }], + defaultParams: [0] }); addFuncDef({ - name: 'minimumBelow', + name: "minimumBelow", category: categories.Filter, - params: [{ name: 'value', type: 'int' }], - defaultParams: [0], + params: [{ name: "value", type: "int" }], + defaultParams: [0] }); addFuncDef({ - name: 'limit', + name: "limit", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [5], + params: [{ name: "n", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'mostDeviant', + name: "mostDeviant", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [10], + params: [{ name: "n", type: "int" }], + defaultParams: [10] }); addFuncDef({ - name: 'exclude', + name: "exclude", category: categories.Filter, - params: [{ name: 'exclude', type: 'string' }], - defaultParams: ['exclude'], + params: [{ name: "exclude", type: "string" }], + defaultParams: ["exclude"] }); addFuncDef({ - name: 'highestCurrent', + name: "highestCurrent", category: categories.Filter, - params: [{ name: 'count', type: 'int' }], - defaultParams: [5], + params: [{ name: "count", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'highestMax', + name: "highestMax", category: categories.Filter, - params: [{ name: 'count', type: 'int' }], - defaultParams: [5], + params: [{ name: "count", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'lowestCurrent', + name: "lowestCurrent", category: categories.Filter, - params: [{ name: 'count', type: 'int' }], - defaultParams: [5], + params: [{ name: "count", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'movingAverage', + name: "movingAverage", category: categories.Filter, params: [ - { name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }, + { + name: "windowSize", + type: "int_or_interval", + options: ["5", "7", "10", "5min", "10min", "30min", "1hour"] + } ], - defaultParams: [10], + defaultParams: [10] }); addFuncDef({ - name: 'movingMedian', + name: "movingMedian", category: categories.Filter, params: [ - { name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }, + { + name: "windowSize", + type: "int_or_interval", + options: ["5", "7", "10", "5min", "10min", "30min", "1hour"] + } ], - defaultParams: ['5'], + defaultParams: ["5"] }); addFuncDef({ - name: 'stdev', + name: "stdev", category: categories.Filter, - params: [{ name: 'n', type: 'int' }, { name: 'tolerance', type: 'int' }], - defaultParams: [5, 0.1], + params: [{ name: "n", type: "int" }, { name: "tolerance", type: "int" }], + defaultParams: [5, 0.1] }); addFuncDef({ - name: 'highestAverage', + name: "highestAverage", category: categories.Filter, - params: [{ name: 'count', type: 'int' }], - defaultParams: [5], + params: [{ name: "count", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'lowestAverage', + name: "lowestAverage", category: categories.Filter, - params: [{ name: 'count', type: 'int' }], - defaultParams: [5], + params: [{ name: "count", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'removeAbovePercentile', + name: "removeAbovePercentile", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [5], + params: [{ name: "n", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'removeAboveValue', + name: "removeAboveValue", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [5], + params: [{ name: "n", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'removeBelowPercentile', + name: "removeBelowPercentile", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [5], + params: [{ name: "n", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'removeBelowValue', + name: "removeBelowValue", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], - defaultParams: [5], + params: [{ name: "n", type: "int" }], + defaultParams: [5] }); addFuncDef({ - name: 'useSeriesAbove', + name: "useSeriesAbove", category: categories.Filter, - params: [{ name: 'value', type: 'int' }, { name: 'search', type: 'string' }, { name: 'replace', type: 'string' }], - defaultParams: [0, 'search', 'replace'], + params: [ + { name: "value", type: "int" }, + { name: "search", type: "string" }, + { name: "replace", type: "string" } + ], + defaultParams: [0, "search", "replace"] }); //////////////////// @@ -591,393 +669,484 @@ addFuncDef({ //////////////////// addFuncDef({ - name: 'aggregateLine', + name: "aggregateLine", category: categories.Combine, - params: [{ name: 'func', type: 'select', options: ['sum', 'avg', 'min', 'max', 'last'] }], - defaultParams: ['avg'], - version: '1.0', + params: [ + { + name: "func", + type: "select", + options: ["sum", "avg", "min", "max", "last"] + } + ], + defaultParams: ["avg"], + version: "1.0" }); addFuncDef({ - name: 'averageOutsidePercentile', + name: "averageOutsidePercentile", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], + params: [{ name: "n", type: "int" }], defaultParams: [95], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'delay', + name: "delay", category: categories.Transform, - params: [{ name: 'steps', type: 'int' }], + params: [{ name: "steps", type: "int" }], defaultParams: [1], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'exponentialMovingAverage', + name: "exponentialMovingAverage", category: categories.Calculate, params: [ - { name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }, + { + name: "windowSize", + type: "int_or_interval", + options: ["5", "7", "10", "5min", "10min", "30min", "1hour"] + } ], defaultParams: [10], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'fallbackSeries', + name: "fallbackSeries", category: categories.Special, - params: [{ name: 'fallback', type: 'string' }], - defaultParams: ['constantLine(0)'], - version: '1.0', + params: [{ name: "fallback", type: "string" }], + defaultParams: ["constantLine(0)"], + version: "1.0" }); addFuncDef({ - name: 'grep', + name: "grep", category: categories.Filter, - params: [{ name: 'grep', type: 'string' }], - defaultParams: ['grep'], - version: '1.0', + params: [{ name: "grep", type: "string" }], + defaultParams: ["grep"], + version: "1.0" }); addFuncDef({ - name: 'groupByNodes', + name: "groupByNodes", category: categories.Special, params: [ { - name: 'function', - type: 'string', - options: ['sum', 'avg', 'maxSeries'], + name: "function", + type: "string", + options: ["sum", "avg", "maxSeries"] }, - { name: 'node', type: 'int', options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] }, - { name: 'node', type: 'int', options: [0, -1, -2, -3, -4, -5, -6, -7], optional: true }, - { name: 'node', type: 'int', options: [0, -1, -2, -3, -4, -5, -6, -7], optional: true }, - { name: 'node', type: 'int', options: [0, -1, -2, -3, -4, -5, -6, -7], optional: true }, + { + name: "node", + type: "int", + options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] + }, + { + name: "node", + type: "int", + options: [0, -1, -2, -3, -4, -5, -6, -7], + optional: true + }, + { + name: "node", + type: "int", + options: [0, -1, -2, -3, -4, -5, -6, -7], + optional: true + }, + { + name: "node", + type: "int", + options: [0, -1, -2, -3, -4, -5, -6, -7], + optional: true + } ], - defaultParams: ['sum', 3], - version: '1.0', + defaultParams: ["sum", 3], + version: "1.0" }); addFuncDef({ - name: 'integralByInterval', + name: "integralByInterval", category: categories.Transform, - params: [{ name: 'intervalUnit', type: 'select', options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'] }], - defaultParams: ['1d'], - version: '1.0', + params: [ + { + name: "intervalUnit", + type: "select", + options: ["1h", "6h", "12h", "1d", "2d", "7d", "14d", "30d"] + } + ], + defaultParams: ["1d"], + version: "1.0" }); addFuncDef({ - name: 'interpolate', + name: "interpolate", category: categories.Transform, - params: [{ name: 'limit', type: 'int', optional: true }], + params: [{ name: "limit", type: "int", optional: true }], defaultParams: [], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'invert', + name: "invert", category: categories.Transform, - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'isNonNull', + name: "isNonNull", category: categories.Combine, - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'linearRegression', + name: "linearRegression", category: categories.Calculate, params: [ { - name: 'startSourceAt', - type: 'select', - options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'], - optional: true, + name: "startSourceAt", + type: "select", + options: ["-1h", "-6h", "-12h", "-1d", "-2d", "-7d", "-14d", "-30d"], + optional: true }, { - name: 'endSourceAt', - type: 'select', - options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'], - optional: true, - }, + name: "endSourceAt", + type: "select", + options: ["-1h", "-6h", "-12h", "-1d", "-2d", "-7d", "-14d", "-30d"], + optional: true + } ], defaultParams: [], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'mapSeries', - shortName: 'map', - params: [{ name: 'node', type: 'int' }], + name: "mapSeries", + shortName: "map", + params: [{ name: "node", type: "int" }], defaultParams: [3], category: categories.Combine, - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'movingMin', + name: "movingMin", category: categories.Calculate, params: [ - { name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }, + { + name: "windowSize", + type: "int_or_interval", + options: ["5", "7", "10", "5min", "10min", "30min", "1hour"] + } ], defaultParams: [10], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'movingMax', + name: "movingMax", category: categories.Calculate, params: [ - { name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }, + { + name: "windowSize", + type: "int_or_interval", + options: ["5", "7", "10", "5min", "10min", "30min", "1hour"] + } ], defaultParams: [10], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'movingSum', + name: "movingSum", category: categories.Calculate, params: [ - { name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }, + { + name: "windowSize", + type: "int_or_interval", + options: ["5", "7", "10", "5min", "10min", "30min", "1hour"] + } ], defaultParams: [10], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'multiplySeriesWithWildcards', + name: "multiplySeriesWithWildcards", category: categories.Calculate, params: [ - { name: 'position', type: 'int', options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] }, - { name: 'position', type: 'int', options: [0, -1, -2, -3, -4, -5, -6, -7], optional: true }, - { name: 'position', type: 'int', options: [0, -1, -2, -3, -4, -5, -6, -7], optional: true }, - { name: 'position', type: 'int', options: [0, -1, -2, -3, -4, -5, -6, -7], optional: true }, + { + name: "position", + type: "int", + options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] + }, + { + name: "position", + type: "int", + options: [0, -1, -2, -3, -4, -5, -6, -7], + optional: true + }, + { + name: "position", + type: "int", + options: [0, -1, -2, -3, -4, -5, -6, -7], + optional: true + }, + { + name: "position", + type: "int", + options: [0, -1, -2, -3, -4, -5, -6, -7], + optional: true + } ], defaultParams: [2], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'offsetToZero', + name: "offsetToZero", category: categories.Transform, - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'pow', + name: "pow", category: categories.Transform, - params: [{ name: 'factor', type: 'int' }], + params: [{ name: "factor", type: "int" }], defaultParams: [10], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'powSeries', + name: "powSeries", category: categories.Transform, params: optionalSeriesRefArgs, - defaultParams: [''], - version: '1.0', + defaultParams: [""], + version: "1.0" }); addFuncDef({ - name: 'reduceSeries', - shortName: 'reduce', + name: "reduceSeries", + shortName: "reduce", params: [ - { name: 'function', type: 'string', options: ['asPercent', 'diffSeries', 'divideSeries'] }, - { name: 'reduceNode', type: 'int', options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] }, - { name: 'reduceMatchers', type: 'string' }, - { name: 'reduceMatchers', type: 'string' }, + { + name: "function", + type: "string", + options: ["asPercent", "diffSeries", "divideSeries"] + }, + { + name: "reduceNode", + type: "int", + options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] + }, + { name: "reduceMatchers", type: "string" }, + { name: "reduceMatchers", type: "string" } ], - defaultParams: ['asPercent', 2, 'used_bytes', 'total_bytes'], + defaultParams: ["asPercent", 2, "used_bytes", "total_bytes"], category: categories.Combine, - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'removeBetweenPercentile', + name: "removeBetweenPercentile", category: categories.Filter, - params: [{ name: 'n', type: 'int' }], + params: [{ name: "n", type: "int" }], defaultParams: [95], - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'removeEmptySeries', + name: "removeEmptySeries", category: categories.Filter, - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'squareRoot', + name: "squareRoot", category: categories.Transform, - version: '1.0', + version: "1.0" }); addFuncDef({ - name: 'timeSlice', + name: "timeSlice", category: categories.Transform, params: [ - { name: 'startSliceAt', type: 'select', options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'] }, { - name: 'endSliceAt', - type: 'select', - options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'], - optional: true, + name: "startSliceAt", + type: "select", + options: ["-1h", "-6h", "-12h", "-1d", "-2d", "-7d", "-14d", "-30d"] }, + { + name: "endSliceAt", + type: "select", + options: ["-1h", "-6h", "-12h", "-1d", "-2d", "-7d", "-14d", "-30d"], + optional: true + } ], - defaultParams: ['-1h'], - version: '1.0', + defaultParams: ["-1h"], + version: "1.0" }); addFuncDef({ - name: 'weightedAverage', + name: "weightedAverage", category: categories.Filter, params: [ - { name: 'other', type: 'value_or_series', optional: true }, - { name: 'node', type: 'int', options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] }, + { name: "other", type: "value_or_series", optional: true }, + { + name: "node", + type: "int", + options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] + } ], - defaultParams: ['#A', 4], - version: '1.0', + defaultParams: ["#A", 4], + version: "1.0" }); addFuncDef({ - name: 'seriesByTag', + name: "seriesByTag", category: categories.Special, params: [ - { name: 'tagExpression', type: 'string' }, - { name: 'tagExpression', type: 'string', optional: true }, - { name: 'tagExpression', type: 'string', optional: true }, - { name: 'tagExpression', type: 'string', optional: true }, + { name: "tagExpression", type: "string" }, + { name: "tagExpression", type: "string", optional: true }, + { name: "tagExpression", type: "string", optional: true }, + { name: "tagExpression", type: "string", optional: true } ], - version: '1.1', + version: "1.1" }); addFuncDef({ - name: 'groupByTags', + name: "groupByTags", category: categories.Special, params: [ { - name: 'function', - type: 'string', - options: ['sum', 'avg', 'maxSeries'], + name: "function", + type: "string", + options: ["sum", "avg", "maxSeries"] }, - { name: 'tag', type: 'string' }, - { name: 'tag', type: 'string', optional: true }, - { name: 'tag', type: 'string', optional: true }, - { name: 'tag', type: 'string', optional: true }, + { name: "tag", type: "string" }, + { name: "tag", type: "string", optional: true }, + { name: "tag", type: "string", optional: true }, + { name: "tag", type: "string", optional: true } ], - defaultParams: ['sum', 'tag'], - version: '1.1', + defaultParams: ["sum", "tag"], + version: "1.1" }); addFuncDef({ - name: 'aliasByTags', + name: "aliasByTags", category: categories.Special, params: [ - { name: 'tag', type: 'string' }, - { name: 'tag', type: 'string', optional: true }, - { name: 'tag', type: 'string', optional: true }, - { name: 'tag', type: 'string', optional: true }, + { name: "tag", type: "string" }, + { name: "tag", type: "string", optional: true }, + { name: "tag", type: "string", optional: true }, + { name: "tag", type: "string", optional: true } ], - defaultParams: ['tag'], - version: '1.1', + defaultParams: ["tag"], + version: "1.1" }); _.each(categories, function(funcList, catName) { - categories[catName] = _.sortBy(funcList, 'name'); + categories[catName] = _.sortBy(funcList, "name"); }); -function FuncInstance(funcDef, options?) { - this.def = funcDef; - this.params = []; - - if (options && options.withDefaultParams) { - this.params = funcDef.defaultParams.slice(0); - } - - this.updateText(); -} - -function isNumeric(obj) { - return !isNaN(parseFloat(obj)) && isFinite(obj); -} - -FuncInstance.prototype.render = function(metricExp) { - var str = this.def.name + '('; - var parameters = _.map( - this.params, - function(value, index) { - var paramType = this.def.params[index].type; - if (paramType === 'int' || paramType === 'value_or_series' || paramType === 'boolean') { - return value; - } else if (paramType === 'int_or_interval' && isNumeric(value)) { - return value; - } - - return "'" + value + "'"; - }.bind(this), - ); - - if (metricExp) { - parameters.unshift(metricExp); - } - - return str + parameters.join(', ') + ')'; -}; - -FuncInstance.prototype._hasMultipleParamsInString = function(strValue, index) { - if (strValue.indexOf(',') === -1) { - return false; - } - - return this.def.params[index + 1] && this.def.params[index + 1].optional; -}; - -FuncInstance.prototype.updateParam = function(strValue, index) { - // handle optional parameters - // if string contains ',' and next param is optional, split and update both - if (this._hasMultipleParamsInString(strValue, index)) { - _.each( - strValue.split(','), - function(partVal, idx) { - this.updateParam(partVal.trim(), index + idx); - }.bind(this), - ); - return; - } - - if (strValue === '' && this.def.params[index].optional) { - this.params.splice(index, 1); - } else { - this.params[index] = strValue; - } - - this.updateText(); -}; - -FuncInstance.prototype.updateText = function() { - if (this.params.length === 0) { - this.text = this.def.name + '()'; - return; - } - - var text = this.def.name + '('; - text += this.params.join(', '); - text += ')'; - this.text = text; -}; - function isVersionRelatedFunction(func, graphiteVersion) { - return isVersionGtOrEq(graphiteVersion, func.version) || !func.version; + return ( + isVersionGtOrEq(graphiteVersion, func.version) || !func.version + ); +} + +export class FuncInstance { + def: any; + params: any; + text: any; + added: boolean; + + constructor(funcDef, options) { + this.def = funcDef; + this.params = []; + + if (options && options.withDefaultParams) { + this.params = funcDef.defaultParams.slice(0); + } + + this.updateText(); + } + + render(metricExp) { + var str = this.def.name + "("; + var parameters = _.map( + this.params, + function(value, index) { + var paramType = this.def.params[index].type; + if ( + paramType === "int" || + paramType === "value_or_series" || + paramType === "boolean" + ) { + return value; + } else if (paramType === "int_or_interval" && $.isNumeric(value)) { + return value; + } + + return "'" + value + "'"; + }.bind(this) + ); + + if (metricExp) { + parameters.unshift(metricExp); + } + + return str + parameters.join(", ") + ")"; + } + + _hasMultipleParamsInString(strValue, index) { + if (strValue.indexOf(",") === -1) { + return false; + } + + return this.def.params[index + 1] && this.def.params[index + 1].optional; + } + + updateParam(strValue, index) { + // handle optional parameters + // if string contains ',' and next param is optional, split and update both + if (this._hasMultipleParamsInString(strValue, index)) { + _.each( + strValue.split(","), + function(partVal, idx) { + this.updateParam(partVal.trim(), index + idx); + }.bind(this) + ); + return; + } + + if (strValue === "" && this.def.params[index].optional) { + this.params.splice(index, 1); + } else { + this.params[index] = strValue; + } + + this.updateText(); + } + + updateText() { + if (this.params.length === 0) { + this.text = this.def.name + "()"; + return; + } + + var text = this.def.name + "("; + text += this.params.join(", "); + text += ")"; + this.text = text; + } } export default { createFuncInstance: function(funcDef, options?) { if (_.isString(funcDef)) { if (!index[funcDef]) { - throw { message: 'Method not found ' + name }; + throw { message: "Method not found " + name }; } funcDef = index[funcDef]; } @@ -1000,5 +1169,5 @@ export default { }); return filteredCategories; - }, + } };