mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Elastic search annotations are working, need to refactor and unify datasource abstraction more, #201
This commit is contained in:
parent
4e47447dec
commit
fa3b84a615
@ -12,6 +12,7 @@
|
||||
- [Issue #610](https://github.com/grafana/grafana/issues/610). InfluxDB: Support for InfluxdB v0.8 list series response schemea (series typeahead)
|
||||
- [Issue #266](https://github.com/grafana/grafana/issues/266). Graphite: New option cacheTimeout to override graphite default memcache timeout
|
||||
- [Issue #606](https://github.com/grafana/grafana/issues/606). General: New global option in config.js to specify admin password (useful to hinder users from accidentally make changes)
|
||||
- [Issue #201](https://github.com/grafana/grafana/issues/201). Annotations: Elasticsearch datasource support for events
|
||||
|
||||
**Changes**
|
||||
- [Issue #536](https://github.com/grafana/grafana/issues/536). Graphite: Use unix epoch for Graphite from/to for absolute time ranges
|
||||
|
@ -12,7 +12,7 @@ function (angular, app, _) {
|
||||
var module = angular.module('grafana.panels.annotations', []);
|
||||
app.useModule(module);
|
||||
|
||||
module.controller('AnnotationsEditorCtrl', function($scope, datasourceSrv, $rootScope) {
|
||||
module.controller('AnnotationsEditorCtrl', function($scope, datasourceSrv) {
|
||||
|
||||
var annotationDefaults = {
|
||||
name: '',
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
<li ng-show="dashboard.loader.save_elasticsearch">
|
||||
<form class="input-prepend nomargin save-dashboard-dropdown-save-form">
|
||||
<input class='input-medium' ng-model="dashboard.title" type="text" ng-model="elasticsearch.title"/>
|
||||
<input class='input-medium' ng-model="dashboard.title" type="text" />
|
||||
<button class="btn" ng-click="saveDashboard()"><i class="icon-save"></i></button>
|
||||
</form>
|
||||
</li>
|
||||
|
@ -1 +1,39 @@
|
||||
<h2>Elasticsearch</h2>
|
||||
<div class="editor-row">
|
||||
<div class="section">
|
||||
<h5>Index name</h5>
|
||||
<div class="editor-option">
|
||||
<input type="text" class="span4" ng-model='currentAnnotation.index' placeholder="events-*"></input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h5>Search query (lucene) <tip>Use [[filterName]] in query to replace part of the query with a filter value</h5>
|
||||
<div class="editor-option">
|
||||
<input type="text" class="span6" ng-model='currentAnnotation.query' placeholder="tags:deploy"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="editor-row">
|
||||
<div class="section">
|
||||
<h5>Field mappings</h5>
|
||||
<div class="editor-option">
|
||||
<label class="small">Time</label>
|
||||
<input type="text" class="input-small" ng-model='currentAnnotation.timeField' placeholder="@timestamp"></input>
|
||||
</div>
|
||||
|
||||
<div class="editor-option">
|
||||
<label class="small">Title</label>
|
||||
<input type="text" class="input-small" ng-model='currentAnnotation.titleField' placeholder="desc"></input>
|
||||
</div>
|
||||
|
||||
<div class="editor-option">
|
||||
<label class="small">Tags</label>
|
||||
<input type="text" class="input-small" ng-model='currentAnnotation.tagsField' placeholder="tags"></input>
|
||||
</div>
|
||||
|
||||
<div class="editor-option">
|
||||
<label class="small">Text</label>
|
||||
<input type="text" class="input-small" ng-model='currentAnnotation.textField' placeholder=""></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -64,7 +64,7 @@ define([
|
||||
function addAnnotation(options) {
|
||||
var tooltip = "<small><b>" + options.title + "</b><br/>";
|
||||
if (options.tags) {
|
||||
tooltip += (options.tags || '') + '<br/>';
|
||||
tooltip += '<span class="tag label label-tag">' + (options.tags || '') + '</span><br/>';
|
||||
}
|
||||
|
||||
if (timezone === 'browser') {
|
||||
|
@ -19,10 +19,87 @@ function (angular, _, $, config, kbn, moment) {
|
||||
this.url = datasource.url;
|
||||
this.name = datasource.name;
|
||||
this.supportAnnotations = true;
|
||||
this.index = datasource.index;
|
||||
this.annotationEditorSrc = 'app/partials/elasticsearch/annotation_editor.html';
|
||||
}
|
||||
|
||||
ElasticDatasource.prototype._request = function(method, url, data) {
|
||||
var options = {
|
||||
url: this.url + "/" + this.index + url,
|
||||
method: method,
|
||||
data: data
|
||||
};
|
||||
|
||||
if (config.elasticsearchBasicAuth) {
|
||||
options.headers = {
|
||||
"Authorization": "Basic " + config.elasticsearchBasicAuth
|
||||
};
|
||||
}
|
||||
|
||||
return $http(options);
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype._get = function(url) {
|
||||
return this._request('GET', url)
|
||||
.then(function(results) {
|
||||
return results.data;
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype._post = function(url, data) {
|
||||
return this._request('POST', url, data)
|
||||
.then(function(results) {
|
||||
return results.data;
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.annotationQuery = function(annotation, filterSrv, rangeUnparsed) {
|
||||
var range = {};
|
||||
var timeField = annotation.timeField || '@timestamp';
|
||||
var queryString = annotation.query || '*';
|
||||
var tagsField = annotation.tagsField || 'tags';
|
||||
var titleField = annotation.titleField || 'desc';
|
||||
var textField = annotation.textField || null;
|
||||
|
||||
range[annotation.timeField]= {
|
||||
from: rangeUnparsed.from,
|
||||
to: rangeUnparsed.to,
|
||||
};
|
||||
|
||||
var filter = { "bool": { "must": [{ "range": range }] } };
|
||||
var query = { "bool": { "should": [{ "query_string": { "query": queryString } }] } };
|
||||
var data = { "query" : { "filtered": { "query" : query, "filter": filter } }, "size": 100 };
|
||||
|
||||
this.index = annotation.index;
|
||||
|
||||
return this._request('POST', '/_search', data).then(function(results) {
|
||||
var list = [];
|
||||
var hits = results.data.hits.hits;
|
||||
|
||||
for (var i = 0; i < hits.length; i++) {
|
||||
var source = hits[i]._source;
|
||||
var event = {
|
||||
annotation: annotation,
|
||||
time: moment.utc(source[timeField]).valueOf(),
|
||||
title: source[titleField],
|
||||
};
|
||||
|
||||
if (source[tagsField]) {
|
||||
if (_.isArray(source[tagsField])) {
|
||||
event.tags = source[tagsField].join(', ');
|
||||
}
|
||||
else {
|
||||
event.tags = source[tagsField];
|
||||
}
|
||||
}
|
||||
if (textField && source[textField]) {
|
||||
event.text = source[textField];
|
||||
}
|
||||
|
||||
list.push(event);
|
||||
}
|
||||
return list;
|
||||
});
|
||||
};
|
||||
|
||||
return ElasticDatasource;
|
||||
|
2
src/css/bootstrap.dark.min.css
vendored
2
src/css/bootstrap.dark.min.css
vendored
File diff suppressed because one or more lines are too long
2
src/css/bootstrap.light.min.css
vendored
2
src/css/bootstrap.light.min.css
vendored
File diff suppressed because one or more lines are too long
2
src/css/default.min.css
vendored
2
src/css/default.min.css
vendored
File diff suppressed because one or more lines are too long
@ -128,4 +128,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.annotation-tags {
|
||||
color: @purple;
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ module.exports = function(config) {
|
||||
'app/routes/**/*.js',
|
||||
'app/app.js',
|
||||
'vendor/angular/**/*.js',
|
||||
'vendor/elasticjs/elastic-angular-client.js'
|
||||
],
|
||||
dest: '<%= tempDir %>'
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user