mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-25 13:44:05 -08:00
Drop metric names after transformations.
After many transformations, it doesn't make sense to keep the metric names, since the result of the transformation is no longer that metric. This drops the metric name after such transformations and makes the web UI deal well with missing metric names. This depends on the current branch on the following things: - prometheus/client_golang needs to be ate237cf15c6
in branch "julius/int-fingerprints" (to be merged with new storage) - prometheus/promdash needs to be atdd7691c9c2
Change-Id: Ib3c8cad8d647d9854e8c653c424b8c235ccc231d
This commit is contained in:
parent
53c0a43754
commit
3d47f94149
|
@ -83,6 +83,17 @@ const (
|
|||
OR
|
||||
)
|
||||
|
||||
// shouldDropMetric indicates whether the metric name should be dropped after
|
||||
// applying this operator to a vector.
|
||||
func (opType BinOpType) shouldDropMetric() bool {
|
||||
switch opType {
|
||||
case ADD, SUB, MUL, DIV, MOD:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// AggrType is an enum for aggregation types.
|
||||
type AggrType int
|
||||
|
||||
|
@ -487,8 +498,8 @@ func (node *VectorAggregation) Eval(timestamp clientmodel.Timestamp) Vector {
|
|||
m := clientmodel.Metric{}
|
||||
if node.keepExtraLabels {
|
||||
m = sample.Metric
|
||||
delete(m, clientmodel.MetricNameLabel)
|
||||
} else {
|
||||
m[clientmodel.MetricNameLabel] = sample.Metric[clientmodel.MetricNameLabel]
|
||||
for _, l := range node.groupBy {
|
||||
if v, ok := sample.Metric[l]; ok {
|
||||
m[l] = v
|
||||
|
@ -708,9 +719,6 @@ func evalVectorBinop(opType BinOpType,
|
|||
}
|
||||
|
||||
func labelsEqual(labels1, labels2 clientmodel.Metric) bool {
|
||||
if len(labels1) != len(labels2) {
|
||||
return false
|
||||
}
|
||||
for label, value := range labels1 {
|
||||
if labels2[label] != value && label != clientmodel.MetricNameLabel {
|
||||
return false
|
||||
|
@ -730,6 +738,9 @@ func (node *VectorArithExpr) Eval(timestamp clientmodel.Timestamp) Vector {
|
|||
value, keep := evalVectorBinop(node.opType, lhs, rhsSample.Value)
|
||||
if keep {
|
||||
rhsSample.Value = value
|
||||
if node.opType.shouldDropMetric() {
|
||||
delete(rhsSample.Metric, clientmodel.MetricNameLabel)
|
||||
}
|
||||
result = append(result, rhsSample)
|
||||
}
|
||||
}
|
||||
|
@ -741,6 +752,9 @@ func (node *VectorArithExpr) Eval(timestamp clientmodel.Timestamp) Vector {
|
|||
value, keep := evalVectorBinop(node.opType, lhsSample.Value, rhs)
|
||||
if keep {
|
||||
lhsSample.Value = value
|
||||
if node.opType.shouldDropMetric() {
|
||||
delete(lhsSample.Metric, clientmodel.MetricNameLabel)
|
||||
}
|
||||
result = append(result, lhsSample)
|
||||
}
|
||||
}
|
||||
|
@ -754,6 +768,9 @@ func (node *VectorArithExpr) Eval(timestamp clientmodel.Timestamp) Vector {
|
|||
value, keep := evalVectorBinop(node.opType, lhsSample.Value, rhsSample.Value)
|
||||
if keep {
|
||||
lhsSample.Value = value
|
||||
if node.opType.shouldDropMetric() {
|
||||
delete(lhsSample.Metric, clientmodel.MetricNameLabel)
|
||||
}
|
||||
result = append(result, lhsSample)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ func deltaImpl(timestamp clientmodel.Timestamp, args []Node) interface{} {
|
|||
Value: resultValue,
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
delete(resultSample.Metric, clientmodel.MetricNameLabel)
|
||||
resultVector = append(resultVector, resultSample)
|
||||
}
|
||||
return resultVector
|
||||
|
@ -381,6 +382,7 @@ func aggrOverTime(timestamp clientmodel.Timestamp, args []Node, aggrFn func(metr
|
|||
continue
|
||||
}
|
||||
|
||||
delete(el.Metric, clientmodel.MetricNameLabel)
|
||||
resultVector = append(resultVector, &clientmodel.Sample{
|
||||
Metric: el.Metric,
|
||||
Value: aggrFn(el.Values),
|
||||
|
@ -446,6 +448,7 @@ func absImpl(timestamp clientmodel.Timestamp, args []Node) interface{} {
|
|||
n := args[0].(VectorNode)
|
||||
vector := n.Eval(timestamp)
|
||||
for _, el := range vector {
|
||||
delete(el.Metric, clientmodel.MetricNameLabel)
|
||||
el.Value = clientmodel.SampleValue(math.Abs(float64(el.Value)))
|
||||
}
|
||||
return vector
|
||||
|
|
|
@ -70,30 +70,30 @@ func TestExpressions(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
expr: `SUM(http_requests)`,
|
||||
output: []string{`http_requests => 3600 @[%v]`},
|
||||
output: []string{`{} => 3600 @[%v]`},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests{instance="0"}) BY(job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 400 @[%v]`,
|
||||
`http_requests{job="app-server"} => 1200 @[%v]`,
|
||||
`{job="api-server"} => 400 @[%v]`,
|
||||
`{job="app-server"} => 1200 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 4,
|
||||
}, {
|
||||
expr: `SUM(http_requests{instance="0"}) BY(job) KEEPING_EXTRA`,
|
||||
output: []string{
|
||||
`http_requests{instance="0", job="api-server"} => 400 @[%v]`,
|
||||
`http_requests{instance="0", job="app-server"} => 1200 @[%v]`,
|
||||
`{instance="0", job="api-server"} => 400 @[%v]`,
|
||||
`{instance="0", job="app-server"} => 1200 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 4,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 1000 @[%v]`,
|
||||
`http_requests{job="app-server"} => 2600 @[%v]`,
|
||||
`{job="api-server"} => 1000 @[%v]`,
|
||||
`{job="app-server"} => 2600 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
|
@ -101,8 +101,8 @@ func TestExpressions(t *testing.T) {
|
|||
// Non-existent labels mentioned in BY-clauses shouldn't propagate to output.
|
||||
expr: `SUM(http_requests) BY (job, nonexistent)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 1000 @[%v]`,
|
||||
`http_requests{job="app-server"} => 2600 @[%v]`,
|
||||
`{job="api-server"} => 1000 @[%v]`,
|
||||
`{job="app-server"} => 2600 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
|
@ -112,141 +112,141 @@ func TestExpressions(t *testing.T) {
|
|||
SUM(http_requests) BY /* comments shouldn't
|
||||
have any effect */ (job) // another comment`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 1000 @[%v]`,
|
||||
`http_requests{job="app-server"} => 2600 @[%v]`,
|
||||
`{job="api-server"} => 1000 @[%v]`,
|
||||
`{job="app-server"} => 2600 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `COUNT(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 4 @[%v]`,
|
||||
`http_requests{job="app-server"} => 4 @[%v]`,
|
||||
`{job="api-server"} => 4 @[%v]`,
|
||||
`{job="app-server"} => 4 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job, group)`,
|
||||
output: []string{
|
||||
`http_requests{group="canary", job="api-server"} => 700 @[%v]`,
|
||||
`http_requests{group="canary", job="app-server"} => 1500 @[%v]`,
|
||||
`http_requests{group="production", job="api-server"} => 300 @[%v]`,
|
||||
`http_requests{group="production", job="app-server"} => 1100 @[%v]`,
|
||||
`{group="canary", job="api-server"} => 700 @[%v]`,
|
||||
`{group="canary", job="app-server"} => 1500 @[%v]`,
|
||||
`{group="production", job="api-server"} => 300 @[%v]`,
|
||||
`{group="production", job="app-server"} => 1100 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `AVG(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 250 @[%v]`,
|
||||
`http_requests{job="app-server"} => 650 @[%v]`,
|
||||
`{job="api-server"} => 250 @[%v]`,
|
||||
`{job="app-server"} => 650 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `MIN(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 100 @[%v]`,
|
||||
`http_requests{job="app-server"} => 500 @[%v]`,
|
||||
`{job="api-server"} => 100 @[%v]`,
|
||||
`{job="app-server"} => 500 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `MAX(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 400 @[%v]`,
|
||||
`http_requests{job="app-server"} => 800 @[%v]`,
|
||||
`{job="api-server"} => 400 @[%v]`,
|
||||
`{job="app-server"} => 800 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job) - COUNT(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 996 @[%v]`,
|
||||
`http_requests{job="app-server"} => 2596 @[%v]`,
|
||||
`{job="api-server"} => 996 @[%v]`,
|
||||
`{job="app-server"} => 2596 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `2 - SUM(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => -998 @[%v]`,
|
||||
`http_requests{job="app-server"} => -2598 @[%v]`,
|
||||
`{job="api-server"} => -998 @[%v]`,
|
||||
`{job="app-server"} => -2598 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `1000 / SUM(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 1 @[%v]`,
|
||||
`http_requests{job="app-server"} => 0.38461538461538464 @[%v]`,
|
||||
`{job="api-server"} => 1 @[%v]`,
|
||||
`{job="app-server"} => 0.38461538461538464 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job) - 2`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 998 @[%v]`,
|
||||
`http_requests{job="app-server"} => 2598 @[%v]`,
|
||||
`{job="api-server"} => 998 @[%v]`,
|
||||
`{job="app-server"} => 2598 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job) % 3`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 1 @[%v]`,
|
||||
`http_requests{job="app-server"} => 2 @[%v]`,
|
||||
`{job="api-server"} => 1 @[%v]`,
|
||||
`{job="app-server"} => 2 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job) / 0`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => +Inf @[%v]`,
|
||||
`http_requests{job="app-server"} => +Inf @[%v]`,
|
||||
`{job="api-server"} => +Inf @[%v]`,
|
||||
`{job="app-server"} => +Inf @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job) > 1000`,
|
||||
output: []string{
|
||||
`http_requests{job="app-server"} => 2600 @[%v]`,
|
||||
`{job="app-server"} => 2600 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `1000 < SUM(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="app-server"} => 1000 @[%v]`,
|
||||
`{job="app-server"} => 1000 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job) <= 1000`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 1000 @[%v]`,
|
||||
`{job="api-server"} => 1000 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job) != 1000`,
|
||||
output: []string{
|
||||
`http_requests{job="app-server"} => 2600 @[%v]`,
|
||||
`{job="app-server"} => 2600 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job) == 1000`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 1000 @[%v]`,
|
||||
`{job="api-server"} => 1000 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
expr: `SUM(http_requests) BY (job) + SUM(http_requests) BY (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="api-server"} => 2000 @[%v]`,
|
||||
`http_requests{job="app-server"} => 5200 @[%v]`,
|
||||
`{job="api-server"} => 2000 @[%v]`,
|
||||
`{job="app-server"} => 5200 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
|
@ -261,22 +261,22 @@ func TestExpressions(t *testing.T) {
|
|||
}, {
|
||||
expr: `http_requests{job="api-server", group="canary"} + delta(http_requests{job="api-server"}[5m], 1)`,
|
||||
output: []string{
|
||||
`http_requests{group="canary", instance="0", job="api-server"} => 330 @[%v]`,
|
||||
`http_requests{group="canary", instance="1", job="api-server"} => 440 @[%v]`,
|
||||
`{group="canary", instance="0", job="api-server"} => 330 @[%v]`,
|
||||
`{group="canary", instance="1", job="api-server"} => 440 @[%v]`,
|
||||
},
|
||||
fullRanges: 4,
|
||||
intervalRanges: 0,
|
||||
}, {
|
||||
expr: `delta(http_requests[25m], 1)`,
|
||||
output: []string{
|
||||
`http_requests{group="canary", instance="0", job="api-server"} => 150 @[%v]`,
|
||||
`http_requests{group="canary", instance="0", job="app-server"} => 350 @[%v]`,
|
||||
`http_requests{group="canary", instance="1", job="api-server"} => 200 @[%v]`,
|
||||
`http_requests{group="canary", instance="1", job="app-server"} => 400 @[%v]`,
|
||||
`http_requests{group="production", instance="0", job="api-server"} => 50 @[%v]`,
|
||||
`http_requests{group="production", instance="0", job="app-server"} => 250 @[%v]`,
|
||||
`http_requests{group="production", instance="1", job="api-server"} => 100 @[%v]`,
|
||||
`http_requests{group="production", instance="1", job="app-server"} => 300 @[%v]`,
|
||||
`{group="canary", instance="0", job="api-server"} => 150 @[%v]`,
|
||||
`{group="canary", instance="0", job="app-server"} => 350 @[%v]`,
|
||||
`{group="canary", instance="1", job="api-server"} => 200 @[%v]`,
|
||||
`{group="canary", instance="1", job="app-server"} => 400 @[%v]`,
|
||||
`{group="production", instance="0", job="api-server"} => 50 @[%v]`,
|
||||
`{group="production", instance="0", job="app-server"} => 250 @[%v]`,
|
||||
`{group="production", instance="1", job="api-server"} => 100 @[%v]`,
|
||||
`{group="production", instance="1", job="app-server"} => 300 @[%v]`,
|
||||
},
|
||||
fullRanges: 8,
|
||||
intervalRanges: 0,
|
||||
|
@ -360,45 +360,45 @@ func TestExpressions(t *testing.T) {
|
|||
// Lower-cased aggregation operators should work too.
|
||||
expr: `sum(http_requests) by (job) + min(http_requests) by (job) + max(http_requests) by (job) + avg(http_requests) by (job)`,
|
||||
output: []string{
|
||||
`http_requests{job="app-server"} => 4550 @[%v]`,
|
||||
`http_requests{job="api-server"} => 1750 @[%v]`,
|
||||
`{job="app-server"} => 4550 @[%v]`,
|
||||
`{job="api-server"} => 1750 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 8,
|
||||
}, {
|
||||
// Deltas should be adjusted for target interval vs. samples under target interval.
|
||||
expr: `delta(http_requests{group="canary", instance="1", job="app-server"}[18m], 1)`,
|
||||
output: []string{`http_requests{group="canary", instance="1", job="app-server"} => 288 @[%v]`},
|
||||
output: []string{`{group="canary", instance="1", job="app-server"} => 288 @[%v]`},
|
||||
fullRanges: 1,
|
||||
intervalRanges: 0,
|
||||
}, {
|
||||
// Rates should transform per-interval deltas to per-second rates.
|
||||
expr: `rate(http_requests{group="canary", instance="1", job="app-server"}[10m])`,
|
||||
output: []string{`http_requests{group="canary", instance="1", job="app-server"} => 0.26666666666666666 @[%v]`},
|
||||
output: []string{`{group="canary", instance="1", job="app-server"} => 0.26666666666666666 @[%v]`},
|
||||
fullRanges: 1,
|
||||
intervalRanges: 0,
|
||||
}, {
|
||||
// Counter resets in middle of range are ignored by delta() if counter == 1.
|
||||
expr: `delta(testcounter_reset_middle[50m], 1)`,
|
||||
output: []string{`testcounter_reset_middle => 90 @[%v]`},
|
||||
output: []string{`{} => 90 @[%v]`},
|
||||
fullRanges: 1,
|
||||
intervalRanges: 0,
|
||||
}, {
|
||||
// Counter resets in middle of range are not ignored by delta() if counter == 0.
|
||||
expr: `delta(testcounter_reset_middle[50m], 0)`,
|
||||
output: []string{`testcounter_reset_middle => 50 @[%v]`},
|
||||
output: []string{`{} => 50 @[%v]`},
|
||||
fullRanges: 1,
|
||||
intervalRanges: 0,
|
||||
}, {
|
||||
// Counter resets at end of range are ignored by delta() if counter == 1.
|
||||
expr: `delta(testcounter_reset_end[5m], 1)`,
|
||||
output: []string{`testcounter_reset_end => 0 @[%v]`},
|
||||
output: []string{`{} => 0 @[%v]`},
|
||||
fullRanges: 1,
|
||||
intervalRanges: 0,
|
||||
}, {
|
||||
// Counter resets at end of range are not ignored by delta() if counter == 0.
|
||||
expr: `delta(testcounter_reset_end[5m], 0)`,
|
||||
output: []string{`testcounter_reset_end => -90 @[%v]`},
|
||||
output: []string{`{} => -90 @[%v]`},
|
||||
fullRanges: 1,
|
||||
intervalRanges: 0,
|
||||
}, {
|
||||
|
@ -470,8 +470,8 @@ func TestExpressions(t *testing.T) {
|
|||
{
|
||||
expr: `abs(-1 * http_requests{group="production",job="api-server"})`,
|
||||
output: []string{
|
||||
`http_requests{group="production", instance="0", job="api-server"} => 100 @[%v]`,
|
||||
`http_requests{group="production", instance="1", job="api-server"} => 200 @[%v]`,
|
||||
`{group="production", instance="0", job="api-server"} => 100 @[%v]`,
|
||||
`{group="production", instance="1", job="api-server"} => 200 @[%v]`,
|
||||
},
|
||||
fullRanges: 0,
|
||||
intervalRanges: 2,
|
||||
|
@ -479,8 +479,8 @@ func TestExpressions(t *testing.T) {
|
|||
{
|
||||
expr: `avg_over_time(http_requests{group="production",job="api-server"}[1h])`,
|
||||
output: []string{
|
||||
`http_requests{group="production", instance="0", job="api-server"} => 50 @[%v]`,
|
||||
`http_requests{group="production", instance="1", job="api-server"} => 100 @[%v]`,
|
||||
`{group="production", instance="0", job="api-server"} => 50 @[%v]`,
|
||||
`{group="production", instance="1", job="api-server"} => 100 @[%v]`,
|
||||
},
|
||||
fullRanges: 2,
|
||||
intervalRanges: 0,
|
||||
|
@ -488,8 +488,8 @@ func TestExpressions(t *testing.T) {
|
|||
{
|
||||
expr: `count_over_time(http_requests{group="production",job="api-server"}[1h])`,
|
||||
output: []string{
|
||||
`http_requests{group="production", instance="0", job="api-server"} => 11 @[%v]`,
|
||||
`http_requests{group="production", instance="1", job="api-server"} => 11 @[%v]`,
|
||||
`{group="production", instance="0", job="api-server"} => 11 @[%v]`,
|
||||
`{group="production", instance="1", job="api-server"} => 11 @[%v]`,
|
||||
},
|
||||
fullRanges: 2,
|
||||
intervalRanges: 0,
|
||||
|
@ -497,8 +497,8 @@ func TestExpressions(t *testing.T) {
|
|||
{
|
||||
expr: `max_over_time(http_requests{group="production",job="api-server"}[1h])`,
|
||||
output: []string{
|
||||
`http_requests{group="production", instance="0", job="api-server"} => 100 @[%v]`,
|
||||
`http_requests{group="production", instance="1", job="api-server"} => 200 @[%v]`,
|
||||
`{group="production", instance="0", job="api-server"} => 100 @[%v]`,
|
||||
`{group="production", instance="1", job="api-server"} => 200 @[%v]`,
|
||||
},
|
||||
fullRanges: 2,
|
||||
intervalRanges: 0,
|
||||
|
@ -506,8 +506,8 @@ func TestExpressions(t *testing.T) {
|
|||
{
|
||||
expr: `min_over_time(http_requests{group="production",job="api-server"}[1h])`,
|
||||
output: []string{
|
||||
`http_requests{group="production", instance="0", job="api-server"} => 0 @[%v]`,
|
||||
`http_requests{group="production", instance="1", job="api-server"} => 0 @[%v]`,
|
||||
`{group="production", instance="0", job="api-server"} => 0 @[%v]`,
|
||||
`{group="production", instance="1", job="api-server"} => 0 @[%v]`,
|
||||
},
|
||||
fullRanges: 2,
|
||||
intervalRanges: 0,
|
||||
|
@ -515,8 +515,8 @@ func TestExpressions(t *testing.T) {
|
|||
{
|
||||
expr: `sum_over_time(http_requests{group="production",job="api-server"}[1h])`,
|
||||
output: []string{
|
||||
`http_requests{group="production", instance="0", job="api-server"} => 550 @[%v]`,
|
||||
`http_requests{group="production", instance="1", job="api-server"} => 1100 @[%v]`,
|
||||
`{group="production", instance="0", job="api-server"} => 550 @[%v]`,
|
||||
`{group="production", instance="1", job="api-server"} => 1100 @[%v]`,
|
||||
},
|
||||
fullRanges: 2,
|
||||
intervalRanges: 0,
|
||||
|
|
|
@ -350,7 +350,7 @@ Prometheus.Graph.prototype.renderLabels = function(labels) {
|
|||
}
|
||||
|
||||
Prometheus.Graph.prototype.metricToTsName = function(labels) {
|
||||
var tsName = labels["__name__"] + "{";
|
||||
var tsName = (labels["__name__"] || '') + "{";
|
||||
var labelStrings = [];
|
||||
for (label in labels) {
|
||||
if (label != "__name__") {
|
||||
|
@ -378,7 +378,7 @@ Prometheus.Graph.prototype.transformData = function(json) {
|
|||
}
|
||||
var data = json.Value.map(function(ts) {
|
||||
return {
|
||||
name: self.metricToTsName(ts.Metric),
|
||||
name: escapeHTML(self.metricToTsName(ts.Metric)),
|
||||
labels: ts.Metric,
|
||||
data: ts.Values.map(function(value) {
|
||||
return {
|
||||
|
@ -438,7 +438,7 @@ Prometheus.Graph.prototype.updateGraph = function(reloadGraph) {
|
|||
graph: self.rickshawGraph,
|
||||
formatter: function(series, x, y) {
|
||||
var swatch = '<span class="detail_swatch" style="background-color: ' + series.color + '"></span>';
|
||||
var content = swatch + series.labels["__name__"] + ": <strong>" + y + '</strong><br>';
|
||||
var content = swatch + (series.labels["__name__"] || 'value') + ": <strong>" + y + '</strong><br>';
|
||||
return content + self.renderLabels(series.labels);
|
||||
},
|
||||
onRender: function() {
|
||||
|
@ -518,7 +518,7 @@ Prometheus.Graph.prototype.handleConsoleResponse = function(data, textStatus) {
|
|||
for (var i = 0; i < data.Value.length; i++) {
|
||||
var v = data.Value[i];
|
||||
var tsName = self.metricToTsName(v.Metric);
|
||||
tBody.append("<tr><td>" + tsName + "</td><td>" + v.Value + "</td></tr>")
|
||||
tBody.append("<tr><td>" + escapeHTML(tsName) + "</td><td>" + v.Value + "</td></tr>")
|
||||
}
|
||||
break;
|
||||
case "matrix":
|
||||
|
@ -529,7 +529,7 @@ Prometheus.Graph.prototype.handleConsoleResponse = function(data, textStatus) {
|
|||
for (var j = 0; j < v.Values.length; j++) {
|
||||
valueText += v.Values[j].Value + " @" + v.Values[j].Timestamp + "<br/>";
|
||||
}
|
||||
tBody.append("<tr><td>" + tsName + "</td><td>" + valueText + "</td></tr>")
|
||||
tBody.append("<tr><td>" + escapeHTML(tsName) + "</td><td>" + valueText + "</td></tr>")
|
||||
}
|
||||
break;
|
||||
case "scalar":
|
||||
|
@ -575,6 +575,21 @@ function addGraph(options) {
|
|||
});
|
||||
}
|
||||
|
||||
function escapeHTML(string) {
|
||||
var entityMap = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
"/": '/'
|
||||
};
|
||||
|
||||
return String(string).replace(/[&<>"'\/]/g, function (s) {
|
||||
return entityMap[s];
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
$.ajaxSetup({
|
||||
cache: false
|
||||
|
|
Loading…
Reference in a new issue