mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-10 07:34:04 -08:00
Merge pull request #111 from prometheus/julius-depointerize
Depointerize Matrix/Vector types as well as time.Time arguments.
This commit is contained in:
commit
8622df50ae
2
main.go
2
main.go
|
@ -95,7 +95,7 @@ func main() {
|
|||
|
||||
case ruleResult := <-ruleResults:
|
||||
for _, sample := range ruleResult.Samples {
|
||||
ts.AppendSample(*sample)
|
||||
ts.AppendSample(sample)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ import (
|
|||
// ----------------------------------------------------------------------------
|
||||
// Raw data value types.
|
||||
|
||||
type Vector []*model.Sample
|
||||
type Matrix []*model.SampleSet
|
||||
type Vector model.Samples
|
||||
type Matrix []model.SampleSet
|
||||
|
||||
type groupedAggregation struct {
|
||||
labels model.Metric
|
||||
|
@ -97,23 +97,23 @@ type Node interface {
|
|||
// interface represents the type returned to the parent node.
|
||||
type ScalarNode interface {
|
||||
Node
|
||||
Eval(timestamp *time.Time, view *viewAdapter) model.SampleValue
|
||||
Eval(timestamp time.Time, view *viewAdapter) model.SampleValue
|
||||
}
|
||||
|
||||
type VectorNode interface {
|
||||
Node
|
||||
Eval(timestamp *time.Time, view *viewAdapter) Vector
|
||||
Eval(timestamp time.Time, view *viewAdapter) Vector
|
||||
}
|
||||
|
||||
type MatrixNode interface {
|
||||
Node
|
||||
Eval(timestamp *time.Time, view *viewAdapter) Matrix
|
||||
EvalBoundaries(timestamp *time.Time, view *viewAdapter) Matrix
|
||||
Eval(timestamp time.Time, view *viewAdapter) Matrix
|
||||
EvalBoundaries(timestamp time.Time, view *viewAdapter) Matrix
|
||||
}
|
||||
|
||||
type StringNode interface {
|
||||
Node
|
||||
Eval(timestamp *time.Time, view *viewAdapter) string
|
||||
Eval(timestamp time.Time, view *viewAdapter) string
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -227,17 +227,17 @@ func (node MatrixLiteral) Children() []Node { return []Node{} }
|
|||
func (node StringLiteral) Children() []Node { return []Node{} }
|
||||
func (node StringFunctionCall) Children() []Node { return node.args }
|
||||
|
||||
func (node *ScalarLiteral) Eval(timestamp *time.Time, view *viewAdapter) model.SampleValue {
|
||||
func (node *ScalarLiteral) Eval(timestamp time.Time, view *viewAdapter) model.SampleValue {
|
||||
return node.value
|
||||
}
|
||||
|
||||
func (node *ScalarArithExpr) Eval(timestamp *time.Time, view *viewAdapter) model.SampleValue {
|
||||
func (node *ScalarArithExpr) Eval(timestamp time.Time, view *viewAdapter) model.SampleValue {
|
||||
lhs := node.lhs.Eval(timestamp, view)
|
||||
rhs := node.rhs.Eval(timestamp, view)
|
||||
return evalScalarBinop(node.opType, lhs, rhs)
|
||||
}
|
||||
|
||||
func (node *ScalarFunctionCall) Eval(timestamp *time.Time, view *viewAdapter) model.SampleValue {
|
||||
func (node *ScalarFunctionCall) Eval(timestamp time.Time, view *viewAdapter) model.SampleValue {
|
||||
return node.function.callFn(timestamp, view, node.args).(model.SampleValue)
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ func EvalVectorInstant(node VectorNode, timestamp time.Time) (vector Vector) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
return node.Eval(×tamp, viewAdapter)
|
||||
return node.Eval(timestamp, viewAdapter)
|
||||
}
|
||||
|
||||
func EvalVectorRange(node VectorNode, start time.Time, end time.Time, interval time.Duration) (matrix Matrix, err error) {
|
||||
|
@ -278,7 +278,7 @@ func EvalVectorRange(node VectorNode, start time.Time, end time.Time, interval t
|
|||
// TODO implement watchdog timer for long-running queries.
|
||||
sampleSets := map[string]*model.SampleSet{}
|
||||
for t := start; t.Before(end); t = t.Add(interval) {
|
||||
vector := node.Eval(&t, viewAdapter)
|
||||
vector := node.Eval(t, viewAdapter)
|
||||
for _, sample := range vector {
|
||||
samplePair := model.SamplePair{
|
||||
Value: sample.Value,
|
||||
|
@ -297,7 +297,7 @@ func EvalVectorRange(node VectorNode, start time.Time, end time.Time, interval t
|
|||
}
|
||||
|
||||
for _, sampleSet := range sampleSets {
|
||||
matrix = append(matrix, sampleSet)
|
||||
matrix = append(matrix, *sampleSet)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -312,23 +312,23 @@ func labelIntersection(metric1, metric2 model.Metric) model.Metric {
|
|||
return intersection
|
||||
}
|
||||
|
||||
func (node *VectorAggregation) groupedAggregationsToVector(aggregations map[string]*groupedAggregation, timestamp *time.Time) Vector {
|
||||
func (node *VectorAggregation) groupedAggregationsToVector(aggregations map[string]*groupedAggregation, timestamp time.Time) Vector {
|
||||
vector := Vector{}
|
||||
for _, aggregation := range aggregations {
|
||||
if node.aggrType == AVG {
|
||||
aggregation.value = aggregation.value / model.SampleValue(aggregation.groupCount)
|
||||
}
|
||||
sample := &model.Sample{
|
||||
sample := model.Sample{
|
||||
Metric: aggregation.labels,
|
||||
Value: aggregation.value,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
vector = append(vector, sample)
|
||||
}
|
||||
return vector
|
||||
}
|
||||
|
||||
func (node *VectorAggregation) Eval(timestamp *time.Time, view *viewAdapter) Vector {
|
||||
func (node *VectorAggregation) Eval(timestamp time.Time, view *viewAdapter) Vector {
|
||||
vector := node.vector.Eval(timestamp, view)
|
||||
result := map[string]*groupedAggregation{}
|
||||
for _, sample := range vector {
|
||||
|
@ -361,7 +361,7 @@ func (node *VectorAggregation) Eval(timestamp *time.Time, view *viewAdapter) Vec
|
|||
return node.groupedAggregationsToVector(result, timestamp)
|
||||
}
|
||||
|
||||
func (node *VectorLiteral) Eval(timestamp *time.Time, view *viewAdapter) Vector {
|
||||
func (node *VectorLiteral) Eval(timestamp time.Time, view *viewAdapter) Vector {
|
||||
values, err := view.GetValueAtTime(node.fingerprints, timestamp)
|
||||
if err != nil {
|
||||
log.Printf("Unable to get vector values")
|
||||
|
@ -370,7 +370,7 @@ func (node *VectorLiteral) Eval(timestamp *time.Time, view *viewAdapter) Vector
|
|||
return values
|
||||
}
|
||||
|
||||
func (node *VectorFunctionCall) Eval(timestamp *time.Time, view *viewAdapter) Vector {
|
||||
func (node *VectorFunctionCall) Eval(timestamp time.Time, view *viewAdapter) Vector {
|
||||
return node.function.callFn(timestamp, view, node.args).(Vector)
|
||||
}
|
||||
|
||||
|
@ -514,7 +514,7 @@ func labelsEqual(labels1, labels2 model.Metric) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (node *VectorArithExpr) Eval(timestamp *time.Time, view *viewAdapter) Vector {
|
||||
func (node *VectorArithExpr) Eval(timestamp time.Time, view *viewAdapter) Vector {
|
||||
lhs := node.lhs.Eval(timestamp, view)
|
||||
result := Vector{}
|
||||
if node.rhs.Type() == SCALAR {
|
||||
|
@ -545,10 +545,10 @@ func (node *VectorArithExpr) Eval(timestamp *time.Time, view *viewAdapter) Vecto
|
|||
panic("Invalid vector arithmetic expression operands")
|
||||
}
|
||||
|
||||
func (node *MatrixLiteral) Eval(timestamp *time.Time, view *viewAdapter) Matrix {
|
||||
func (node *MatrixLiteral) Eval(timestamp time.Time, view *viewAdapter) Matrix {
|
||||
interval := &model.Interval{
|
||||
OldestInclusive: timestamp.Add(-node.interval),
|
||||
NewestInclusive: *timestamp,
|
||||
NewestInclusive: timestamp,
|
||||
}
|
||||
values, err := view.GetRangeValues(node.fingerprints, interval)
|
||||
if err != nil {
|
||||
|
@ -558,10 +558,10 @@ func (node *MatrixLiteral) Eval(timestamp *time.Time, view *viewAdapter) Matrix
|
|||
return values
|
||||
}
|
||||
|
||||
func (node *MatrixLiteral) EvalBoundaries(timestamp *time.Time, view *viewAdapter) Matrix {
|
||||
func (node *MatrixLiteral) EvalBoundaries(timestamp time.Time, view *viewAdapter) Matrix {
|
||||
interval := &model.Interval{
|
||||
OldestInclusive: timestamp.Add(-node.interval),
|
||||
NewestInclusive: *timestamp,
|
||||
NewestInclusive: timestamp,
|
||||
}
|
||||
values, err := view.GetBoundaryValues(node.fingerprints, interval)
|
||||
if err != nil {
|
||||
|
@ -583,11 +583,11 @@ func (matrix Matrix) Swap(i, j int) {
|
|||
matrix[i], matrix[j] = matrix[j], matrix[i]
|
||||
}
|
||||
|
||||
func (node *StringLiteral) Eval(timestamp *time.Time, view *viewAdapter) string {
|
||||
func (node *StringLiteral) Eval(timestamp time.Time, view *viewAdapter) string {
|
||||
return node.str
|
||||
}
|
||||
|
||||
func (node *StringFunctionCall) Eval(timestamp *time.Time, view *viewAdapter) string {
|
||||
func (node *StringFunctionCall) Eval(timestamp time.Time, view *viewAdapter) string {
|
||||
return node.function.callFn(timestamp, view, node.args).(string)
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ type Function struct {
|
|||
name string
|
||||
argTypes []ExprType
|
||||
returnType ExprType
|
||||
callFn func(timestamp *time.Time, view *viewAdapter, args []Node) interface{}
|
||||
callFn func(timestamp time.Time, view *viewAdapter, args []Node) interface{}
|
||||
}
|
||||
|
||||
func (function *Function) CheckArgTypes(args []Node) error {
|
||||
|
@ -63,17 +63,17 @@ func (function *Function) CheckArgTypes(args []Node) error {
|
|||
}
|
||||
|
||||
// === time() ===
|
||||
func timeImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
func timeImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
return model.SampleValue(time.Now().Unix())
|
||||
}
|
||||
|
||||
// === count(vector VectorNode) ===
|
||||
func countImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
func countImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
return model.SampleValue(len(args[0].(VectorNode).Eval(timestamp, view)))
|
||||
}
|
||||
|
||||
// === delta(matrix MatrixNode, isCounter ScalarNode) ===
|
||||
func deltaImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
func deltaImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
matrixNode := args[0].(MatrixNode)
|
||||
isCounter := int(args[1].(ScalarNode).Eval(timestamp, view))
|
||||
resultVector := Vector{}
|
||||
|
@ -98,10 +98,10 @@ func deltaImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{}
|
|||
lastValue = currentValue
|
||||
}
|
||||
resultValue := lastValue - samples.Values[0].Value + counterCorrection
|
||||
resultSample := &model.Sample{
|
||||
resultSample := model.Sample{
|
||||
Metric: samples.Metric,
|
||||
Value: resultValue,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
resultVector = append(resultVector, resultSample)
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ func deltaImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{}
|
|||
}
|
||||
|
||||
// === rate(node *MatrixNode) ===
|
||||
func rateImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
func rateImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
args = append(args, &ScalarLiteral{value: 1})
|
||||
vector := deltaImpl(timestamp, view, args).(Vector)
|
||||
|
||||
|
@ -124,36 +124,36 @@ func rateImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{}
|
|||
}
|
||||
|
||||
// === sampleVectorImpl() ===
|
||||
func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
func sampleVectorImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
|
||||
return Vector{
|
||||
&model.Sample{
|
||||
model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "http_requests",
|
||||
"job": "api-server",
|
||||
"instance": "0",
|
||||
},
|
||||
Value: 10,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
},
|
||||
&model.Sample{
|
||||
model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "http_requests",
|
||||
"job": "api-server",
|
||||
"instance": "1",
|
||||
},
|
||||
Value: 20,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
},
|
||||
&model.Sample{
|
||||
model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "http_requests",
|
||||
"job": "api-server",
|
||||
"instance": "2",
|
||||
},
|
||||
Value: 30,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
},
|
||||
&model.Sample{
|
||||
model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "http_requests",
|
||||
"job": "api-server",
|
||||
|
@ -161,9 +161,9 @@ func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) inte
|
|||
"group": "canary",
|
||||
},
|
||||
Value: 40,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
},
|
||||
&model.Sample{
|
||||
model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "http_requests",
|
||||
"job": "api-server",
|
||||
|
@ -171,9 +171,9 @@ func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) inte
|
|||
"group": "canary",
|
||||
},
|
||||
Value: 40,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
},
|
||||
&model.Sample{
|
||||
model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "http_requests",
|
||||
"job": "api-server",
|
||||
|
@ -181,9 +181,9 @@ func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) inte
|
|||
"group": "mytest",
|
||||
},
|
||||
Value: 40,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
},
|
||||
&model.Sample{
|
||||
model.Sample{
|
||||
Metric: model.Metric{
|
||||
model.MetricNameLabel: "http_requests",
|
||||
"job": "api-server",
|
||||
|
@ -191,7 +191,7 @@ func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) inte
|
|||
"group": "mytest",
|
||||
},
|
||||
Value: 40,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,11 +50,11 @@ func interpolateSamples(first, second *model.SamplePair, timestamp time.Time) *m
|
|||
// surrounding a given target time. If samples are found both before and after
|
||||
// the target time, the sample value is interpolated between these. Otherwise,
|
||||
// the single closest sample is returned verbatim.
|
||||
func (v *viewAdapter) chooseClosestSample(samples []model.SamplePair, timestamp *time.Time) (sample *model.SamplePair) {
|
||||
func (v *viewAdapter) chooseClosestSample(samples []model.SamplePair, timestamp time.Time) (sample *model.SamplePair) {
|
||||
var closestBefore *model.SamplePair
|
||||
var closestAfter *model.SamplePair
|
||||
for _, candidate := range samples {
|
||||
delta := candidate.Timestamp.Sub(*timestamp)
|
||||
delta := candidate.Timestamp.Sub(timestamp)
|
||||
// Samples before target time.
|
||||
if delta < 0 {
|
||||
// Ignore samples outside of staleness policy window.
|
||||
|
@ -86,7 +86,7 @@ func (v *viewAdapter) chooseClosestSample(samples []model.SamplePair, timestamp
|
|||
|
||||
switch {
|
||||
case closestBefore != nil && closestAfter != nil:
|
||||
sample = interpolateSamples(closestBefore, closestAfter, *timestamp)
|
||||
sample = interpolateSamples(closestBefore, closestAfter, timestamp)
|
||||
case closestBefore != nil:
|
||||
sample = closestBefore
|
||||
default:
|
||||
|
@ -96,26 +96,26 @@ func (v *viewAdapter) chooseClosestSample(samples []model.SamplePair, timestamp
|
|||
return
|
||||
}
|
||||
|
||||
func (v *viewAdapter) GetValueAtTime(fingerprints model.Fingerprints, timestamp *time.Time) (samples []*model.Sample, err error) {
|
||||
func (v *viewAdapter) GetValueAtTime(fingerprints model.Fingerprints, timestamp time.Time) (samples Vector, err error) {
|
||||
for _, fingerprint := range fingerprints {
|
||||
sampleCandidates := v.view.GetValueAtTime(fingerprint, *timestamp)
|
||||
sampleCandidates := v.view.GetValueAtTime(fingerprint, timestamp)
|
||||
samplePair := v.chooseClosestSample(sampleCandidates, timestamp)
|
||||
m, err := queryStorage.GetMetricForFingerprint(fingerprint)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if samplePair != nil {
|
||||
samples = append(samples, &model.Sample{
|
||||
samples = append(samples, model.Sample{
|
||||
Metric: *m,
|
||||
Value: samplePair.Value,
|
||||
Timestamp: *timestamp,
|
||||
Timestamp: timestamp,
|
||||
})
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (v *viewAdapter) GetBoundaryValues(fingerprints model.Fingerprints, interval *model.Interval) (sampleSets []*model.SampleSet, err error) {
|
||||
func (v *viewAdapter) GetBoundaryValues(fingerprints model.Fingerprints, interval *model.Interval) (sampleSets []model.SampleSet, err error) {
|
||||
for _, fingerprint := range fingerprints {
|
||||
// TODO: change to GetBoundaryValues() once it has the right return type.
|
||||
samplePairs := v.view.GetRangeValues(fingerprint, *interval)
|
||||
|
@ -129,7 +129,7 @@ func (v *viewAdapter) GetBoundaryValues(fingerprints model.Fingerprints, interva
|
|||
continue
|
||||
}
|
||||
|
||||
sampleSet := &model.SampleSet{
|
||||
sampleSet := model.SampleSet{
|
||||
Metric: *m,
|
||||
Values: samplePairs,
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ func (v *viewAdapter) GetBoundaryValues(fingerprints model.Fingerprints, interva
|
|||
return sampleSets, nil
|
||||
}
|
||||
|
||||
func (v *viewAdapter) GetRangeValues(fingerprints model.Fingerprints, interval *model.Interval) (sampleSets []*model.SampleSet, err error) {
|
||||
func (v *viewAdapter) GetRangeValues(fingerprints model.Fingerprints, interval *model.Interval) (sampleSets []model.SampleSet, err error) {
|
||||
for _, fingerprint := range fingerprints {
|
||||
samplePairs := v.view.GetRangeValues(fingerprint, *interval)
|
||||
if samplePairs == nil {
|
||||
|
@ -151,7 +151,7 @@ func (v *viewAdapter) GetRangeValues(fingerprints model.Fingerprints, interval *
|
|||
continue
|
||||
}
|
||||
|
||||
sampleSet := &model.SampleSet{
|
||||
sampleSet := model.SampleSet{
|
||||
Metric: *m,
|
||||
Values: samplePairs,
|
||||
}
|
||||
|
|
|
@ -152,8 +152,8 @@ func TypedValueToJSON(data interface{}, typeStr string) string {
|
|||
return string(dataJSON)
|
||||
}
|
||||
|
||||
func EvalToString(node Node, timestamp *time.Time, format OutputFormat) string {
|
||||
viewAdapter, err := viewAdapterForInstantQuery(node, *timestamp)
|
||||
func EvalToString(node Node, timestamp time.Time, format OutputFormat) string {
|
||||
viewAdapter, err := viewAdapterForInstantQuery(node, timestamp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ func TestExpressions(t *testing.T) {
|
|||
t.Errorf("Test should fail, but didn't")
|
||||
}
|
||||
failed := false
|
||||
resultStr := ast.EvalToString(testExpr, &testEvalTime, ast.TEXT)
|
||||
resultStr := ast.EvalToString(testExpr, testEvalTime, ast.TEXT)
|
||||
resultLines := strings.Split(resultStr, "\n")
|
||||
|
||||
if len(exprTest.output) != len(resultLines) {
|
||||
|
|
|
@ -42,7 +42,7 @@ func getTestVectorFromTestMatrix(matrix ast.Matrix) ast.Vector {
|
|||
vector := ast.Vector{}
|
||||
for _, sampleSet := range matrix {
|
||||
lastSample := sampleSet.Values[len(sampleSet.Values)-1]
|
||||
vector = append(vector, &model.Sample{
|
||||
vector = append(vector, model.Sample{
|
||||
Metric: sampleSet.Metric,
|
||||
Value: lastSample.Value,
|
||||
Timestamp: lastSample.Timestamp,
|
||||
|
|
|
@ -44,7 +44,7 @@ func (serv MetricsService) Query(expr string, formatJson string) (result string)
|
|||
rb.SetContentType(gorest.Text_Plain)
|
||||
}
|
||||
|
||||
return ast.EvalToString(exprNode, ×tamp, format)
|
||||
return ast.EvalToString(exprNode, timestamp, format)
|
||||
}
|
||||
|
||||
func (serv MetricsService) QueryRange(expr string, end int64, duration int64, step int64) string {
|
||||
|
|
Loading…
Reference in a new issue