lib/storage: fix returning camelcase label names (#3608)

* lib/storage: fix returning camelcase label names

* doc: add change log

* Update docs/CHANGELOG.md

* Update docs/CHANGELOG.md

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
Dmytro Kozlov 2023-01-07 10:50:14 +02:00 committed by GitHub
parent 5fe7ff24c2
commit 488940502c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 14 deletions

View file

@ -44,6 +44,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): fix a panic during target discovery when `vmagent` runs with `-promscrape.dropOriginalLabels` command-line flag. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3580). The bug has been introduced in [v1.85.0](https://docs.victoriametrics.com/CHANGELOG.html#v1850).
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): [dockerswarm_sd_configs](https://docs.victoriametrics.com/sd_configs.html#dockerswarm_sd_configs): properly encode `filters` field. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3579).
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): fix possible resource leak after hot reload of the updated [consul_sd_configs](https://docs.victoriametrics.com/sd_configs.html#consul_sd_configs). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3468).
* BUGFIX: properly return label names starting from uppercase such as `CamelCaseLabel` from [/api/v1/labels](https://docs.victoriametrics.com/url-examples.html#apiv1labels). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3566).
## [v1.85.3](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.3)

View file

@ -857,7 +857,7 @@ func (is *indexSearch) searchLabelNamesWithFiltersOnDate(qt *querytracer.Tracer,
if len(labelName) == 0 {
labelName = []byte("__name__")
}
if isArtificialTagKey(labelName) || string(labelName) == string(prevLabelName) {
if isArtificialTagKey(labelName) {
// Search for the next tag key.
// The last char in kb.B must be tagSeparatorChar.
// Just increment it in order to jump to the next tag key.
@ -872,6 +872,17 @@ func (is *indexSearch) searchLabelNamesWithFiltersOnDate(qt *querytracer.Tracer,
ts.Seek(kb.B)
continue
}
if string(labelName) == string(prevLabelName) {
var tagValue []byte
if string(labelName) != "__name__" {
tagValue = labelName
}
kb.B = is.marshalCommonPrefixForDate(kb.B[:0], date)
kb.B = marshalTagValue(kb.B, tagValue)
kb.B[len(kb.B)-1]++
ts.Seek(kb.B)
continue
}
lns[string(labelName)] = struct{}{}
prevLabelName = append(prevLabelName[:0], labelName...)
}

View file

@ -1585,7 +1585,7 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
perDayMetricIDs := make(map[uint64]*uint64set.Set)
var allMetricIDs uint64set.Set
labelNames := []string{
"__name__", "constant", "day", "uniqueid",
"__name__", "constant", "day", "UniqueId", "some_unique_id",
}
labelValues := []string{
"testMetric",
@ -1606,9 +1606,13 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
fmt.Sprintf("%v", day),
)
mn.AddTag(
"uniqueid",
"UniqueId",
fmt.Sprintf("%v", metric),
)
mn.AddTag(
"some_unique_id",
fmt.Sprintf("%v", day),
)
mn.sortTags()
metricNameBuf = mn.Marshal(metricNameBuf[:0])
@ -1775,6 +1779,10 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
t.Fatalf("unexpected SeriesCountByMetricName;\ngot\n%v\nwant\n%v", status.SeriesCountByMetricName, expectedSeriesCountByMetricName)
}
expectedSeriesCountByLabelName := []TopHeapEntry{
{
Name: "UniqueId",
Count: 1000,
},
{
Name: "__name__",
Count: 1000,
@ -1788,7 +1796,7 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
Count: 1000,
},
{
Name: "uniqueid",
Name: "some_unique_id",
Count: 1000,
},
}
@ -1806,7 +1814,7 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
}
expectedLabelValueCountByLabelName := []TopHeapEntry{
{
Name: "uniqueid",
Name: "UniqueId",
Count: 1000,
},
{
@ -1821,6 +1829,10 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
Name: "day",
Count: 1,
},
{
Name: "some_unique_id",
Count: 1,
},
}
if !reflect.DeepEqual(status.LabelValueCountByLabelName, expectedLabelValueCountByLabelName) {
t.Fatalf("unexpected LabelValueCountByLabelName;\ngot\n%v\nwant\n%v", status.LabelValueCountByLabelName, expectedLabelValueCountByLabelName)
@ -1839,11 +1851,11 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
Count: 1000,
},
{
Name: "uniqueid=0",
Count: 1,
Name: "some_unique_id=0",
Count: 1000,
},
{
Name: "uniqueid=1",
Name: "UniqueId=1",
Count: 1,
},
}
@ -1854,7 +1866,7 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
if status.TotalSeries != expectedTotalSeries {
t.Fatalf("unexpected TotalSeries; got %d; want %d", status.TotalSeries, expectedTotalSeries)
}
expectedLabelValuePairs := uint64(4000)
expectedLabelValuePairs := uint64(5000)
if status.TotalLabelValuePairs != expectedLabelValuePairs {
t.Fatalf("unexpected TotalLabelValuePairs; got %d; want %d", status.TotalLabelValuePairs, expectedLabelValuePairs)
}
@ -1884,7 +1896,7 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
if status.TotalSeries != expectedTotalSeries {
t.Fatalf("unexpected TotalSeries; got %d; want %d", status.TotalSeries, expectedTotalSeries)
}
expectedLabelValuePairs = 4000
expectedLabelValuePairs = 5000
if status.TotalLabelValuePairs != expectedLabelValuePairs {
t.Fatalf("unexpected TotalLabelValuePairs; got %d; want %d", status.TotalLabelValuePairs, expectedLabelValuePairs)
}
@ -1910,7 +1922,7 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
if status.TotalSeries != expectedTotalSeries {
t.Fatalf("unexpected TotalSeries; got %d; want %d", status.TotalSeries, expectedTotalSeries)
}
expectedLabelValuePairs = 20000
expectedLabelValuePairs = 25000
if status.TotalLabelValuePairs != expectedLabelValuePairs {
t.Fatalf("unexpected TotalLabelValuePairs; got %d; want %d", status.TotalLabelValuePairs, expectedLabelValuePairs)
}
@ -1942,7 +1954,7 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
// Check GetTSDBStatus with non-nil filter, which matches only 3 series
tfs = NewTagFilters()
if err := tfs.Add([]byte("uniqueid"), []byte("0|1|3"), false, true); err != nil {
if err := tfs.Add([]byte("UniqueId"), []byte("0|1|3"), false, true); err != nil {
t.Fatalf("cannot add filter: %s", err)
}
status, err = db.GetTSDBStatus(nil, []*TagFilters{tfs}, baseDate, "", 5, 1e6, noDeadline)
@ -1965,7 +1977,7 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
if status.TotalSeries != expectedTotalSeries {
t.Fatalf("unexpected TotalSeries; got %d; want %d", status.TotalSeries, expectedTotalSeries)
}
expectedLabelValuePairs = 12
expectedLabelValuePairs = 15
if status.TotalLabelValuePairs != expectedLabelValuePairs {
t.Fatalf("unexpected TotalLabelValuePairs; got %d; want %d", status.TotalLabelValuePairs, expectedLabelValuePairs)
}
@ -1991,7 +2003,7 @@ func TestSearchTSIDWithTimeRange(t *testing.T) {
if status.TotalSeries != expectedTotalSeries {
t.Fatalf("unexpected TotalSeries; got %d; want %d", status.TotalSeries, expectedTotalSeries)
}
expectedLabelValuePairs = 60
expectedLabelValuePairs = 75
if status.TotalLabelValuePairs != expectedLabelValuePairs {
t.Fatalf("unexpected TotalLabelValuePairs; got %d; want %d", status.TotalLabelValuePairs, expectedLabelValuePairs)
}