mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
add prometheus annotation query
This commit is contained in:
parent
80e15dd754
commit
f8b05e0f42
@ -188,6 +188,58 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
|
||||
}
|
||||
};
|
||||
|
||||
this.annotationQuery = function(options) {
|
||||
var annotation = options.annotation;
|
||||
var expr = annotation.expr || '';
|
||||
var tagKeys = annotation.tagKeys || '';
|
||||
var titleFormat = annotation.titleFormat || '';
|
||||
var textFormat = annotation.textFormat || '';
|
||||
|
||||
if (!expr) { return $q.when([]); }
|
||||
|
||||
var interpolated;
|
||||
try {
|
||||
interpolated = templateSrv.replace(expr);
|
||||
}
|
||||
catch (err) {
|
||||
return $q.reject(err);
|
||||
}
|
||||
|
||||
var query = {
|
||||
expr: interpolated,
|
||||
step: '60s'
|
||||
};
|
||||
var start = getPrometheusTime(options.range.from, false);
|
||||
var end = getPrometheusTime(options.range.to, true);
|
||||
return this.performTimeSeriesQuery(query, start, end).then(function(results) {
|
||||
var eventList = [];
|
||||
tagKeys = tagKeys.split(',');
|
||||
|
||||
_.each(results.data.data.result, function(series) {
|
||||
var tags = _.chain(series.metric)
|
||||
.filter(function(v, k) {
|
||||
return _.contains(tagKeys, k);
|
||||
}).value();
|
||||
|
||||
_.each(series.values, function(value) {
|
||||
if (value[1] === '1') {
|
||||
var event = {
|
||||
annotation: annotation,
|
||||
time: Math.floor(value[0]) * 1000,
|
||||
title: renderTemplate(titleFormat, series.metric),
|
||||
tags: tags,
|
||||
text: renderTemplate(textFormat, series.metric)
|
||||
};
|
||||
|
||||
eventList.push(event);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return eventList;
|
||||
});
|
||||
};
|
||||
|
||||
this.testDatasource = function() {
|
||||
return this.metricFindQuery('metrics(.*)').then(function() {
|
||||
return { status: 'success', message: 'Data source is working', title: 'Success' };
|
||||
@ -240,22 +292,25 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
|
||||
return getOriginalMetricName(labelData);
|
||||
}
|
||||
|
||||
var originalSettings = _.templateSettings;
|
||||
return renderTemplate(options.legendFormat, labelData) || '{}';
|
||||
}
|
||||
|
||||
function renderTemplate(format, data) {
|
||||
_.templateSettings = {
|
||||
interpolate: /\{\{(.+?)\}\}/g
|
||||
};
|
||||
|
||||
var template = _.template(templateSrv.replace(options.legendFormat));
|
||||
var metricName;
|
||||
var template = _.template(templateSrv.replace(format));
|
||||
var result;
|
||||
try {
|
||||
metricName = template(labelData);
|
||||
result = template(data);
|
||||
} catch (e) {
|
||||
metricName = '{}';
|
||||
result = null;
|
||||
}
|
||||
|
||||
_.templateSettings = originalSettings;
|
||||
|
||||
return metricName;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getOriginalMetricName(labelData) {
|
||||
|
@ -5,8 +5,13 @@ class PrometheusConfigCtrl {
|
||||
static templateUrl = 'public/app/plugins/datasource/prometheus/partials/config.html';
|
||||
}
|
||||
|
||||
class PrometheusAnnotationsQueryCtrl {
|
||||
static templateUrl = 'public/app/plugins/datasource/prometheus/partials/annotations.editor.html';
|
||||
}
|
||||
|
||||
export {
|
||||
PrometheusDatasource as Datasource,
|
||||
PrometheusQueryCtrl as QueryCtrl,
|
||||
PrometheusConfigCtrl as ConfigCtrl
|
||||
PrometheusConfigCtrl as ConfigCtrl,
|
||||
PrometheusAnnotationsQueryCtrl as AnnotationsQueryCtrl,
|
||||
};
|
||||
|
@ -0,0 +1,28 @@
|
||||
<div class="editor-row">
|
||||
<div class="section">
|
||||
<h5>Search expression</h5>
|
||||
<div class="editor-option">
|
||||
<input type="text" class="span6" ng-model='currentAnnotation.expr' placeholder="ALERTS"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="editor-row">
|
||||
<div class="section">
|
||||
<h5>Field formats</h5>
|
||||
<div class="editor-option">
|
||||
<label class="small">Title</label>
|
||||
<input type="text" class="input-small" ng-model='currentAnnotation.titleFormat' placeholder="alertname"></input>
|
||||
</div>
|
||||
|
||||
<div class="editor-option">
|
||||
<label class="small">Tags</label>
|
||||
<input type="text" class="input-small" ng-model='currentAnnotation.tagKeys' placeholder="label1,label2"></input>
|
||||
</div>
|
||||
|
||||
<div class="editor-option">
|
||||
<label class="small">Text</label>
|
||||
<input type="text" class="input-small" ng-model='currentAnnotation.textFormat' placeholder="instance"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -3,5 +3,6 @@
|
||||
"name": "Prometheus",
|
||||
"id": "prometheus",
|
||||
|
||||
"metrics": true
|
||||
"metrics": true,
|
||||
"annotations": true
|
||||
}
|
||||
|
@ -157,4 +157,39 @@ describe('PrometheusDatasource', function() {
|
||||
expect(results.length).to.be(3);
|
||||
});
|
||||
});
|
||||
describe('When performing annotationQuery', function() {
|
||||
var results;
|
||||
var urlExpected = 'proxied/api/v1/query_range?query=' +
|
||||
encodeURIComponent('ALERTS{alertstate="firing"}') +
|
||||
'&start=1443438675&end=1443460275&step=60s';
|
||||
var annotation = {
|
||||
expr: 'ALERTS{alertstate="firing"}',
|
||||
tagKeys: 'job',
|
||||
titleFormat: '{{alertname}}',
|
||||
textFormat: '{{instance}}'
|
||||
};
|
||||
var response = {
|
||||
status: "success",
|
||||
data: {
|
||||
resultType: "matrix",
|
||||
result: [{
|
||||
metric: {"__name__": "ALERTS", alertname: "InstanceDown", alertstate: "firing", instance: "testinstance", job: "testjob"},
|
||||
values: [[1443454528, "1"]]
|
||||
}]
|
||||
}
|
||||
};
|
||||
beforeEach(function() {
|
||||
ctx.$httpBackend.expect('GET', urlExpected).respond(response);
|
||||
ctx.ds.annotationQuery(annotation, {from: moment(1443438674760), to: moment(1443460274760)}).then(function(data) { results = data; });
|
||||
ctx.$httpBackend.flush();
|
||||
});
|
||||
it('should return annotation list', function() {
|
||||
ctx.$rootScope.$apply();
|
||||
expect(results.length).to.be(1);
|
||||
expect(results[0].tags).to.contain('testjob');
|
||||
expect(results[0].title).to.be('InstanceDown');
|
||||
expect(results[0].text).to.be('testinstance');
|
||||
expect(results[0].time).to.be(1443454528 * 1000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user