app/vmselect: obtain labels and label values from Prometheus storage inside netstorage package

This commit is contained in:
Aliaksandr Valialkin 2020-09-23 22:42:44 +03:00
parent a70df4bd83
commit ff1cbb524e
3 changed files with 41 additions and 55 deletions

View file

@ -514,12 +514,40 @@ func GetLabels(deadline searchutils.Deadline) ([]string, error) {
}
}
// Merge labels obtained from Prometheus storage.
promLabels, err := promdb.GetLabelNames(deadline)
if err != nil {
return nil, fmt.Errorf("cannot obtain labels from Prometheus storage: %w", err)
}
labels = mergeStrings(labels, promLabels)
// Sort labels like Prometheus does
sort.Strings(labels)
return labels, nil
}
func mergeStrings(a, b []string) []string {
if len(a) == 0 {
return b
}
if len(b) == 0 {
return a
}
m := make(map[string]struct{}, len(a)+len(b))
for _, s := range a {
m[s] = struct{}{}
}
for _, s := range b {
m[s] = struct{}{}
}
result := make([]string, 0, len(m))
for s := range m {
result = append(result, s)
}
return result
}
// GetLabelValues returns label values for the given labelName
// until the given deadline.
func GetLabelValues(labelName string, deadline searchutils.Deadline) ([]string, error) {
@ -536,6 +564,13 @@ func GetLabelValues(labelName string, deadline searchutils.Deadline) ([]string,
return nil, fmt.Errorf("error during label values search for labelName=%q: %w", labelName, err)
}
// Merge label values obtained from Prometheus storage.
promLabelValues, err := promdb.GetLabelValues(labelName, deadline)
if err != nil {
return nil, fmt.Errorf("cannot obtain label values for %q from Prometheus storage: %w", labelName, err)
}
labelValues = mergeStrings(labelValues, promLabelValues)
// Sort labelValues like Prometheus does
sort.Strings(labelValues)

View file

@ -14,7 +14,6 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/promql"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/searchutils"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmstorage/promdb"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver"
@ -286,10 +285,6 @@ func LabelValuesHandler(startTime time.Time, labelName string, w http.ResponseWr
if err := r.ParseForm(); err != nil {
return fmt.Errorf("cannot parse form values: %w", err)
}
promTR := storage.TimeRange{
MinTimestamp: 0,
MaxTimestamp: startTime.UnixNano() / 1e6,
}
var labelValues []string
if len(r.Form["match[]"]) == 0 && len(r.Form["start"]) == 0 && len(r.Form["end"]) == 0 {
var err error
@ -319,17 +314,8 @@ func LabelValuesHandler(startTime time.Time, labelName string, w http.ResponseWr
if err != nil {
return fmt.Errorf("cannot obtain label values for %q, match[]=%q, start=%d, end=%d: %w", labelName, matches, start, end, err)
}
promTR.MinTimestamp = start
promTR.MaxTimestamp = end
}
// Merge label values obtained from Prometheus storage.
promLabelValues, err := promdb.GetLabelValues(promTR, labelName, deadline)
if err != nil {
return fmt.Errorf("cannot obtain label values for %q from Prometheus storage: %s", labelName, err)
}
labelValues = mergeAndSortStrings(labelValues, promLabelValues)
w.Header().Set("Content-Type", "application/json")
WriteLabelValuesResponse(w, labelValues)
labelValuesDuration.UpdateDuration(startTime)
@ -464,10 +450,6 @@ func LabelsHandler(startTime time.Time, w http.ResponseWriter, r *http.Request)
if err := r.ParseForm(); err != nil {
return fmt.Errorf("cannot parse form values: %w", err)
}
promTR := storage.TimeRange{
MinTimestamp: 0,
MaxTimestamp: startTime.UnixNano() / 1e6,
}
var labels []string
if len(r.Form["match[]"]) == 0 && len(r.Form["start"]) == 0 && len(r.Form["end"]) == 0 {
var err error
@ -495,45 +477,14 @@ func LabelsHandler(startTime time.Time, w http.ResponseWriter, r *http.Request)
if err != nil {
return fmt.Errorf("cannot obtain labels for match[]=%q, start=%d, end=%d: %w", matches, start, end, err)
}
promTR.MinTimestamp = start
promTR.MaxTimestamp = end
}
// Merge labels obtained from Prometheus storage.
promLabels, err := promdb.GetLabelNames(promTR, deadline)
if err != nil {
return fmt.Errorf("cannot obtain labels from Prometheus storage: %s", err)
}
labels = mergeAndSortStrings(labels, promLabels)
w.Header().Set("Content-Type", "application/json")
WriteLabelsResponse(w, labels)
labelsDuration.UpdateDuration(startTime)
return nil
}
func mergeAndSortStrings(a, b []string) []string {
if len(a) == 0 {
return b
}
if len(b) == 0 {
return a
}
m := make(map[string]struct{}, len(a)+len(b))
for _, s := range a {
m[s] = struct{}{}
}
for _, s := range b {
m[s] = struct{}{}
}
result := make([]string, 0, len(m))
for s := range m {
result = append(result, s)
}
sort.Strings(result)
return result
}
func labelsWithMatches(matches []string, start, end int64, deadline searchutils.Deadline) ([]string, error) {
if len(matches) == 0 {
logger.Panicf("BUG: matches must be non-empty")

View file

@ -60,12 +60,12 @@ func MustClose() {
var promDB *tsdb.DB
// GetLabelNames returns label names on the given time range tr.
func GetLabelNames(tr storage.TimeRange, deadline searchutils.Deadline) ([]string, error) {
// GetLabelNames returns label names.
func GetLabelNames(deadline searchutils.Deadline) ([]string, error) {
d := time.Unix(int64(deadline.Deadline()), 0)
ctx, cancel := context.WithDeadline(context.Background(), d)
defer cancel()
q, err := promDB.Querier(ctx, tr.MinTimestamp, tr.MaxTimestamp)
q, err := promDB.Querier(ctx, 0, d.UnixNano()/1e6)
if err != nil {
return nil, err
}
@ -77,12 +77,12 @@ func GetLabelNames(tr storage.TimeRange, deadline searchutils.Deadline) ([]strin
return names, err
}
// GetLabelValues returns values for the given labelName on the given tr.
func GetLabelValues(tr storage.TimeRange, labelName string, deadline searchutils.Deadline) ([]string, error) {
// GetLabelValues returns values for the given labelName.
func GetLabelValues(labelName string, deadline searchutils.Deadline) ([]string, error) {
d := time.Unix(int64(deadline.Deadline()), 0)
ctx, cancel := context.WithDeadline(context.Background(), d)
defer cancel()
q, err := promDB.Querier(ctx, tr.MinTimestamp, tr.MaxTimestamp)
q, err := promDB.Querier(ctx, 0, d.UnixNano()/1e6)
if err != nil {
return nil, err
}