Allow selecting available metrics through UI.

This commit is contained in:
Julius Volz 2013-02-06 17:08:05 +01:00
parent 2659304380
commit 8194702bb3
5 changed files with 64 additions and 8 deletions

View file

@ -2,6 +2,7 @@ package api
import ( import (
"code.google.com/p/gorest" "code.google.com/p/gorest"
"github.com/prometheus/prometheus/storage/metric"
"github.com/prometheus/prometheus/utility" "github.com/prometheus/prometheus/utility"
) )
@ -10,5 +11,14 @@ type MetricsService struct {
query gorest.EndPoint `method:"GET" path:"/query?{expr:string}&{json:string}" output:"string"` query gorest.EndPoint `method:"GET" path:"/query?{expr:string}&{json:string}" output:"string"`
queryRange gorest.EndPoint `method:"GET" path:"/query_range?{expr:string}&{end:int64}&{range:int64}&{step:int64}" output:"string"` queryRange gorest.EndPoint `method:"GET" path:"/query_range?{expr:string}&{end:int64}&{range:int64}&{step:int64}" output:"string"`
time utility.Time metrics gorest.EndPoint `method:"GET" path:"/metrics" output:"string"`
persistence metric.MetricPersistence
time utility.Time
}
func NewMetricsService(p metric.MetricPersistence) *MetricsService {
return &MetricsService{
persistence: p,
}
} }

View file

@ -2,9 +2,11 @@ package api
import ( import (
"code.google.com/p/gorest" "code.google.com/p/gorest"
"encoding/json"
"errors" "errors"
"github.com/prometheus/prometheus/rules" "github.com/prometheus/prometheus/rules"
"github.com/prometheus/prometheus/rules/ast" "github.com/prometheus/prometheus/rules/ast"
"log"
"sort" "sort"
"time" "time"
) )
@ -65,3 +67,22 @@ func (serv MetricsService) QueryRange(Expr string, End int64, Range int64, Step
sort.Sort(matrix) sort.Sort(matrix)
return ast.TypedValueToJSON(matrix, "matrix") return ast.TypedValueToJSON(matrix, "matrix")
} }
func (serv MetricsService) Metrics() string {
metricNames, err := serv.persistence.GetAllMetricNames()
rb := serv.ResponseBuilder()
rb.SetContentType(gorest.Application_Json)
if err != nil {
log.Printf("Error loading metric names: %v", err)
rb.SetResponseCode(500)
return err.Error()
}
sort.Strings(metricNames)
resultBytes, err := json.Marshal(metricNames)
if err != nil {
log.Printf("Error marshalling metric names: %v", err)
rb.SetResponseCode(500)
return err.Error()
}
return string(resultBytes)
}

View file

@ -49,8 +49,7 @@ func main() {
persistence, err := leveldb.NewLevelDBMetricPersistence(*metricsStoragePath) persistence, err := leveldb.NewLevelDBMetricPersistence(*metricsStoragePath)
if err != nil { if err != nil {
log.Print(err) log.Fatalf("Error opening storage: %v", err)
os.Exit(1)
} }
go func() { go func() {
@ -79,7 +78,7 @@ func main() {
} }
go func() { go func() {
gorest.RegisterService(new(api.MetricsService)) gorest.RegisterService(api.NewMetricsService(persistence))
exporter := registry.DefaultRegistry.YieldExporter() exporter := registry.DefaultRegistry.YieldExporter()
http.Handle("/", gorest.Handle()) http.Handle("/", gorest.Handle())

View file

@ -22,7 +22,12 @@
<div class="grouping_box"> <div class="grouping_box">
<form action="/api/query_range" method="GET" class="query_form"> <form action="/api/query_range" method="GET" class="query_form">
<label for="expr{{id}}">Expression:</label> <label for="expr{{id}}">Expression:</label>
<input type="text" name="expr" id="expr{{id}}" size="80" value="{{expr}}"><br> <input type="text" name="expr" id="expr{{id}}" size="80" value="{{expr}}">
<select name="insert_metric">
<option value="">- Insert Metric -</option>
</select>
<br>
<label for="range_input{{id}}">Range:</label> <label for="range_input{{id}}">Range:</label>
<input type="button" value="-" name="dec_range"> <input type="button" value="-" name="dec_range">

View file

@ -69,6 +69,7 @@ Prometheus.Graph.prototype.initialize = function() {
self.expr = graphWrapper.find("input[name=expr]"); self.expr = graphWrapper.find("input[name=expr]");
self.rangeInput = self.queryForm.find("input[name=range_input]"); self.rangeInput = self.queryForm.find("input[name=range_input]");
self.stacked = self.queryForm.find("input[name=stacked]"); self.stacked = self.queryForm.find("input[name=stacked]");
self.insertMetric = self.queryForm.find("select[name=insert_metric]");
self.graph = graphWrapper.find(".graph"); self.graph = graphWrapper.find(".graph");
self.legend = graphWrapper.find(".legend"); self.legend = graphWrapper.find(".legend");
@ -81,18 +82,40 @@ Prometheus.Graph.prototype.initialize = function() {
self.queryForm.find("input[name=inc_range]").click(function() { self.increaseRange(); }); self.queryForm.find("input[name=inc_range]").click(function() { self.increaseRange(); });
self.queryForm.find("input[name=dec_range]").click(function() { self.decreaseRange(); }); self.queryForm.find("input[name=dec_range]").click(function() { self.decreaseRange(); });
self.insertMetric.change(function() {
self.expr.val(self.expr.val() + self.insertMetric.val());
});
self.expr.focus(); // TODO: move to external Graph method. self.expr.focus(); // TODO: move to external Graph method.
self.populateInsertableMetrics();
if (self.expr.val()) { if (self.expr.val()) {
self.submitQuery(); self.submitQuery();
} }
}; };
Prometheus.Graph.prototype.populateInsertableMetrics = function() {
var self = this;
$.ajax({
method: "GET",
url: "/api/metrics",
dataType: "json",
success: function(json, textStatus) {
for (var i = 0; i < json.length; i++) {
self.insertMetric[0].options.add(new Option(json[i], json[i]));
}
},
error: function() {
alert("Error loading available metrics!");
},
});
};
Prometheus.Graph.prototype.onChange = function(handler) { Prometheus.Graph.prototype.onChange = function(handler) {
this.changeHandler = handler; this.changeHandler = handler;
}; };
Prometheus.Graph.prototype.getOptions = function(handler) { Prometheus.Graph.prototype.getOptions = function() {
var self = this; var self = this;
var options = {}; var options = {};
@ -306,8 +329,6 @@ function storeGraphOptionsInUrl(options) {
var allGraphsOptions = []; var allGraphsOptions = [];
for (var i = 0; i < graphs.length; i++) { for (var i = 0; i < graphs.length; i++) {
allGraphsOptions.push(graphs[i].getOptions()); allGraphsOptions.push(graphs[i].getOptions());
console.log(graphs[i].id);
console.log(graphs[i].getOptions());
} }
var optionsJSON = JSON.stringify(allGraphsOptions); var optionsJSON = JSON.stringify(allGraphsOptions);
window.location.hash = encodeURIComponent(optionsJSON); window.location.hash = encodeURIComponent(optionsJSON);