mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
Apply the new signature/fingerprinting functions from client_golang.
This requires the new version of client_golang (vendoring will follow in the next commit), which changes the fingerprinting for clientmodel.Metric.
This commit is contained in:
parent
ebac14eff3
commit
9e85ab0eef
|
@ -17,7 +17,6 @@ import (
|
|||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
|
@ -383,23 +382,6 @@ func (node *ScalarFunctionCall) Eval(timestamp clientmodel.Timestamp) clientmode
|
|||
return node.function.callFn(timestamp, node.args).(clientmodel.SampleValue)
|
||||
}
|
||||
|
||||
// hashForLabels returns a hash value taken from the label/value pairs of the
|
||||
// specified labels in the metric.
|
||||
func hashForLabels(metric clientmodel.Metric, labels clientmodel.LabelNames) uint64 {
|
||||
var result uint64
|
||||
s := fnv.New64a()
|
||||
|
||||
for _, label := range labels {
|
||||
s.Write([]byte(label))
|
||||
s.Write([]byte{clientmodel.SeparatorByte})
|
||||
s.Write([]byte(metric[label]))
|
||||
result ^= s.Sum64()
|
||||
s.Reset()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// EvalVectorInstant evaluates a VectorNode with an instant query.
|
||||
func EvalVectorInstant(node VectorNode, timestamp clientmodel.Timestamp, storage local.Storage, queryStats *stats.TimerGroup) (Vector, error) {
|
||||
totalEvalTimer := queryStats.GetTimer(stats.TotalEvalTime).Start()
|
||||
|
@ -503,7 +485,7 @@ func (node *VectorAggregation) Eval(timestamp clientmodel.Timestamp) Vector {
|
|||
vector := node.vector.Eval(timestamp)
|
||||
result := map[uint64]*groupedAggregation{}
|
||||
for _, sample := range vector {
|
||||
groupingKey := hashForLabels(sample.Metric.Metric, node.groupBy)
|
||||
groupingKey := clientmodel.SignatureForLabels(sample.Metric.Metric, node.groupBy)
|
||||
if groupedResult, ok := result[groupingKey]; ok {
|
||||
if node.keepExtraLabels {
|
||||
groupedResult.labels = labelIntersection(groupedResult.labels, sample.Metric)
|
||||
|
@ -879,7 +861,7 @@ func (node *VectorArithExpr) evalVectors(timestamp clientmodel.Timestamp, lhs, r
|
|||
metric := node.resultMetric(ls, rs)
|
||||
// Check if the same label set has been added for a many-to-one matching before.
|
||||
if node.matchCardinality == MatchManyToOne || node.matchCardinality == MatchOneToMany {
|
||||
insHash := hashForLabels(metric.Metric, node.includeLabels)
|
||||
insHash := clientmodel.SignatureForLabels(metric.Metric, node.includeLabels)
|
||||
if ihs, exists := added[hash]; exists {
|
||||
for _, ih := range ihs {
|
||||
if ih == insHash {
|
||||
|
@ -971,7 +953,7 @@ func (node *VectorArithExpr) hashForMetric(metric clientmodel.Metric) uint64 {
|
|||
}
|
||||
}
|
||||
}
|
||||
return hashForLabels(metric, labels)
|
||||
return clientmodel.SignatureForLabels(metric, labels)
|
||||
}
|
||||
|
||||
// Eval implements the MatrixNode interface and returns the value of
|
||||
|
|
|
@ -504,7 +504,7 @@ func histogramQuantileImpl(timestamp clientmodel.Timestamp, args []Node) interfa
|
|||
q := args[0].(ScalarNode).Eval(timestamp)
|
||||
inVec := args[1].(VectorNode).Eval(timestamp)
|
||||
outVec := Vector{}
|
||||
fpToMetricWithBuckets := map[clientmodel.Fingerprint]*metricWithBuckets{}
|
||||
signatureToMetricWithBuckets := map[uint64]*metricWithBuckets{}
|
||||
for _, el := range inVec {
|
||||
upperBound, err := strconv.ParseFloat(
|
||||
string(el.Metric.Metric[clientmodel.BucketLabel]), 64,
|
||||
|
@ -514,18 +514,18 @@ func histogramQuantileImpl(timestamp clientmodel.Timestamp, args []Node) interfa
|
|||
// TODO(beorn7): Issue a warning somehow.
|
||||
continue
|
||||
}
|
||||
fp := bucketFingerprint(el.Metric.Metric)
|
||||
mb, ok := fpToMetricWithBuckets[fp]
|
||||
signature := clientmodel.SignatureWithoutLabels(el.Metric.Metric, excludedLabels)
|
||||
mb, ok := signatureToMetricWithBuckets[signature]
|
||||
if !ok {
|
||||
el.Metric.Delete(clientmodel.BucketLabel)
|
||||
el.Metric.Delete(clientmodel.MetricNameLabel)
|
||||
mb = &metricWithBuckets{el.Metric, nil}
|
||||
fpToMetricWithBuckets[fp] = mb
|
||||
signatureToMetricWithBuckets[signature] = mb
|
||||
}
|
||||
mb.buckets = append(mb.buckets, bucket{upperBound, el.Value})
|
||||
}
|
||||
|
||||
for _, mb := range fpToMetricWithBuckets {
|
||||
for _, mb := range signatureToMetricWithBuckets {
|
||||
outVec = append(outVec, &Sample{
|
||||
Metric: mb.metric,
|
||||
Value: clientmodel.SampleValue(quantile(q, mb.buckets)),
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"hash/fnv"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
|
@ -24,6 +22,13 @@ import (
|
|||
|
||||
// Helpers to calculate quantiles.
|
||||
|
||||
// excludedLabels are the labels to exclude from signature calculation for
|
||||
// quantiles.
|
||||
var excludedLabels = map[clientmodel.LabelName]struct{}{
|
||||
clientmodel.MetricNameLabel: struct{}{},
|
||||
clientmodel.BucketLabel: struct{}{},
|
||||
}
|
||||
|
||||
type bucket struct {
|
||||
upperBound float64
|
||||
count clientmodel.SampleValue
|
||||
|
@ -99,46 +104,3 @@ func quantile(q clientmodel.SampleValue, buckets buckets) float64 {
|
|||
}
|
||||
return bucketStart + (bucketEnd-bucketStart)*float64(rank/count)
|
||||
}
|
||||
|
||||
// bucketFingerprint works like the Fingerprint method of Metric, but ignores
|
||||
// the name and the bucket label.
|
||||
func bucketFingerprint(m clientmodel.Metric) clientmodel.Fingerprint {
|
||||
numLabels := 0
|
||||
if len(m) > 2 {
|
||||
numLabels = len(m) - 2
|
||||
}
|
||||
labelNames := make([]string, 0, numLabels)
|
||||
maxLength := 0
|
||||
|
||||
for labelName, labelValue := range m {
|
||||
if labelName == clientmodel.MetricNameLabel || labelName == clientmodel.BucketLabel {
|
||||
continue
|
||||
}
|
||||
labelNames = append(labelNames, string(labelName))
|
||||
if len(labelName) > maxLength {
|
||||
maxLength = len(labelName)
|
||||
}
|
||||
if len(labelValue) > maxLength {
|
||||
maxLength = len(labelValue)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(labelNames)
|
||||
|
||||
summer := fnv.New64a()
|
||||
buf := make([]byte, maxLength)
|
||||
|
||||
for _, labelName := range labelNames {
|
||||
labelValue := m[clientmodel.LabelName(labelName)]
|
||||
|
||||
copy(buf, labelName)
|
||||
summer.Write(buf[:len(labelName)])
|
||||
summer.Write([]byte{clientmodel.SeparatorByte})
|
||||
|
||||
copy(buf, labelValue)
|
||||
summer.Write(buf[:len(labelValue)])
|
||||
summer.Write([]byte{clientmodel.SeparatorByte})
|
||||
}
|
||||
|
||||
return clientmodel.Fingerprint(binary.LittleEndian.Uint64(summer.Sum(nil)))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue