mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-24 13:14:05 -08:00
Correctly handle empty labels. (#594)
Currently a time series with empty labels is not treated the same as one with missing labels. Currently this can only come from ALERTS&ALERT_FOR_STATE so it's unlikely anyone has actually hit it. Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
This commit is contained in:
parent
2ae028114c
commit
6ac81cc7a9
43
db_test.go
43
db_test.go
|
@ -219,6 +219,29 @@ func TestDBAppenderAddRef(t *testing.T) {
|
||||||
}, res)
|
}, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAppendEmptyLabelsIgnored(t *testing.T) {
|
||||||
|
db, delete := openTestDB(t, nil)
|
||||||
|
defer func() {
|
||||||
|
testutil.Ok(t, db.Close())
|
||||||
|
delete()
|
||||||
|
}()
|
||||||
|
|
||||||
|
app1 := db.Appender()
|
||||||
|
|
||||||
|
ref1, err := app1.Add(labels.FromStrings("a", "b"), 123, 0)
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
|
// Construct labels manually so there is an empty label.
|
||||||
|
ref2, err := app1.Add(labels.Labels{labels.Label{"a", "b"}, labels.Label{"c", ""}}, 124, 0)
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
|
// Should be the same series.
|
||||||
|
testutil.Equals(t, ref1, ref2)
|
||||||
|
|
||||||
|
err = app1.Commit()
|
||||||
|
testutil.Ok(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestDeleteSimple(t *testing.T) {
|
func TestDeleteSimple(t *testing.T) {
|
||||||
numSamples := int64(10)
|
numSamples := int64(10)
|
||||||
|
|
||||||
|
@ -1580,26 +1603,26 @@ func TestDB_LabelNames(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
sampleLabels1: [][2]string{
|
sampleLabels1: [][2]string{
|
||||||
[2]string{"name1", ""},
|
[2]string{"name1", "1"},
|
||||||
[2]string{"name3", ""},
|
[2]string{"name3", "3"},
|
||||||
[2]string{"name2", ""},
|
[2]string{"name2", "2"},
|
||||||
},
|
},
|
||||||
sampleLabels2: [][2]string{
|
sampleLabels2: [][2]string{
|
||||||
[2]string{"name4", ""},
|
[2]string{"name4", "4"},
|
||||||
[2]string{"name1", ""},
|
[2]string{"name1", "1"},
|
||||||
},
|
},
|
||||||
exp1: []string{"name1", "name2", "name3"},
|
exp1: []string{"name1", "name2", "name3"},
|
||||||
exp2: []string{"name1", "name2", "name3", "name4"},
|
exp2: []string{"name1", "name2", "name3", "name4"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sampleLabels1: [][2]string{
|
sampleLabels1: [][2]string{
|
||||||
[2]string{"name2", ""},
|
[2]string{"name2", "2"},
|
||||||
[2]string{"name1", ""},
|
[2]string{"name1", "1"},
|
||||||
[2]string{"name2", ""},
|
[2]string{"name2", "2"},
|
||||||
},
|
},
|
||||||
sampleLabels2: [][2]string{
|
sampleLabels2: [][2]string{
|
||||||
[2]string{"name6", ""},
|
[2]string{"name6", "6"},
|
||||||
[2]string{"name0", ""},
|
[2]string{"name0", "0"},
|
||||||
},
|
},
|
||||||
exp1: []string{"name1", "name2"},
|
exp1: []string{"name1", "name2"},
|
||||||
exp2: []string{"name0", "name1", "name2", "name6"},
|
exp2: []string{"name0", "name1", "name2", "name6"},
|
||||||
|
|
3
head.go
3
head.go
|
@ -755,6 +755,9 @@ func (a *headAppender) Add(lset labels.Labels, t int64, v float64) (uint64, erro
|
||||||
return 0, ErrOutOfBounds
|
return 0, ErrOutOfBounds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure no empty labels have gotten through.
|
||||||
|
lset = lset.WithoutEmpty()
|
||||||
|
|
||||||
s, created := a.head.getOrCreate(lset.Hash(), lset)
|
s, created := a.head.getOrCreate(lset.Hash(), lset)
|
||||||
if created {
|
if created {
|
||||||
a.series = append(a.series, RefSeries{
|
a.series = append(a.series, RefSeries{
|
||||||
|
|
|
@ -103,6 +103,23 @@ func (ls Labels) Map() map[string]string {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithoutEmpty returns the labelset without empty labels.
|
||||||
|
// May return the same labelset.
|
||||||
|
func (ls Labels) WithoutEmpty() Labels {
|
||||||
|
for _, v := range ls {
|
||||||
|
if v.Value == "" {
|
||||||
|
els := make(Labels, 0, len(ls)-1)
|
||||||
|
for _, v := range ls {
|
||||||
|
if v.Value != "" {
|
||||||
|
els = append(els, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return els
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ls
|
||||||
|
}
|
||||||
|
|
||||||
// New returns a sorted Labels from the given labels.
|
// New returns a sorted Labels from the given labels.
|
||||||
// The caller has to guarantee that all label names are unique.
|
// The caller has to guarantee that all label names are unique.
|
||||||
func New(ls ...Label) Labels {
|
func New(ls ...Label) Labels {
|
||||||
|
@ -119,7 +136,9 @@ func New(ls ...Label) Labels {
|
||||||
func FromMap(m map[string]string) Labels {
|
func FromMap(m map[string]string) Labels {
|
||||||
l := make(Labels, 0, len(m))
|
l := make(Labels, 0, len(m))
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
l = append(l, Label{Name: k, Value: v})
|
if v != "" {
|
||||||
|
l = append(l, Label{Name: k, Value: v})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sort.Sort(l)
|
sort.Sort(l)
|
||||||
|
|
||||||
|
@ -133,7 +152,9 @@ func FromStrings(ss ...string) Labels {
|
||||||
}
|
}
|
||||||
var res Labels
|
var res Labels
|
||||||
for i := 0; i < len(ss); i += 2 {
|
for i := 0; i < len(ss); i += 2 {
|
||||||
res = append(res, Label{Name: ss[i], Value: ss[i+1]})
|
if ss[i+1] != "" {
|
||||||
|
res = append(res, Label{Name: ss[i], Value: ss[i+1]})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(res)
|
sort.Sort(res)
|
||||||
|
|
Loading…
Reference in a new issue