mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'apps'
This commit is contained in:
3
public/app/plugins/datasource/elasticsearch/datasource.d.ts
vendored
Normal file
3
public/app/plugins/datasource/elasticsearch/datasource.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
declare var Datasource: any;
|
||||
export default Datasource;
|
||||
|
||||
@@ -7,33 +7,27 @@ define([
|
||||
'./index_pattern',
|
||||
'./elastic_response',
|
||||
'./query_ctrl',
|
||||
'./directives'
|
||||
],
|
||||
function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticResponse) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
/** @ngInject */
|
||||
function ElasticDatasource(instanceSettings, $q, backendSrv, templateSrv, timeSrv) {
|
||||
this.basicAuth = instanceSettings.basicAuth;
|
||||
this.withCredentials = instanceSettings.withCredentials;
|
||||
this.url = instanceSettings.url;
|
||||
this.name = instanceSettings.name;
|
||||
this.index = instanceSettings.index;
|
||||
this.timeField = instanceSettings.jsonData.timeField;
|
||||
this.esVersion = instanceSettings.jsonData.esVersion;
|
||||
this.indexPattern = new IndexPattern(instanceSettings.index, instanceSettings.jsonData.interval);
|
||||
this.interval = instanceSettings.jsonData.timeInterval;
|
||||
this.queryBuilder = new ElasticQueryBuilder({
|
||||
timeField: this.timeField,
|
||||
esVersion: this.esVersion,
|
||||
});
|
||||
|
||||
module.factory('ElasticDatasource', function($q, backendSrv, templateSrv, timeSrv) {
|
||||
|
||||
function ElasticDatasource(datasource) {
|
||||
this.type = 'elasticsearch';
|
||||
this.basicAuth = datasource.basicAuth;
|
||||
this.withCredentials = datasource.withCredentials;
|
||||
this.url = datasource.url;
|
||||
this.name = datasource.name;
|
||||
this.index = datasource.index;
|
||||
this.timeField = datasource.jsonData.timeField;
|
||||
this.esVersion = datasource.jsonData.esVersion;
|
||||
this.indexPattern = new IndexPattern(datasource.index, datasource.jsonData.interval);
|
||||
this.interval = datasource.jsonData.timeInterval;
|
||||
this.queryBuilder = new ElasticQueryBuilder({
|
||||
timeField: this.timeField,
|
||||
esVersion: this.esVersion,
|
||||
});
|
||||
}
|
||||
|
||||
ElasticDatasource.prototype._request = function(method, url, data) {
|
||||
this._request = function(method, url, data) {
|
||||
var options = {
|
||||
url: this.url + "/" + url,
|
||||
method: method,
|
||||
@@ -52,21 +46,21 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
return backendSrv.datasourceRequest(options);
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype._get = function(url) {
|
||||
this._get = function(url) {
|
||||
return this._request('GET', this.indexPattern.getIndexForToday() + url)
|
||||
.then(function(results) {
|
||||
return results.data;
|
||||
});
|
||||
.then(function(results) {
|
||||
return results.data;
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype._post = function(url, data) {
|
||||
this._post = function(url, data) {
|
||||
return this._request('POST', url, data)
|
||||
.then(function(results) {
|
||||
return results.data;
|
||||
});
|
||||
.then(function(results) {
|
||||
return results.data;
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.annotationQuery = function(options) {
|
||||
this.annotationQuery = function(options) {
|
||||
var annotation = options.annotation;
|
||||
var timeField = annotation.timeField || '@timestamp';
|
||||
var queryString = annotation.query || '*';
|
||||
@@ -147,7 +141,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.testDatasource = function() {
|
||||
this.testDatasource = function() {
|
||||
return this._get('/_stats').then(function() {
|
||||
return { status: "success", message: "Data source is working", title: "Success" };
|
||||
}, function(err) {
|
||||
@@ -159,13 +153,13 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.getQueryHeader = function(searchType, timeFrom, timeTo) {
|
||||
this.getQueryHeader = function(searchType, timeFrom, timeTo) {
|
||||
var header = {search_type: searchType, "ignore_unavailable": true};
|
||||
header.index = this.indexPattern.getIndexList(timeFrom, timeTo);
|
||||
return angular.toJson(header);
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.query = function(options) {
|
||||
this.query = function(options) {
|
||||
var payload = "";
|
||||
var target;
|
||||
var sentTargets = [];
|
||||
@@ -203,7 +197,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.getFields = function(query) {
|
||||
this.getFields = function(query) {
|
||||
return this._get('/_mapping').then(function(res) {
|
||||
var fields = {};
|
||||
var typeMap = {
|
||||
@@ -240,7 +234,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.getTerms = function(queryDef) {
|
||||
this.getTerms = function(queryDef) {
|
||||
var range = timeSrv.timeRange();
|
||||
var header = this.getQueryHeader('count', range.from, range.to);
|
||||
var esQuery = angular.toJson(this.queryBuilder.getTermsQuery(queryDef));
|
||||
@@ -258,7 +252,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.metricFindQuery = function(query) {
|
||||
this.metricFindQuery = function(query) {
|
||||
query = templateSrv.replace(query);
|
||||
query = angular.fromJson(query);
|
||||
if (!query) {
|
||||
@@ -273,14 +267,14 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
}
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.getDashboard = function(id) {
|
||||
this.getDashboard = function(id) {
|
||||
return this._get('/dashboard/' + id)
|
||||
.then(function(result) {
|
||||
return angular.fromJson(result._source.dashboard);
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.searchDashboards = function() {
|
||||
this.searchDashboards = function() {
|
||||
var query = {
|
||||
query: { query_string: { query: '*' } },
|
||||
size: 10000,
|
||||
@@ -308,7 +302,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
return displayHits;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return ElasticDatasource;
|
||||
});
|
||||
return ElasticDatasource;
|
||||
});
|
||||
|
||||
@@ -20,6 +20,10 @@ function (angular) {
|
||||
return {templateUrl: 'app/plugins/datasource/elasticsearch/partials/annotations.editor.html'};
|
||||
});
|
||||
|
||||
module.directive('elastic', function() {
|
||||
return {templateUrl: 'app/plugins/datasource/elasticsearch/partials/config.html'};
|
||||
});
|
||||
|
||||
module.directive('elasticMetricAgg', function() {
|
||||
return {
|
||||
templateUrl: 'app/plugins/datasource/elasticsearch/partials/metric_agg.html',
|
||||
|
||||
38
public/app/plugins/datasource/elasticsearch/edit_view.ts
Normal file
38
public/app/plugins/datasource/elasticsearch/edit_view.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
///<reference path="../../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
|
||||
export class EditViewCtrl {
|
||||
|
||||
constructor($scope) {
|
||||
$scope.indexPatternTypes = [
|
||||
{name: 'No pattern', value: undefined},
|
||||
{name: 'Hourly', value: 'Hourly', example: '[logstash-]YYYY.MM.DD.HH'},
|
||||
{name: 'Daily', value: 'Daily', example: '[logstash-]YYYY.MM.DD'},
|
||||
{name: 'Weekly', value: 'Weekly', example: '[logstash-]GGGG.WW'},
|
||||
{name: 'Monthly', value: 'Monthly', example: '[logstash-]YYYY.MM'},
|
||||
{name: 'Yearly', value: 'Yearly', example: '[logstash-]YYYY'},
|
||||
];
|
||||
|
||||
$scope.esVersions = [
|
||||
{name: '1.x', value: 1},
|
||||
{name: '2.x', value: 2},
|
||||
];
|
||||
|
||||
$scope.indexPatternTypeChanged = function() {
|
||||
var def = _.findWhere($scope.indexPatternTypes, {value: $scope.current.jsonData.interval});
|
||||
$scope.current.database = def.example || 'es-index-name';
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function editViewDirective() {
|
||||
return {
|
||||
templateUrl: 'app/plugins/datasource/elasticsearch/partials/edit_view.html',
|
||||
controller: EditViewCtrl,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
export default editViewDirective;
|
||||
60
public/app/plugins/datasource/elasticsearch/module.js
Normal file
60
public/app/plugins/datasource/elasticsearch/module.js
Normal file
@@ -0,0 +1,60 @@
|
||||
define([
|
||||
'angular',
|
||||
'./datasource',
|
||||
'./edit_view',
|
||||
'./bucket_agg',
|
||||
'./metric_agg',
|
||||
],
|
||||
function (angular, ElasticDatasource, editView) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.directives');
|
||||
|
||||
module.directive('metricQueryEditorElasticsearch', function() {
|
||||
return {controller: 'ElasticQueryCtrl', templateUrl: 'app/plugins/datasource/elasticsearch/partials/query.editor.html'};
|
||||
});
|
||||
|
||||
module.directive('metricQueryOptionsElasticsearch', function() {
|
||||
return {templateUrl: 'app/plugins/datasource/elasticsearch/partials/query.options.html'};
|
||||
});
|
||||
|
||||
module.directive('annotationsQueryEditorElasticsearch', function() {
|
||||
return {templateUrl: 'app/plugins/datasource/elasticsearch/partials/annotations.editor.html'};
|
||||
});
|
||||
|
||||
module.directive('elasticMetricAgg', function() {
|
||||
return {
|
||||
templateUrl: 'app/plugins/datasource/elasticsearch/partials/metric_agg.html',
|
||||
controller: 'ElasticMetricAggCtrl',
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
target: "=",
|
||||
index: "=",
|
||||
onChange: "&",
|
||||
getFields: "&",
|
||||
esVersion: '='
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('elasticBucketAgg', function() {
|
||||
return {
|
||||
templateUrl: 'app/plugins/datasource/elasticsearch/partials/bucket_agg.html',
|
||||
controller: 'ElasticBucketAggCtrl',
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
target: "=",
|
||||
index: "=",
|
||||
onChange: "&",
|
||||
getFields: "&",
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('datasourceCustomSettingsViewElasticsearch', editView.default);
|
||||
|
||||
return {
|
||||
Datasource: ElasticDatasource,
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,5 +1,4 @@
|
||||
<div ng-include="httpConfigPartialSrc"></div>
|
||||
<br>
|
||||
<datasource-http-settings></datasource-http-settings>
|
||||
|
||||
<h5>Elasticsearch details</h5>
|
||||
|
||||
@@ -42,8 +41,8 @@
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<h5>Default query settings</h5>
|
||||
|
||||
<div class="tight-form last">
|
||||
@@ -53,7 +52,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-medium tight-form-input input-xlarge" ng-model="current.jsonData.timeInterval"
|
||||
spellcheck='false' placeholder="example: >10s">
|
||||
spellcheck='false' placeholder="example: >10s">
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
<i class="fa fa-question-circle" bs-tooltip="'Set a low limit by having a greater sign: example: >10s'" data-placement="right"></i>
|
||||
@@ -1,16 +1,7 @@
|
||||
{
|
||||
"pluginType": "datasource",
|
||||
"type": "datasource",
|
||||
"name": "Elasticsearch",
|
||||
|
||||
"type": "elasticsearch",
|
||||
"serviceName": "ElasticDatasource",
|
||||
|
||||
"module": "app/plugins/datasource/elasticsearch/datasource",
|
||||
|
||||
"partials": {
|
||||
"config": "app/plugins/datasource/elasticsearch/partials/config.html",
|
||||
"annotations": "app/plugins/datasource/elasticsearch/partials/annotations.editor.html"
|
||||
},
|
||||
"id": "elasticsearch",
|
||||
|
||||
"defaultMatchFormat": "lucene",
|
||||
"annotations": true,
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
|
||||
import "../datasource";
|
||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
||||
import moment from 'moment';
|
||||
import angular from 'angular';
|
||||
import helpers from 'test/specs/helpers';
|
||||
import Datasource from "../datasource";
|
||||
|
||||
describe('ElasticDatasource', function() {
|
||||
var ctx = new helpers.ServiceTestContext();
|
||||
var instanceSettings: any = {jsonData: {}};
|
||||
|
||||
beforeEach(angularMocks.module('grafana.core'));
|
||||
beforeEach(angularMocks.module('grafana.services'));
|
||||
beforeEach(ctx.providePhase(['templateSrv', 'backendSrv']));
|
||||
beforeEach(ctx.createService('ElasticDatasource'));
|
||||
beforeEach(function() {
|
||||
ctx.ds = new ctx.service({jsonData: {}});
|
||||
});
|
||||
beforeEach(angularMocks.inject(function($q, $rootScope, $httpBackend, $injector) {
|
||||
ctx.$q = $q;
|
||||
ctx.$httpBackend = $httpBackend;
|
||||
ctx.$rootScope = $rootScope;
|
||||
ctx.$injector = $injector;
|
||||
}));
|
||||
|
||||
function createDatasource(instanceSettings) {
|
||||
instanceSettings.jsonData = instanceSettings.jsonData || {};
|
||||
ctx.ds = ctx.$injector.instantiate(Datasource, {instanceSettings: instanceSettings});
|
||||
}
|
||||
|
||||
describe('When testing datasource with index pattern', function() {
|
||||
beforeEach(function() {
|
||||
ctx.ds = new ctx.service({
|
||||
url: 'http://es.com',
|
||||
index: '[asd-]YYYY.MM.DD',
|
||||
jsonData: { interval: 'Daily' }
|
||||
});
|
||||
createDatasource({url: 'http://es.com', index: '[asd-]YYYY.MM.DD', jsonData: {interval: 'Daily'}});
|
||||
});
|
||||
|
||||
it('should translate index pattern to current day', function() {
|
||||
@@ -44,11 +48,7 @@ describe('ElasticDatasource', function() {
|
||||
var requestOptions, parts, header;
|
||||
|
||||
beforeEach(function() {
|
||||
ctx.ds = new ctx.service({
|
||||
url: 'http://es.com',
|
||||
index: '[asd-]YYYY.MM.DD',
|
||||
jsonData: { interval: 'Daily' }
|
||||
});
|
||||
createDatasource({url: 'http://es.com', index: '[asd-]YYYY.MM.DD', jsonData: {interval: 'Daily'}});
|
||||
|
||||
ctx.backendSrv.datasourceRequest = function(options) {
|
||||
requestOptions = options;
|
||||
@@ -83,7 +83,7 @@ describe('ElasticDatasource', function() {
|
||||
var requestOptions, parts, header;
|
||||
|
||||
beforeEach(function() {
|
||||
ctx.ds = new ctx.service({url: 'http://es.com', index: 'test', jsonData: {}});
|
||||
createDatasource({url: 'http://es.com', index: 'test'});
|
||||
|
||||
ctx.backendSrv.datasourceRequest = function(options) {
|
||||
requestOptions = options;
|
||||
|
||||
Reference in New Issue
Block a user