app/vmselect/graphite: follow-up after 529d7be26b

This commit is contained in:
Aliaksandr Valialkin 2021-03-18 16:15:27 +02:00
parent 529d7be26b
commit b0c956a178
2 changed files with 29 additions and 22 deletions

View File

@ -222,23 +222,32 @@ func MetricsIndexHandler(startTime time.Time, w http.ResponseWriter, r *http.Req
return nil return nil
} }
// metricsFind searches for label values that match the given head and tail. // metricsFind searches for label values that match the given qHead and qTail.
func metricsFind(tr storage.TimeRange, label, head, tail string, delimiter byte, isExpand bool, deadline searchutils.Deadline) ([]string, error) { func metricsFind(tr storage.TimeRange, label, qHead, qTail string, delimiter byte, isExpand bool, deadline searchutils.Deadline) ([]string, error) {
n := strings.IndexAny(tail, "*{[") n := strings.IndexAny(qTail, "*{[")
// fast path.
if n < 0 { if n < 0 {
res, err := netstorage.GetTagValueSuffixes(tr, label, head+tail, delimiter, deadline) query := qHead + qTail
suffixes, err := netstorage.GetTagValueSuffixes(tr, label, query, delimiter, deadline)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(res) == 0 { if len(suffixes) == 0 {
return nil, nil return nil, nil
} }
return []string{head + tail}, nil if len(query) > 0 && query[len(query)-1] == delimiter {
return []string{query}, nil
} }
if strings.HasSuffix(head, "*") { results := make([]string, 0, len(suffixes))
head = head[:len(head)-1] for _, suffix := range suffixes {
suffixes, err := netstorage.GetTagValueSuffixes(tr, label, head, delimiter, deadline) if len(suffix) == 0 || len(suffix) == 1 && suffix[0] == delimiter {
results = append(results, query+suffix)
}
}
return results, nil
}
if n == len(qTail)-1 && strings.HasSuffix(qTail, "*") {
query := qHead + qTail[:len(qTail)-1]
suffixes, err := netstorage.GetTagValueSuffixes(tr, label, query, delimiter, deadline)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -247,25 +256,22 @@ func metricsFind(tr storage.TimeRange, label, head, tail string, delimiter byte,
} }
results := make([]string, 0, len(suffixes)) results := make([]string, 0, len(suffixes))
for _, suffix := range suffixes { for _, suffix := range suffixes {
results = append(results, head+suffix) results = append(results, query+suffix)
} }
return results, nil return results, nil
} }
qHead += qTail[:n]
head += tail[:n] paths, err := metricsFind(tr, label, qHead, "*", delimiter, isExpand, deadline)
subquery := head + "*"
// execute subquery with the given head.
paths, err := metricsFind(tr, label, subquery, "*", delimiter, isExpand, deadline)
if err != nil { if err != nil {
return nil, err return nil, err
} }
tailNew := "" suffix := qTail[n:]
suffix := tail[n:] qTail = ""
if m := strings.IndexByte(suffix, delimiter); m >= 0 { if m := strings.IndexByte(suffix, delimiter); m >= 0 {
tailNew = suffix[m+1:] qTail = suffix[m+1:]
suffix = suffix[:m+1] suffix = suffix[:m+1]
} }
qPrefix := head + suffix qPrefix := qHead + suffix
rePrefix, err := getRegexpForQuery(qPrefix, delimiter) rePrefix, err := getRegexpForQuery(qPrefix, delimiter)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot convert query %q to regexp: %w", qPrefix, err) return nil, fmt.Errorf("cannot convert query %q to regexp: %w", qPrefix, err)
@ -275,11 +281,11 @@ func metricsFind(tr storage.TimeRange, label, head, tail string, delimiter byte,
if !rePrefix.MatchString(path) { if !rePrefix.MatchString(path) {
continue continue
} }
if tailNew == "" { if qTail == "" {
results = append(results, path) results = append(results, path)
continue continue
} }
fullPaths, err := metricsFind(tr, label, path, tailNew, delimiter, isExpand, deadline) fullPaths, err := metricsFind(tr, label, path, qTail, delimiter, isExpand, deadline)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -10,6 +10,7 @@
* `process_virtual_memory_peak_bytes` - peak virtual memory usage for the process. * `process_virtual_memory_peak_bytes` - peak virtual memory usage for the process.
* BUGFIX: prevent from infinite loop on `{__graphite__="..."}` filters when a metric name contains `*`, `{` or `[` chars. * BUGFIX: prevent from infinite loop on `{__graphite__="..."}` filters when a metric name contains `*`, `{` or `[` chars.
* BUGFIX: prevent from infinite loop in `/metrics/find` and `/metrics/expand` [Graphite Metrics API handlers](https://victoriametrics.github.io/#graphite-metrics-api-usage) when they match metric names or labels with `*`, `{` or `[` chars.
# [v1.56.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.56.0) # [v1.56.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.56.0)