mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
Update package model/textparse for new labels.Labels type
Parse metrics using labels.ScratchBuilder, so we reduce assumptions about internals of Labels. Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This commit is contained in:
parent
fe9fe0e1e5
commit
1f04899ae3
|
@ -22,7 +22,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
@ -82,6 +81,7 @@ func (l *openMetricsLexer) Error(es string) {
|
||||||
// This is based on the working draft https://docs.google.com/document/u/1/d/1KwV0mAXwwbvvifBvDKH_LU1YjyXE_wxCkHNoCGq1GX0/edit
|
// This is based on the working draft https://docs.google.com/document/u/1/d/1KwV0mAXwwbvvifBvDKH_LU1YjyXE_wxCkHNoCGq1GX0/edit
|
||||||
type OpenMetricsParser struct {
|
type OpenMetricsParser struct {
|
||||||
l *openMetricsLexer
|
l *openMetricsLexer
|
||||||
|
builder labels.ScratchBuilder
|
||||||
series []byte
|
series []byte
|
||||||
text []byte
|
text []byte
|
||||||
mtype MetricType
|
mtype MetricType
|
||||||
|
@ -158,14 +158,11 @@ func (p *OpenMetricsParser) Comment() []byte {
|
||||||
// Metric writes the labels of the current sample into the passed labels.
|
// Metric writes the labels of the current sample into the passed labels.
|
||||||
// It returns the string from which the metric was parsed.
|
// It returns the string from which the metric was parsed.
|
||||||
func (p *OpenMetricsParser) Metric(l *labels.Labels) string {
|
func (p *OpenMetricsParser) Metric(l *labels.Labels) string {
|
||||||
// Allocate the full immutable string immediately, so we just
|
// Copy the buffer to a string: this is only necessary for the return value.
|
||||||
// have to create references on it below.
|
|
||||||
s := string(p.series)
|
s := string(p.series)
|
||||||
|
|
||||||
*l = append(*l, labels.Label{
|
p.builder.Reset()
|
||||||
Name: labels.MetricName,
|
p.builder.Add(labels.MetricName, s[:p.offsets[0]-p.start])
|
||||||
Value: s[:p.offsets[0]-p.start],
|
|
||||||
})
|
|
||||||
|
|
||||||
for i := 1; i < len(p.offsets); i += 4 {
|
for i := 1; i < len(p.offsets); i += 4 {
|
||||||
a := p.offsets[i] - p.start
|
a := p.offsets[i] - p.start
|
||||||
|
@ -173,16 +170,16 @@ func (p *OpenMetricsParser) Metric(l *labels.Labels) string {
|
||||||
c := p.offsets[i+2] - p.start
|
c := p.offsets[i+2] - p.start
|
||||||
d := p.offsets[i+3] - p.start
|
d := p.offsets[i+3] - p.start
|
||||||
|
|
||||||
|
value := s[c:d]
|
||||||
// Replacer causes allocations. Replace only when necessary.
|
// Replacer causes allocations. Replace only when necessary.
|
||||||
if strings.IndexByte(s[c:d], byte('\\')) >= 0 {
|
if strings.IndexByte(s[c:d], byte('\\')) >= 0 {
|
||||||
*l = append(*l, labels.Label{Name: s[a:b], Value: lvalReplacer.Replace(s[c:d])})
|
value = lvalReplacer.Replace(value)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
*l = append(*l, labels.Label{Name: s[a:b], Value: s[c:d]})
|
p.builder.Add(s[a:b], value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort labels.
|
p.builder.Sort()
|
||||||
sort.Sort(*l)
|
*l = p.builder.Labels()
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
@ -204,17 +201,18 @@ func (p *OpenMetricsParser) Exemplar(e *exemplar.Exemplar) bool {
|
||||||
e.Ts = p.exemplarTs
|
e.Ts = p.exemplarTs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.builder.Reset()
|
||||||
for i := 0; i < len(p.eOffsets); i += 4 {
|
for i := 0; i < len(p.eOffsets); i += 4 {
|
||||||
a := p.eOffsets[i] - p.start
|
a := p.eOffsets[i] - p.start
|
||||||
b := p.eOffsets[i+1] - p.start
|
b := p.eOffsets[i+1] - p.start
|
||||||
c := p.eOffsets[i+2] - p.start
|
c := p.eOffsets[i+2] - p.start
|
||||||
d := p.eOffsets[i+3] - p.start
|
d := p.eOffsets[i+3] - p.start
|
||||||
|
|
||||||
e.Labels = append(e.Labels, labels.Label{Name: s[a:b], Value: s[c:d]})
|
p.builder.Add(s[a:b], s[c:d])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the labels.
|
p.builder.Sort()
|
||||||
sort.Sort(e.Labels)
|
e.Labels = p.builder.Labels()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
@ -144,6 +143,7 @@ func (l *promlexer) Error(es string) {
|
||||||
// Prometheus text exposition format.
|
// Prometheus text exposition format.
|
||||||
type PromParser struct {
|
type PromParser struct {
|
||||||
l *promlexer
|
l *promlexer
|
||||||
|
builder labels.ScratchBuilder
|
||||||
series []byte
|
series []byte
|
||||||
text []byte
|
text []byte
|
||||||
mtype MetricType
|
mtype MetricType
|
||||||
|
@ -212,14 +212,11 @@ func (p *PromParser) Comment() []byte {
|
||||||
// Metric writes the labels of the current sample into the passed labels.
|
// Metric writes the labels of the current sample into the passed labels.
|
||||||
// It returns the string from which the metric was parsed.
|
// It returns the string from which the metric was parsed.
|
||||||
func (p *PromParser) Metric(l *labels.Labels) string {
|
func (p *PromParser) Metric(l *labels.Labels) string {
|
||||||
// Allocate the full immutable string immediately, so we just
|
// Copy the buffer to a string: this is only necessary for the return value.
|
||||||
// have to create references on it below.
|
|
||||||
s := string(p.series)
|
s := string(p.series)
|
||||||
|
|
||||||
*l = append(*l, labels.Label{
|
p.builder.Reset()
|
||||||
Name: labels.MetricName,
|
p.builder.Add(labels.MetricName, s[:p.offsets[0]-p.start])
|
||||||
Value: s[:p.offsets[0]-p.start],
|
|
||||||
})
|
|
||||||
|
|
||||||
for i := 1; i < len(p.offsets); i += 4 {
|
for i := 1; i < len(p.offsets); i += 4 {
|
||||||
a := p.offsets[i] - p.start
|
a := p.offsets[i] - p.start
|
||||||
|
@ -227,16 +224,16 @@ func (p *PromParser) Metric(l *labels.Labels) string {
|
||||||
c := p.offsets[i+2] - p.start
|
c := p.offsets[i+2] - p.start
|
||||||
d := p.offsets[i+3] - p.start
|
d := p.offsets[i+3] - p.start
|
||||||
|
|
||||||
|
value := s[c:d]
|
||||||
// Replacer causes allocations. Replace only when necessary.
|
// Replacer causes allocations. Replace only when necessary.
|
||||||
if strings.IndexByte(s[c:d], byte('\\')) >= 0 {
|
if strings.IndexByte(s[c:d], byte('\\')) >= 0 {
|
||||||
*l = append(*l, labels.Label{Name: s[a:b], Value: lvalReplacer.Replace(s[c:d])})
|
value = lvalReplacer.Replace(value)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
*l = append(*l, labels.Label{Name: s[a:b], Value: s[c:d]})
|
p.builder.Add(s[a:b], value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort labels to maintain the sorted labels invariant.
|
p.builder.Sort()
|
||||||
sort.Sort(*l)
|
*l = p.builder.Labels()
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
@ -59,6 +58,8 @@ type ProtobufParser struct {
|
||||||
// that we have to decode the next MetricFamily.
|
// that we have to decode the next MetricFamily.
|
||||||
state Entry
|
state Entry
|
||||||
|
|
||||||
|
builder labels.ScratchBuilder // held here to reduce allocations when building Labels
|
||||||
|
|
||||||
mf *dto.MetricFamily
|
mf *dto.MetricFamily
|
||||||
|
|
||||||
// The following are just shenanigans to satisfy the Parser interface.
|
// The following are just shenanigans to satisfy the Parser interface.
|
||||||
|
@ -245,23 +246,19 @@ func (p *ProtobufParser) Comment() []byte {
|
||||||
// Metric writes the labels of the current sample into the passed labels.
|
// Metric writes the labels of the current sample into the passed labels.
|
||||||
// It returns the string from which the metric was parsed.
|
// It returns the string from which the metric was parsed.
|
||||||
func (p *ProtobufParser) Metric(l *labels.Labels) string {
|
func (p *ProtobufParser) Metric(l *labels.Labels) string {
|
||||||
*l = append(*l, labels.Label{
|
p.builder.Reset()
|
||||||
Name: labels.MetricName,
|
p.builder.Add(labels.MetricName, p.getMagicName())
|
||||||
Value: p.getMagicName(),
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, lp := range p.mf.GetMetric()[p.metricPos].GetLabel() {
|
for _, lp := range p.mf.GetMetric()[p.metricPos].GetLabel() {
|
||||||
*l = append(*l, labels.Label{
|
p.builder.Add(lp.GetName(), lp.GetValue())
|
||||||
Name: lp.GetName(),
|
|
||||||
Value: lp.GetValue(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if needed, name, value := p.getMagicLabel(); needed {
|
if needed, name, value := p.getMagicLabel(); needed {
|
||||||
*l = append(*l, labels.Label{Name: name, Value: value})
|
p.builder.Add(name, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort labels to maintain the sorted labels invariant.
|
// Sort labels to maintain the sorted labels invariant.
|
||||||
sort.Sort(*l)
|
p.builder.Sort()
|
||||||
|
*l = p.builder.Labels()
|
||||||
|
|
||||||
return p.metricBytes.String()
|
return p.metricBytes.String()
|
||||||
}
|
}
|
||||||
|
@ -305,12 +302,12 @@ func (p *ProtobufParser) Exemplar(ex *exemplar.Exemplar) bool {
|
||||||
ex.HasTs = true
|
ex.HasTs = true
|
||||||
ex.Ts = ts.GetSeconds()*1000 + int64(ts.GetNanos()/1_000_000)
|
ex.Ts = ts.GetSeconds()*1000 + int64(ts.GetNanos()/1_000_000)
|
||||||
}
|
}
|
||||||
|
p.builder.Reset()
|
||||||
for _, lp := range exProto.GetLabel() {
|
for _, lp := range exProto.GetLabel() {
|
||||||
ex.Labels = append(ex.Labels, labels.Label{
|
p.builder.Add(lp.GetName(), lp.GetValue())
|
||||||
Name: lp.GetName(),
|
|
||||||
Value: lp.GetValue(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
p.builder.Sort()
|
||||||
|
ex.Labels = p.builder.Labels()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue