mirror of
https://github.com/prometheus/prometheus.git
synced 2025-02-21 03:16:00 -08:00
Fix labels handling with dedupelabels tag
Use scratch builder. Use hash compare instead of compare by label. Signed-off-by: György Krajcsovits <gyorgy.krajcsovits@grafana.com>
This commit is contained in:
parent
6b15791ec6
commit
8dfa733596
|
@ -28,14 +28,15 @@ import (
|
||||||
"github.com/prometheus/prometheus/util/convertnhcb"
|
"github.com/prometheus/prometheus/util/convertnhcb"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errLabelsMismatch = errors.New("labels mismatch")
|
|
||||||
|
|
||||||
type NHCBParser struct {
|
type NHCBParser struct {
|
||||||
// The parser we're wrapping.
|
// The parser we're wrapping.
|
||||||
parser Parser
|
parser Parser
|
||||||
// Option to keep classic histograms along with converted histograms.
|
// Option to keep classic histograms along with converted histograms.
|
||||||
keepClassicHistograms bool
|
keepClassicHistograms bool
|
||||||
|
|
||||||
|
// Labels builder.
|
||||||
|
builder labels.ScratchBuilder
|
||||||
|
|
||||||
// Caches the values from the underlying parser.
|
// Caches the values from the underlying parser.
|
||||||
// For Series and Histogram.
|
// For Series and Histogram.
|
||||||
bytes []byte
|
bytes []byte
|
||||||
|
@ -77,10 +78,11 @@ type NHCBParser struct {
|
||||||
lastBaseHistLabels labels.Labels
|
lastBaseHistLabels labels.Labels
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNHCBParser(p Parser, keepClassicHistograms bool) Parser {
|
func NewNHCBParser(p Parser, st *labels.SymbolTable, keepClassicHistograms bool) Parser {
|
||||||
return &NHCBParser{
|
return &NHCBParser{
|
||||||
parser: p,
|
parser: p,
|
||||||
keepClassicHistograms: keepClassicHistograms,
|
keepClassicHistograms: keepClassicHistograms,
|
||||||
|
builder: labels.NewScratchBuilderWithSymbolTable(st, 16),
|
||||||
tempNHCB: convertnhcb.NewTempHistogram(),
|
tempNHCB: convertnhcb.NewTempHistogram(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,48 +200,37 @@ func (p *NHCBParser) compareLabels() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare the labels.
|
if p.lastBaseHistLabels.Get(labels.MetricName) != convertnhcb.GetHistogramMetricBaseName(p.lset.Get(labels.MetricName)) {
|
||||||
err := p.lset.Validate(func(l labels.Label) error {
|
// Different metric name.
|
||||||
switch {
|
p.storeBaseLabels()
|
||||||
case l.Name == labels.BucketLabel:
|
return true
|
||||||
case l.Name == labels.MetricName:
|
}
|
||||||
baseName := convertnhcb.GetHistogramMetricBaseName(l.Value)
|
var buf []byte
|
||||||
if baseName != p.lastBaseHistLabels.Get(labels.MetricName) {
|
lastHash, _ := p.lastBaseHistLabels.HashWithoutLabels(buf, labels.BucketLabel)
|
||||||
// Different metric name.
|
nextHash, _ := p.lset.HashWithoutLabels(buf, labels.BucketLabel)
|
||||||
if p.typ == model.MetricTypeHistogram {
|
if lastHash != nextHash {
|
||||||
p.storeBaseLabels()
|
// Different label values.
|
||||||
} else {
|
p.storeBaseLabels()
|
||||||
p.lastBaseHistLabels = labels.EmptyLabels()
|
return true
|
||||||
}
|
}
|
||||||
return errLabelsMismatch
|
|
||||||
}
|
return false
|
||||||
case l.Value != p.lastBaseHistLabels.Get(l.Name):
|
|
||||||
// Different label value.
|
|
||||||
if p.typ == model.MetricTypeHistogram {
|
|
||||||
p.storeBaseLabels()
|
|
||||||
} else {
|
|
||||||
p.lastBaseHistLabels = labels.EmptyLabels()
|
|
||||||
}
|
|
||||||
return errLabelsMismatch
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
return errors.Is(err, errLabelsMismatch)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the label set of the classic histogram without suffix and bucket `le` label.
|
// Save the label set of the classic histogram without suffix and bucket `le` label.
|
||||||
func (p *NHCBParser) storeBaseLabels() {
|
func (p *NHCBParser) storeBaseLabels() {
|
||||||
builder := labels.Builder{}
|
p.builder.Reset()
|
||||||
p.lset.Range(func(l labels.Label) {
|
p.lset.Range(func(l labels.Label) {
|
||||||
switch {
|
switch {
|
||||||
case l.Name == labels.BucketLabel:
|
case l.Name == labels.BucketLabel:
|
||||||
case l.Name == labels.MetricName:
|
case l.Name == labels.MetricName:
|
||||||
builder.Set(l.Name, convertnhcb.GetHistogramMetricBaseName(l.Value))
|
p.builder.Add(l.Name, convertnhcb.GetHistogramMetricBaseName(l.Value))
|
||||||
default:
|
default:
|
||||||
builder.Set(l.Name, l.Value)
|
p.builder.Add(l.Name, l.Value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
p.lastBaseHistLabels = builder.Labels()
|
// Note: we don't sort the labels as changing the name label value doesn't affect sorting.
|
||||||
|
p.lastBaseHistLabels = p.builder.Labels()
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleClassicHistogramSeries collates the classic histogram series to be converted to NHCB
|
// handleClassicHistogramSeries collates the classic histogram series to be converted to NHCB
|
||||||
|
|
|
@ -441,7 +441,7 @@ foobar{quantile="0.99"} 150.1`
|
||||||
}
|
}
|
||||||
|
|
||||||
p := NewOpenMetricsParser([]byte(input), labels.NewSymbolTable(), WithOMParserCTSeriesSkipped())
|
p := NewOpenMetricsParser([]byte(input), labels.NewSymbolTable(), WithOMParserCTSeriesSkipped())
|
||||||
p = NewNHCBParser(p, false)
|
p = NewNHCBParser(p, labels.NewSymbolTable(), false)
|
||||||
got := testParse(t, p)
|
got := testParse(t, p)
|
||||||
requireEntries(t, exp, got)
|
requireEntries(t, exp, got)
|
||||||
}
|
}
|
||||||
|
@ -508,7 +508,8 @@ something_bucket{a="b",le="+Inf"} 9 # {id="something-test"} 2e100 123.000
|
||||||
}
|
}
|
||||||
|
|
||||||
p := NewOpenMetricsParser([]byte(input), labels.NewSymbolTable(), WithOMParserCTSeriesSkipped())
|
p := NewOpenMetricsParser([]byte(input), labels.NewSymbolTable(), WithOMParserCTSeriesSkipped())
|
||||||
p = NewNHCBParser(p, false)
|
|
||||||
|
p = NewNHCBParser(p, labels.NewSymbolTable(), false)
|
||||||
got := testParse(t, p)
|
got := testParse(t, p)
|
||||||
requireEntries(t, exp, got)
|
requireEntries(t, exp, got)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1546,7 +1546,7 @@ type appendErrors struct {
|
||||||
func (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string, ts time.Time) (total, added, seriesAdded int, err error) {
|
func (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string, ts time.Time) (total, added, seriesAdded int, err error) {
|
||||||
p, err := textparse.New(b, contentType, sl.scrapeClassicHistograms, sl.enableCTZeroIngestion, sl.symbolTable)
|
p, err := textparse.New(b, contentType, sl.scrapeClassicHistograms, sl.enableCTZeroIngestion, sl.symbolTable)
|
||||||
if sl.convertClassicHistograms {
|
if sl.convertClassicHistograms {
|
||||||
p = textparse.NewNHCBParser(p, sl.scrapeClassicHistograms)
|
p = textparse.NewNHCBParser(p, sl.symbolTable, sl.scrapeClassicHistograms)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sl.l.Debug(
|
sl.l.Debug(
|
||||||
|
|
Loading…
Reference in a new issue