mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-01-30 15:22:07 +00:00
app/vmselect: obtain labels and label values from Prometheus storage inside netstorage package
This commit is contained in:
parent
a70df4bd83
commit
ff1cbb524e
3 changed files with 41 additions and 55 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue