Commit 93d21bec by Torkel Ödegaard

Merge branch 'master' into develop

parents 02e2d5da 4ce1ee41
FROM phusion/baseimage:0.9.22
MAINTAINER Denys Zhdanov <denis.zhdanov@gmail.com>
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"]
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.
......@@ -495,3 +495,4 @@ public_url =
[external_image_storage.gcs]
key_file =
bucket =
path =
\ No newline at end of file
......@@ -438,3 +438,4 @@ log_queries =
[external_image_storage.gcs]
;key_file =
;bucket =
;path =
\ No newline at end of file
......@@ -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`
......
......@@ -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**:
......
......@@ -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
......
{
"stable": "4.5.2",
"testing": "4.5.2"
"stable": "4.6.2",
"testing": "4.6.2"
}
......@@ -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)
......
......@@ -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
......
......@@ -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
}
......
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)
})
}
......@@ -15,6 +15,8 @@ class Settings {
disableLoginForm: boolean;
defaultDatasource: string;
alertingEnabled: boolean;
authProxyEnabled: boolean;
ldapEnabled: boolean;
constructor(options) {
var defaults = {
......
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 = '<i class="grafana-tip fa fa-'+(attrs.icon||'question-circle')+'" bs-tooltip="\''+
kbn.addslashes(elem.text())+'\'"></i>';
_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 ? (' <tip>' + attrs.tip + '</tip>') : '';
var showIf = attrs.showIf ? (' ng-show="' + attrs.showIf + '" ') : '';
var template = '<div class="editor-option gf-form-checkbox text-center"' + showIf + '>' +
' <label for="' + attrs.model + '" class="small">' +
attrs.text + tip + '</label>' +
'<input class="cr1" id="' + attrs.model + '" type="checkbox" ' +
' ng-model="' + attrs.model + '"' + ngchange +
' ng-checked="' + attrs.model + '"></input>' +
' <label for="' + attrs.model + '" class="cr1"></label>';
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 ? (' <tip>' + attrs.tip + '</tip>') : '';
var label = '<label for="' + scope.$id + model + '" class="checkbox-label">' +
text + tip + '</label>';
var template =
'<input class="cr1" id="' + scope.$id + model + '" type="checkbox" ' +
' ng-model="' + model + '"' + ngchange +
' ng-checked="' + model + '"></input>' +
' <label for="' + scope.$id + model + '" class="cr1"></label>';
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 = [
'<ul class="dropdown-menu ' + upclass + '" role="menu" aria-labelledby="drop1">',
'</ul>'
];
angular.forEach(items, function (item, index) {
if (item.divider) {
return ul.splice(index + 1, 0, '<li class="divider"></li>');
}
var li = '<li' + (item.submenu && item.submenu.length ? ' class="dropdown-submenu"' : '') + '>' +
'<a tabindex="-1" ng-href="' + (item.href || '') + '"' + (item.click ? ' ng-click="' + item.click + '"' : '') +
(item.target ? ' target="' + item.target + '"' : '') + (item.method ? ' data-method="' + item.method + '"' : '') +
'>' + (item.text || '') + '</a>';
if (item.submenu && item.submenu.length) {
li += buildTemplate(item.submenu).join('\n');
}
li += '</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');
}
};
});
});
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 =
'<i class="grafana-tip fa fa-' +
(attrs.icon || "question-circle") +
'" bs-tooltip="\'' +
kbn.addslashes(elem.text()) +
"'\"></i>";
_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 ? " <tip>" + attrs.tip + "</tip>" : "";
var showIf = attrs.showIf ? ' ng-show="' + attrs.showIf + '" ' : "";
var template =
'<div class="editor-option gf-form-checkbox text-center"' +
showIf +
">" +
' <label for="' +
attrs.model +
'" class="small">' +
attrs.text +
tip +
"</label>" +
'<input class="cr1" id="' +
attrs.model +
'" type="checkbox" ' +
' ng-model="' +
attrs.model +
'"' +
ngchange +
' ng-checked="' +
attrs.model +
'"></input>' +
' <label for="' +
attrs.model +
'" class="cr1"></label>';
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 ? " <tip>" + attrs.tip + "</tip>" : "";
var label =
'<label for="' +
scope.$id +
model +
'" class="checkbox-label">' +
text +
tip +
"</label>";
var template =
'<input class="cr1" id="' +
scope.$id +
model +
'" type="checkbox" ' +
' ng-model="' +
model +
'"' +
ngchange +
' ng-checked="' +
model +
'"></input>' +
' <label for="' +
scope.$id +
model +
'" class="cr1"></label>';
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 = [
'<ul class="dropdown-menu ' +
upclass +
'" role="menu" aria-labelledby="drop1">',
"</ul>"
];
for (let index = 0; index < items.length; index++) {
let item = items[index];
if (item.divider) {
ul.splice(index + 1, 0, '<li class="divider"></li>');
continue;
}
var li =
"<li" +
(item.submenu && item.submenu.length
? ' class="dropdown-submenu"'
: "") +
">" +
'<a tabindex="-1" ng-href="' +
(item.href || "") +
'"' +
(item.click ? ' ng-click="' + item.click + '"' : "") +
(item.target ? ' target="' + item.target + '"' : "") +
(item.method ? ' data-method="' + item.method + '"' : "") +
">" +
(item.text || "") +
"</a>";
if (item.submenu && item.submenu.length) {
li += buildTemplate(item.submenu).join("\n");
}
li += "</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);
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());
});
elm.off('input keydown change');
elm.bind('blur', function() {
scope.$apply(function() {
ngModelCtrl.$setViewValue(elm.val());
});
}
};
}
});
}
};
}
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;
});
}
};
}
function emptyToNull() {
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;
};
}
};
}
function validTimeSpan() {
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);
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;
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 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 bootstrapTagsinput() {
function getItemProperty(scope, property) {
if (!property) {
return undefined;
}
coreModule.default.directive('tagColorFromName', function() {
return {
scope: { tagColorFromName: "=" },
link: function (scope, element) {
setColor(scope.tagColorFromName, element);
}
};
});
if (angular.isFunction(scope.$parent[property])) {
return scope.$parent[property];
}
coreModule.default.directive('bootstrapTagsinput', function() {
return function(item) {
return item[property];
};
}
function getItemProperty(scope, property) {
if (!property) {
return undefined;
return {
restrict: 'EA',
scope: {
model: '=ngModel',
onTagsUpdated: "&",
},
template: '<select multiple></select>',
replace: false,
link: function(scope, element, attrs) {
if (!angular.isArray(scope.model)) {
scope.model = [];
}
if (angular.isFunction(scope.$parent[property])) {
return scope.$parent[property];
}
var select = $('select', element);
return function(item) {
return item[property];
};
}
if (attrs.placeholder) {
select.attr('placeholder', attrs.placeholder);
}
return {
restrict: 'EA',
scope: {
model: '=ngModel',
onTagsUpdated: "&",
},
template: '<select multiple></select>',
replace: false,
link: function(scope, element, attrs) {
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 = [];
}
var select = $('select', element);
select.tagsinput('removeAll');
if (attrs.placeholder) {
select.attr('placeholder', attrs.placeholder);
for (var i = 0; i < scope.model.length; i++) {
select.tagsinput('add', scope.model[i]);
}
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);
}
};
});
}, true);
}
};
}
});
coreModule.directive('tagColorFromName', tagColorFromName);
coreModule.directive('bootstrapTagsinput', bootstrapTagsinput);
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';
......
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.getNav('cfg', 'admin', 'global-orgs');
......@@ -48,7 +44,7 @@ function (angular) {
};
$scope.init();
}
}
});
});
angular.module('grafana.controllers').controller('AdminEditOrgCtrl', AdminEditOrgCtrl);
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);
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.getNav('cfg', 'admin', 'global-orgs');
$scope.getOrgs();
......@@ -35,7 +31,7 @@ function (angular) {
};
$scope.init();
}
}
});
});
angular.module('grafana.controllers').controller('AdminListOrgsCtrl', AdminListOrgsCtrl);
define([
'angular',
'lodash',
],
function (angular, _) {
'use strict';
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",
import angular from 'angular';
import _ from 'lodash';
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: '<dash-link ng-repeat="link in generatedLinks" link="link"></dash-link>',
link: function() { }
};
}
/** @ngInject */
function dashLink($compile, linkSrv) {
return {
restrict: 'E',
link: function(scope, elem) {
var link = scope.link;
var template = '<div class="gf-form">' +
'<a class="pointer gf-form-label" data-placement="bottom"' +
(link.asDropdown ? ' ng-click="fillDropdown(link)" data-toggle="dropdown"' : "") + '>' +
'<i></i> <span></span></a>';
if (link.asDropdown) {
template += '<ul class="dropdown-menu" role="menu">' +
'<li ng-repeat="dash in link.searchHits"><a href="{{dash.url}}">{{dash.title}}</a></li>' +
'</ul>';
}
};
});
module.directive('dashLinksContainer', function() {
return {
scope: {
links: "="
},
restrict: 'E',
controller: 'DashLinksContainerCtrl',
template: '<dash-link ng-repeat="link in generatedLinks" link="link"></dash-link>',
link: function() { }
};
});
module.directive('dashLink', function($compile, linkSrv) {
return {
restrict: 'E',
link: function(scope, elem) {
var link = scope.link;
var template = '<div class="gf-form">' +
'<a class="pointer gf-form-label" data-placement="bottom"' +
(link.asDropdown ? ' ng-click="fillDropdown(link)" data-toggle="dropdown"' : "") + '>' +
'<i></i> <span></span></a>';
if (link.asDropdown) {
template += '<ul class="dropdown-menu" role="menu">' +
'<li ng-repeat="dash in link.searchHits"><a href="{{dash.url}}">{{dash.title}}</a></li>' +
'</ul>';
}
template += '</div>';
template += '</div>';
elem.html(template);
$compile(elem.contents())(scope);
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);
}
var anchor = elem.find('a');
var icon = elem.find('i');
var span = elem.find('span');
// 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);
function update() {
var linkInfo = linkSrv.getAnchorInfo(link);
span.text(linkInfo.title);
anchor.attr("href", linkInfo.href);
}
// fix for menus on the far right
if (link.asDropdown && scope.$last) {
elem.find('.dropdown-menu').addClass('pull-right');
}
// 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);
update();
scope.$on('refresh', update);
// fix for menus on the far right
if (link.asDropdown && scope.$last) {
elem.find('.dropdown-menu').addClass('pull-right');
}
};
});
module.controller("DashLinksContainerCtrl", function($scope, $rootScope, $q, backendSrv, dashboardSrv, linkSrv) {
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);
define([
'./org_users_ctrl',
'./profile_ctrl',
'./select_org_ctrl',
'./change_password_ctrl',
'./newOrgCtrl',
'./userInviteCtrl',
'./orgApiKeysCtrl',
'./orgDetailsCtrl',
'./prefs_control',
'./user_groups_ctrl',
'./user_group_details_ctrl',
'./create_user_group_modal',
], function () {});
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';
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);
define([
'angular',
'app/core/config',
],
function (angular, config) {
'use strict';
config = config.default;
var module = angular.module('grafana.controllers');
module.controller('NewOrgCtrl', function($scope, $http, backendSrv, navModelSrv) {
$scope.navModel = navModelSrv.getOrgNav(0);
$scope.newOrg = {name: ''};
$scope.createOrg = function() {
backendSrv.post('/api/orgs/', $scope.newOrg).then(function(result) {
backendSrv.post('/api/user/using/' + result.orgId).then(function() {
window.location.href = config.appSubUrl + '/org';
});
});
};
});
});
import angular from 'angular';
import config from 'app/core/config';
export class NewOrgCtrl {
/** @ngInject **/
constructor($scope, $http, backendSrv, navModelSrv) {
$scope.navModel = navModelSrv.getOrgNav(0);
$scope.newOrg = {name: ''};
$scope.createOrg = function() {
backendSrv.post('/api/orgs/', $scope.newOrg).then(function(result) {
backendSrv.post('/api/user/using/' + result.orgId).then(function() {
window.location.href = config.appSubUrl + '/org';
});
});
};
}
}
angular.module('grafana.controllers').controller('NewOrgCtrl', NewOrgCtrl);
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.getNav('cfg', 'apikeys');
$scope.roleTypes = ['Viewer', 'Editor', 'Admin'];
$scope.token = { role: 'Viewer' };
......@@ -43,6 +40,7 @@ function (angular) {
};
$scope.init();
}
}
});
});
angular.module('grafana.controllers').controller('OrgApiKeysCtrl', OrgApiKeysCtrl);
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.getNav('cfg', 'org');
......@@ -33,6 +29,7 @@ function (angular) {
};
$scope.init();
}
}
});
});
angular.module('grafana.controllers').controller('OrgDetailsCtrl', OrgDetailsCtrl);
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);
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);
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) {
import angular from 'angular';
import _ from 'lodash';
import './link_srv';
$scope.panel.links = $scope.panel.links || [];
function panelLinksEditor() {
return {
scope: {
panel: "="
},
restrict: 'E',
controller: 'PanelLinksEditorCtrl',
templateUrl: 'public/app/features/panellinks/module.html',
link: function() {
}
};
}
$scope.addLink = function() {
$scope.panel.links.push({
type: 'dashboard',
});
};
export class PanelLinksEditorCtrl {
/** @ngInject */
constructor($scope, backendSrv) {
$scope.panel.links = $scope.panel.links || [];
$scope.searchDashboards = function(queryStr, callback) {
backendSrv.search({query: queryStr}).then(function(hits) {
var dashboards = _.map(hits, function(dash) {
return dash.title;
});
$scope.addLink = function() {
$scope.panel.links.push({
type: 'dashboard',
});
};
callback(dashboards);
$scope.searchDashboards = function(queryStr, callback) {
backendSrv.search({query: queryStr}).then(function(hits) {
var dashboards = _.map(hits, function(dash) {
return dash.title;
});
};
$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);
};
});
});
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);
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);
......@@ -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() {
......
......@@ -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) {
......
......@@ -25,6 +25,10 @@
<span class="gf-form-label width-9">Version</span>
<select class="gf-form-input gf-size-auto" ng-model="ctrl.current.jsonData.esVersion" ng-options="f.value as f.name for f in ctrl.esVersions"></select>
</div>
<div class="gf-form max-width-30" ng-if="ctrl.current.jsonData.esVersion>=56">
<span class="gf-form-label width-15">Max concurrent Shard Requests</span>
<input class="gf-form-input" type="text" ng-model='ctrl.current.jsonData.maxConcurrentShardRequests' placeholder="" required></input>
</div>
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label width-9">Min interval</span>
......
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;
}
};
});
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',
category: categories.Calculate,
name: "holtWintersForecast",
category: categories.Calculate
});
addFuncDef({
name: 'holtWintersConfidenceBands',
name: "holtWintersConfidenceBands",
category: categories.Calculate,
params: [{ name: 'delta', type: 'int' }],
defaultParams: [3],
params: [{ name: "delta", type: "int" }],
defaultParams: [3]
});
addFuncDef({
name: 'holtWintersAberration',
name: "holtWintersAberration",
category: categories.Calculate,
params: [{ name: 'delta', type: 'int' }],
defaultParams: [3],
params: [{ name: "delta", type: "int" }],
defaultParams: [3]
});
addFuncDef({
name: 'nPercentile',
name: "nPercentile",
category: categories.Calculate,
params: [{ name: 'Nth percentile', type: 'int' }],
defaultParams: [95],
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',
name: "percentileOfSeries",
category: categories.Combine,
params: [{ name: 'n', type: 'int' }, { name: 'interpolate', type: 'boolean', options: ['true', 'false'] }],
defaultParams: [95, 'false'],
params: [
{ name: "n", type: "int" },
{ name: "interpolate", type: "boolean", options: ["true", "false"] }
],
defaultParams: [95, "false"]
});
addFuncDef({
name: 'sumSeriesWithWildcards',
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 },
{ name: "node", type: "int" },
{ name: "node", type: "int", optional: true },
{ name: "node", type: "int", optional: true },
{ name: "node", type: "int", optional: true }
],
defaultParams: [3],
defaultParams: [3]
});
addFuncDef({
name: 'maxSeries',
shortName: 'max',
category: categories.Combine,
name: "maxSeries",
shortName: "max",
category: categories.Combine
});
addFuncDef({
name: 'minSeries',
shortName: 'min',
category: categories.Combine,
name: "minSeries",
shortName: "min",
category: categories.Combine
});
addFuncDef({
name: 'averageSeriesWithWildcards',
name: "averageSeriesWithWildcards",
category: categories.Combine,
params: [{ name: 'node', type: 'int' }, { name: 'node', type: 'int', optional: true }],
defaultParams: [3],
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'],
defaultParams: [3, "sum"]
});
addFuncDef({
name: 'aliasByNode',
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 },
{
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],
defaultParams: [3]
});
addFuncDef({
name: 'substr',
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] },
{
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],
defaultParams: [0, 0]
});
addFuncDef({
name: 'sortByName',
name: "sortByName",
category: categories.Special,
params: [{ name: 'natural', type: 'boolean', options: ['true', 'false'], optional: true }],
defaultParams: ['false'],
params: [
{
name: "natural",
type: "boolean",
options: ["true", "false"],
optional: true
}
],
defaultParams: ["false"]
});
addFuncDef({
name: 'sortByMaxima',
category: categories.Special,
name: "sortByMaxima",
category: categories.Special
});
addFuncDef({
name: 'sortByMinima',
category: categories.Special,
name: "sortByMinima",
category: categories.Special
});
addFuncDef({
name: 'sortByTotal',
category: categories.Special,
name: "sortByTotal",
category: categories.Special
});
addFuncDef({
name: 'aliasByMetric',
category: categories.Special,
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',
category: categories.Special,
name: "countSeries",
category: categories.Special
});
addFuncDef({
name: 'constantLine',
name: "constantLine",
category: categories.Special,
params: [{ name: 'value', type: 'int' }],
defaultParams: [10],
params: [{ name: "value", type: "int" }],
defaultParams: [10]
});
addFuncDef({
name: 'cactiStyle',
category: categories.Special,
name: "cactiStyle",
category: categories.Special
});
addFuncDef({
name: 'keepLastValue',
name: "keepLastValue",
category: categories.Special,
params: [{ name: 'n', type: 'int' }],
defaultParams: [100],
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',
category: categories.Transform,
name: "integral",
category: categories.Transform
});
addFuncDef({
name: 'derivative',
category: categories.Transform,
name: "derivative",
category: categories.Transform
});
addFuncDef({
name: 'nonNegativeDerivative',
name: "nonNegativeDerivative",
category: categories.Transform,
params: [{ name: 'max value or 0', type: 'int', optional: true }],
defaultParams: [''],
params: [{ name: "max value or 0", type: "int", optional: true }],
defaultParams: [""]
});
addFuncDef({
name: 'timeShift',
name: "timeShift",
category: categories.Transform,
params: [{ name: 'amount', type: 'select', options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'] }],
defaultParams: ['1d'],
params: [
{
name: "amount",
type: "select",
options: ["1h", "6h", "12h", "1d", "2d", "7d", "14d", "30d"]
}
],
defaultParams: ["1d"]
});
addFuncDef({
name: 'timeStack',
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' },
{
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],
defaultParams: ["1d", 0, 7]
});
addFuncDef({
name: 'summarize',
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'] },
{ 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'],
defaultParams: ["1h", "sum", "false"]
});
addFuncDef({
name: 'smartSummarize',
name: "smartSummarize",
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"]
}
],
defaultParams: ['1h', 'sum'],
defaultParams: ["1h", "sum"]
});
addFuncDef({
name: 'absolute',
category: categories.Transform,
name: "absolute",
category: categories.Transform
});
addFuncDef({
name: 'hitcount',
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 isVersionRelatedFunction(func, graphiteVersion) {
return (
isVersionGtOrEq(graphiteVersion, func.version) || !func.version
);
}
function isNumeric(obj) {
return !isNaN(parseFloat(obj)) && isFinite(obj);
}
export class FuncInstance {
def: any;
params: any;
text: any;
added: boolean;
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;
}
constructor(funcDef, options) {
this.def = funcDef;
this.params = [];
return "'" + value + "'";
}.bind(this),
);
if (options && options.withDefaultParams) {
this.params = funcDef.defaultParams.slice(0);
}
if (metricExp) {
parameters.unshift(metricExp);
this.updateText();
}
return str + parameters.join(', ') + ')';
};
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);
}
FuncInstance.prototype._hasMultipleParamsInString = function(strValue, index) {
if (strValue.indexOf(',') === -1) {
return false;
return str + parameters.join(", ") + ")";
}
return this.def.params[index + 1] && this.def.params[index + 1].optional;
};
_hasMultipleParamsInString(strValue, index) {
if (strValue.indexOf(",") === -1) {
return false;
}
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;
return this.def.params[index + 1] && this.def.params[index + 1].optional;
}
if (strValue === '' && this.def.params[index].optional) {
this.params.splice(index, 1);
} else {
this.params[index] = strValue;
}
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;
}
this.updateText();
};
if (strValue === "" && this.def.params[index].optional) {
this.params.splice(index, 1);
} else {
this.params[index] = strValue;
}
FuncInstance.prototype.updateText = function() {
if (this.params.length === 0) {
this.text = this.def.name + '()';
return;
this.updateText();
}
var text = this.def.name + '(';
text += this.params.join(', ');
text += ')';
this.text = text;
};
updateText() {
if (this.params.length === 0) {
this.text = this.def.name + "()";
return;
}
function isVersionRelatedFunction(func, graphiteVersion) {
return isVersionGtOrEq(graphiteVersion, func.version) || !func.version;
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;
},
}
};
define([
'lodash'
],
function (_) {
'use strict';
import _ from "lodash";
function PrometheusMetricFindQuery(datasource, query, timeSrv) {
export default class PrometheusMetricFindQuery {
datasource: any;
query: any;
range: any;
constructor(datasource, query, timeSrv) {
this.datasource = datasource;
this.query = query;
this.range = timeSrv.timeRange();
}
PrometheusMetricFindQuery.prototype.process = function() {
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\((.+)\)$/;
......@@ -18,7 +19,10 @@ function (_) {
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]);
return this.labelValuesQuery(
label_values_query[2],
label_values_query[1]
);
} else {
return this.labelValuesQuery(label_values_query[2], null);
}
......@@ -36,29 +40,32 @@ function (_) {
// if query contains full metric name, return metric name and label list
return this.metricNameAndLabelsQuery(this.query);
};
}
PrometheusMetricFindQuery.prototype.labelValuesQuery = function(label, metric) {
labelValuesQuery(label, metric) {
var url;
if (!metric) {
// return label values globally
url = '/api/v1/label/' + label + '/values';
url = "/api/v1/label/" + label + "/values";
return this.datasource._request('GET', url).then(function(result) {
return this.datasource._request("GET", url).then(function(result) {
return _.map(result.data.data, function(value) {
return {text: 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) {
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];
});
......@@ -71,58 +78,64 @@ function (_) {
});
});
}
};
}
PrometheusMetricFindQuery.prototype.metricNameQuery = function(metricFilterPattern) {
var url = '/api/v1/label/__name__/values';
metricNameQuery(metricFilterPattern) {
var url = "/api/v1/label/__name__/values";
return this.datasource._request('GET', url)
.then(function(result) {
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();
.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) {
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 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
};
return {
text: text,
expandable: true
};
});
});
});
};
}
PrometheusMetricFindQuery.prototype.metricNameAndLabelsQuery = function(query) {
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 url =
"/api/v1/series?match[]=" +
encodeURIComponent(query) +
"&start=" +
start +
"&end=" +
end;
var self = this;
return this.datasource._request('GET', url)
.then(function(result) {
return this.datasource._request("GET", url).then(function(result) {
return _.map(result.data.data, function(metric) {
return {
text: self.datasource.getOriginalMetricName(metric),
......@@ -130,7 +143,5 @@ function (_) {
};
});
});
};
return PrometheusMetricFindQuery;
});
}
}
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);
......@@ -17,7 +17,7 @@
"max-line-length": [true, 150],
"member-access": false,
"no-arg": true,
"no-bitwise": true,
"no-bitwise": false,
"no-console": [true,
"debug",
"info",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment