mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-25 05:34:05 -08:00
More efficient JSON query result format.
This depends on https://github.com/prometheus/client_golang/pull/51. For vectors, the result format looks like this: ```json { "version": 1, "type" : "vector", "value" : [ { "timestamp" : 1421765411.045, "value" : "65.475000", "metric" : { "quantile" : "0.5", "instance" : "http://localhost:9090/metrics", "job" : "prometheus", "__name__" : "http_request_duration_microseconds", "handler" : "/static/", "method" : "get", "code" : "304" } }, { "timestamp" : 1421765411.045, "value" : "5826.339000", "metric" : { "quantile" : "0.9", "instance" : "http://localhost:9090/metrics", "job" : "prometheus", "__name__" : "http_request_duration_microseconds", "handler" : "prometheus", "method" : "get", "code" : "200" } }, /* ... */ ] } ``` For matrices, it looks like this: ```json { "version": 1, "type" : "matrix", "value" : [ { "metric" : { "quantile" : "0.99", "instance" : "http://localhost:9090/metrics", "job" : "prometheus", "__name__" : "http_request_duration_microseconds", "handler" : "/static/", "method" : "get", "code" : "200" }, "values" : [ [ 1421765547.659, "29162.953000" ], [ 1421765548.659, "29162.953000" ], [ 1421765549.659, "29162.953000" ], /* ... */ ] } ] } ```
This commit is contained in:
parent
f7e3da5488
commit
d4374a9265
|
@ -81,7 +81,7 @@ func TestNotificationHandler(t *testing.T) {
|
|||
// Correct message.
|
||||
summary: "Summary",
|
||||
description: "Description",
|
||||
message: `[{"Description":"Description","Labels":{"instance":"testinstance"},"Payload":{"ActiveSince":"0001-01-01T00:00:00Z","AlertingRule":"Test rule string","GeneratorURL":"prometheus_url","Value":"0.333333"},"Summary":"Summary"}]`,
|
||||
message: `[{"Description":"Description","Labels":{"instance":"testinstance"},"Payload":{"ActiveSince":"0001-01-01T00:00:00Z","AlertingRule":"Test rule string","GeneratorURL":"prometheus_url","Value":"0.3333333333333333"},"Summary":"Summary"}]`,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -36,15 +36,15 @@ var stalenessDelta = flag.Duration("query.staleness-delta", 300*time.Second, "St
|
|||
|
||||
// SampleStream is a stream of Values belonging to an attached COWMetric.
|
||||
type SampleStream struct {
|
||||
Metric clientmodel.COWMetric
|
||||
Values metric.Values
|
||||
Metric clientmodel.COWMetric `json:"metric"`
|
||||
Values metric.Values `json:"values"`
|
||||
}
|
||||
|
||||
// Sample is a single sample belonging to a COWMetric.
|
||||
type Sample struct {
|
||||
Metric clientmodel.COWMetric
|
||||
Value clientmodel.SampleValue
|
||||
Timestamp clientmodel.Timestamp
|
||||
Metric clientmodel.COWMetric `json:"metric"`
|
||||
Value clientmodel.SampleValue `json:"value"`
|
||||
Timestamp clientmodel.Timestamp `json:"timestamp"`
|
||||
}
|
||||
|
||||
// Vector is basically only an alias for clientmodel.Samples, but the
|
||||
|
|
|
@ -37,6 +37,8 @@ const (
|
|||
JSON
|
||||
)
|
||||
|
||||
const jsonFormatVersion = 1
|
||||
|
||||
func (opType BinOpType) String() string {
|
||||
opTypeMap := map[BinOpType]string{
|
||||
Add: "+",
|
||||
|
@ -121,11 +123,13 @@ func (matrix Matrix) String() string {
|
|||
// ErrorToJSON converts the given error into JSON.
|
||||
func ErrorToJSON(err error) string {
|
||||
errorStruct := struct {
|
||||
Type string
|
||||
Value string
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
Version int `json:"version"`
|
||||
}{
|
||||
Type: "error",
|
||||
Value: err.Error(),
|
||||
Type: "error",
|
||||
Value: err.Error(),
|
||||
Version: jsonFormatVersion,
|
||||
}
|
||||
|
||||
errorJSON, err := json.Marshal(errorStruct)
|
||||
|
@ -139,11 +143,13 @@ func ErrorToJSON(err error) string {
|
|||
// 'vector', or 'matrix' into its JSON representation.
|
||||
func TypedValueToJSON(data interface{}, typeStr string) string {
|
||||
dataStruct := struct {
|
||||
Type string
|
||||
Value interface{}
|
||||
Type string `json:"type"`
|
||||
Value interface{} `json:"value"`
|
||||
Version int `json:"version"`
|
||||
}{
|
||||
Type: typeStr,
|
||||
Value: data,
|
||||
Type: typeStr,
|
||||
Value: data,
|
||||
Version: jsonFormatVersion,
|
||||
}
|
||||
dataJSON, err := json.Marshal(dataStruct)
|
||||
if err != nil {
|
||||
|
|
|
@ -15,13 +15,14 @@ package metric
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
clientmodel "github.com/prometheus/client_golang/model"
|
||||
)
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
func (s SamplePair) MarshalJSON() ([]byte, error) {
|
||||
return []byte(fmt.Sprintf("{\"Value\": \"%f\", \"Timestamp\": %s}", s.Value, s.Timestamp.String())), nil
|
||||
return []byte(fmt.Sprintf("[%s, \"%s\"]", s.Timestamp.String(), strconv.FormatFloat(float64(s.Value), 'f', -1, 64))), nil
|
||||
}
|
||||
|
||||
// SamplePair pairs a SampleValue with a Timestamp.
|
||||
|
|
|
@ -385,18 +385,18 @@ Prometheus.Graph.prototype.parseValue = function(value) {
|
|||
Prometheus.Graph.prototype.transformData = function(json) {
|
||||
self = this;
|
||||
var palette = new Rickshaw.Color.Palette();
|
||||
if (json.Type != "matrix") {
|
||||
if (json.type != "matrix") {
|
||||
self.showError("Result is not of matrix type! Please enter a correct expression.");
|
||||
return [];
|
||||
}
|
||||
var data = json.Value.map(function(ts) {
|
||||
var data = json.value.map(function(ts) {
|
||||
return {
|
||||
name: escapeHTML(self.metricToTsName(ts.Metric)),
|
||||
labels: ts.Metric,
|
||||
data: ts.Values.map(function(value) {
|
||||
name: escapeHTML(self.metricToTsName(ts.metric)),
|
||||
labels: ts.metric,
|
||||
data: ts.values.map(function(value) {
|
||||
return {
|
||||
x: value.Timestamp,
|
||||
y: self.parseValue(value.Value)
|
||||
x: value[0],
|
||||
y: self.parseValue(value[1])
|
||||
}
|
||||
}),
|
||||
color: palette.color()
|
||||
|
@ -506,8 +506,8 @@ Prometheus.Graph.prototype.resizeGraph = function() {
|
|||
|
||||
Prometheus.Graph.prototype.handleGraphResponse = function(json, textStatus) {
|
||||
var self = this
|
||||
if (json.Type == "error") {
|
||||
self.showError(json.Value);
|
||||
if (json.type == "error") {
|
||||
self.showError(json.value);
|
||||
return;
|
||||
}
|
||||
self.data = self.transformData(json);
|
||||
|
@ -526,38 +526,38 @@ Prometheus.Graph.prototype.handleConsoleResponse = function(data, textStatus) {
|
|||
var tBody = self.consoleTab.find(".console_table tbody");
|
||||
tBody.empty();
|
||||
|
||||
switch(data.Type) {
|
||||
switch(data.type) {
|
||||
case "vector":
|
||||
if (data.Value.length === 0) {
|
||||
if (data.value.length === 0) {
|
||||
tBody.append("<tr><td colspan='2'><i>no data</i></td></tr>");
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < data.Value.length; i++) {
|
||||
var v = data.Value[i];
|
||||
var tsName = self.metricToTsName(v.Metric);
|
||||
tBody.append("<tr><td>" + escapeHTML(tsName) + "</td><td>" + v.Value + "</td></tr>");
|
||||
for (var i = 0; i < data.value.length; i++) {
|
||||
var v = data.value[i];
|
||||
var tsName = self.metricToTsName(v.metric);
|
||||
tBody.append("<tr><td>" + escapeHTML(tsName) + "</td><td>" + v.value + "</td></tr>");
|
||||
}
|
||||
break;
|
||||
case "matrix":
|
||||
if (data.Value.length === 0) {
|
||||
if (data.value.length === 0) {
|
||||
tBody.append("<tr><td colspan='2'><i>no data</i></td></tr>");
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < data.Value.length; i++) {
|
||||
var v = data.Value[i];
|
||||
var tsName = self.metricToTsName(v.Metric);
|
||||
for (var i = 0; i < data.value.length; i++) {
|
||||
var v = data.value[i];
|
||||
var tsName = self.metricToTsName(v.metric);
|
||||
var valueText = "";
|
||||
for (var j = 0; j < v.Values.length; j++) {
|
||||
valueText += v.Values[j].Value + " @" + v.Values[j].Timestamp + "<br/>";
|
||||
for (var j = 0; j < v.values.length; j++) {
|
||||
valueText += v.values[j][1] + " @" + v.values[j][0] + "<br/>";
|
||||
}
|
||||
tBody.append("<tr><td>" + escapeHTML(tsName) + "</td><td>" + valueText + "</td></tr>")
|
||||
}
|
||||
break;
|
||||
case "scalar":
|
||||
tBody.append("<tr><td>scalar</td><td>" + data.Value + "</td></tr>");
|
||||
tBody.append("<tr><td>scalar</td><td>" + data.value + "</td></tr>");
|
||||
break;
|
||||
case "error":
|
||||
self.showError(data.Value);
|
||||
self.showError(data.value);
|
||||
break;
|
||||
default:
|
||||
self.showError("Unsupported value type!");
|
||||
|
|
|
@ -397,11 +397,11 @@ PromConsole.Graph.prototype._render = function(data) {
|
|||
// Get the data into the right format.
|
||||
var seriesLen = 0;
|
||||
for (var e = 0; e < data.length; e++) {
|
||||
for (var i = 0; i < data[e].Value.length; i++) {
|
||||
for (var i = 0; i < data[e].value.length; i++) {
|
||||
series[seriesLen++] = {
|
||||
data: data[e].Value[i].Values.map(function(s) {return {x: s.Timestamp, y: parseFloat(s.Value)} }),
|
||||
data: data[e].value[i].values.map(function(s) {return {x: s[0], y: parseFloat(s[1])} }),
|
||||
color: palette.color(),
|
||||
name: nameFunc(data[e].Value[i].Metric),
|
||||
name: nameFunc(data[e].value[i].metric),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -549,12 +549,12 @@ PromConsole._chooseNameFunction = function(data) {
|
|||
// If only one label varies, use that value.
|
||||
var labelValues = {};
|
||||
for (var e = 0; e < data.length; e++) {
|
||||
for (var i = 0; i < data[e].Value.length; i++) {
|
||||
for (var label in data[e].Value[i].Metric) {
|
||||
for (var i = 0; i < data[e].value.length; i++) {
|
||||
for (var label in data[e].value[i].metric) {
|
||||
if (!(label in labelValues)) {
|
||||
labelValues[label] = {};
|
||||
}
|
||||
labelValues[label][data[e].Value[i].Metric[label]] = 1;
|
||||
labelValues[label][data[e].value[i].metric[label]] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue