mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-15 00:13:30 +01:00
lib/storage: properly handle {__name__=~"prefix(suffix1|suffix2)",other_label="..."}
queries
They were broken in the commit 00cbb099b6
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1644
This commit is contained in:
parent
f93146c81e
commit
d15d036a5a
@ -9,6 +9,7 @@ sort: 15
|
|||||||
* FEATURE: vmagent: add `vm_promscrape_max_scrape_size_exceeded_errors_total` metric for counting of the failed scrapes due to the exceeded response size (the response size limit can be configured via `-promscrape.maxScrapeSize` command-line flag). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1639).
|
* FEATURE: vmagent: add `vm_promscrape_max_scrape_size_exceeded_errors_total` metric for counting of the failed scrapes due to the exceeded response size (the response size limit can be configured via `-promscrape.maxScrapeSize` command-line flag). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1639).
|
||||||
|
|
||||||
* BUGFIX: vmalert: properly reload rule groups if only the `interval` config option is changed. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1641).
|
* BUGFIX: vmalert: properly reload rule groups if only the `interval` config option is changed. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1641).
|
||||||
|
* BUGFIX: properly handle `{__name__=~"prefix(suffix1|suffix2)",other_label="..."}` queries. They may return unexpected empty responses since v1.66.0. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1644).
|
||||||
|
|
||||||
|
|
||||||
## [v1.66.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.66.1)
|
## [v1.66.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.66.1)
|
||||||
|
@ -30,6 +30,7 @@ func convertToCompositeTagFilters(tfs *TagFilters) []*TagFilters {
|
|||||||
var tfssCompiled []*TagFilters
|
var tfssCompiled []*TagFilters
|
||||||
// Search for filters on metric name, which will be used for creating composite filters.
|
// Search for filters on metric name, which will be used for creating composite filters.
|
||||||
var names [][]byte
|
var names [][]byte
|
||||||
|
namePrefix := ""
|
||||||
hasPositiveFilter := false
|
hasPositiveFilter := false
|
||||||
for _, tf := range tfs.tfs {
|
for _, tf := range tfs.tfs {
|
||||||
if len(tf.key) == 0 {
|
if len(tf.key) == 0 {
|
||||||
@ -43,6 +44,7 @@ func convertToCompositeTagFilters(tfs *TagFilters) []*TagFilters {
|
|||||||
for _, orSuffix := range tf.orSuffixes {
|
for _, orSuffix := range tf.orSuffixes {
|
||||||
names = append(names, []byte(orSuffix))
|
names = append(names, []byte(orSuffix))
|
||||||
}
|
}
|
||||||
|
namePrefix = tf.regexpPrefix
|
||||||
}
|
}
|
||||||
} else if !tf.isNegative && !tf.isEmptyMatch {
|
} else if !tf.isNegative && !tf.isEmptyMatch {
|
||||||
hasPositiveFilter = true
|
hasPositiveFilter = true
|
||||||
@ -54,7 +56,7 @@ func convertToCompositeTagFilters(tfs *TagFilters) []*TagFilters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create composite filters for the found names.
|
// Create composite filters for the found names.
|
||||||
var compositeKey []byte
|
var compositeKey, nameWithPrefix []byte
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
compositeFilters := 0
|
compositeFilters := 0
|
||||||
tfsNew := make([]tagFilter, 0, len(tfs.tfs))
|
tfsNew := make([]tagFilter, 0, len(tfs.tfs))
|
||||||
@ -95,7 +97,9 @@ func convertToCompositeTagFilters(tfs *TagFilters) []*TagFilters {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Create composite filter on (name, tf)
|
// Create composite filter on (name, tf)
|
||||||
compositeKey = marshalCompositeTagKey(compositeKey[:0], name, tf.key)
|
nameWithPrefix = append(nameWithPrefix[:0], namePrefix...)
|
||||||
|
nameWithPrefix = append(nameWithPrefix, name...)
|
||||||
|
compositeKey = marshalCompositeTagKey(compositeKey[:0], nameWithPrefix, tf.key)
|
||||||
var tfNew tagFilter
|
var tfNew tagFilter
|
||||||
if err := tfNew.Init(tfs.commonPrefix, compositeKey, tf.value, tf.isNegative, tf.isRegexp); err != nil {
|
if err := tfNew.Init(tfs.commonPrefix, compositeKey, tf.value, tf.isNegative, tf.isRegexp); err != nil {
|
||||||
logger.Panicf("BUG: unexpected error when creating composite tag filter for name=%q and key=%q: %s", name, tf.key, err)
|
logger.Panicf("BUG: unexpected error when creating composite tag filter for name=%q and key=%q: %s", name, tf.key, err)
|
||||||
@ -239,13 +243,18 @@ type tagFilter struct {
|
|||||||
// matchCost is a cost for matching a filter against a single string.
|
// matchCost is a cost for matching a filter against a single string.
|
||||||
matchCost uint64
|
matchCost uint64
|
||||||
|
|
||||||
|
// contains the prefix for regexp filter if isRegexp==true.
|
||||||
|
regexpPrefix string
|
||||||
|
|
||||||
// Prefix always contains {nsPrefixTagToMetricIDs, AccountID, ProjectID, key}.
|
// Prefix always contains {nsPrefixTagToMetricIDs, AccountID, ProjectID, key}.
|
||||||
// Additionally it contains:
|
// Additionally it contains:
|
||||||
// - value if !isRegexp.
|
// - value if !isRegexp.
|
||||||
// - non-regexp prefix if isRegexp.
|
// - regexpPrefix if isRegexp.
|
||||||
prefix []byte
|
prefix []byte
|
||||||
|
|
||||||
// or values obtained from regexp suffix if it equals to "foo|bar|..."
|
// `or` values obtained from regexp suffix if it equals to "foo|bar|..."
|
||||||
|
//
|
||||||
|
// the regexp prefix is stored in regexpPrefix.
|
||||||
//
|
//
|
||||||
// This array is also populated with matching Graphite metrics if key="__graphite__"
|
// This array is also populated with matching Graphite metrics if key="__graphite__"
|
||||||
orSuffixes []string
|
orSuffixes []string
|
||||||
@ -350,6 +359,7 @@ func (tf *tagFilter) InitFromGraphiteQuery(commonPrefix, query []byte, paths []s
|
|||||||
tf.value = append(tf.value[:0], query...)
|
tf.value = append(tf.value[:0], query...)
|
||||||
tf.isNegative = isNegative
|
tf.isNegative = isNegative
|
||||||
tf.isRegexp = true // this is needed for tagFilter.matchSuffix
|
tf.isRegexp = true // this is needed for tagFilter.matchSuffix
|
||||||
|
tf.regexpPrefix = prefix
|
||||||
tf.prefix = append(tf.prefix[:0], commonPrefix...)
|
tf.prefix = append(tf.prefix[:0], commonPrefix...)
|
||||||
tf.prefix = marshalTagValue(tf.prefix, nil)
|
tf.prefix = marshalTagValue(tf.prefix, nil)
|
||||||
tf.prefix = marshalTagValueNoTrailingTagSeparator(tf.prefix, []byte(prefix))
|
tf.prefix = marshalTagValueNoTrailingTagSeparator(tf.prefix, []byte(prefix))
|
||||||
@ -395,6 +405,7 @@ func (tf *tagFilter) Init(commonPrefix, key, value []byte, isNegative, isRegexp
|
|||||||
tf.isRegexp = isRegexp
|
tf.isRegexp = isRegexp
|
||||||
tf.matchCost = 0
|
tf.matchCost = 0
|
||||||
|
|
||||||
|
tf.regexpPrefix = ""
|
||||||
tf.prefix = tf.prefix[:0]
|
tf.prefix = tf.prefix[:0]
|
||||||
|
|
||||||
tf.orSuffixes = tf.orSuffixes[:0]
|
tf.orSuffixes = tf.orSuffixes[:0]
|
||||||
@ -412,6 +423,8 @@ func (tf *tagFilter) Init(commonPrefix, key, value []byte, isNegative, isRegexp
|
|||||||
if len(expr) == 0 {
|
if len(expr) == 0 {
|
||||||
tf.value = append(tf.value[:0], prefix...)
|
tf.value = append(tf.value[:0], prefix...)
|
||||||
tf.isRegexp = false
|
tf.isRegexp = false
|
||||||
|
} else {
|
||||||
|
tf.regexpPrefix = string(prefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tf.prefix = marshalTagValueNoTrailingTagSeparator(tf.prefix, prefix)
|
tf.prefix = marshalTagValueNoTrailingTagSeparator(tf.prefix, prefix)
|
||||||
|
@ -418,6 +418,44 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Multiple values regexp filter, which can be converted to non-regexp.
|
||||||
|
f([]TagFilter{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("bar|foo"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("bar|foo"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Multiple values regexp filter with common prefix, which can be converted to non-regexp.
|
||||||
|
f([]TagFilter{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("xxx(bar|foo)"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("xxx(bar|foo)"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// Multiple values regexp filter, which can be converted to non-regexp, with non-name filter.
|
// Multiple values regexp filter, which can be converted to non-regexp, with non-name filter.
|
||||||
f([]TagFilter{
|
f([]TagFilter{
|
||||||
{
|
{
|
||||||
@ -451,6 +489,39 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Multiple values regexp filter with common prefix, which can be converted to non-regexp, with non-name filter.
|
||||||
|
f([]TagFilter{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("xxx(bar|foox)"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("foo"),
|
||||||
|
Value: []byte("abc"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: []byte("\xfe\x06xxxbarfoo"),
|
||||||
|
Value: []byte("abc"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: []byte("\xfe\x07xxxfooxfoo"),
|
||||||
|
Value: []byte("abc"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// Two multiple values regexp filter, which can be converted to non-regexp, with non-name filter.
|
// Two multiple values regexp filter, which can be converted to non-regexp, with non-name filter.
|
||||||
f([]TagFilter{
|
f([]TagFilter{
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user