(ctx context.Context, hints *storage.LabelHints, matchers ...*labels.Matcher)
| 552 | } |
| 553 | |
| 554 | func (q querier) LabelNames(ctx context.Context, hints *storage.LabelHints, matchers ...*labels.Matcher) ([]string, annotations.Annotations, error) { |
| 555 | ctx, stats, userID, mint, maxt, metadataQuerier, queriers, err := q.setupFromCtx(ctx) |
| 556 | if err == errEmptyTimeRange { |
| 557 | return nil, nil, nil |
| 558 | } else if err != nil { |
| 559 | return nil, nil, err |
| 560 | } |
| 561 | startT := time.Now() |
| 562 | defer func() { |
| 563 | stats.AddQueryStorageWallTime(time.Since(startT)) |
| 564 | }() |
| 565 | |
| 566 | // For label names queries without specifying the start time, we prefer to |
| 567 | // only query ingesters and not to query maxQueryLength to avoid OOM kill. |
| 568 | if mint == 0 { |
| 569 | return metadataQuerier.LabelNames(ctx, hints, matchers...) |
| 570 | } |
| 571 | |
| 572 | startTime := model.Time(mint) |
| 573 | endTime := model.Time(maxt) |
| 574 | |
| 575 | if maxQueryLength := q.limits.MaxQueryLength(userID); maxQueryLength > 0 && endTime.Sub(startTime) > maxQueryLength { |
| 576 | limitErr := validation.LimitError(fmt.Sprintf(validation.ErrQueryTooLong, endTime.Sub(startTime), maxQueryLength)) |
| 577 | return nil, nil, limitErr |
| 578 | } |
| 579 | |
| 580 | if len(queriers) == 1 { |
| 581 | return queriers[0].LabelNames(ctx, hints, matchers...) |
| 582 | } |
| 583 | |
| 584 | var ( |
| 585 | g, _ = errgroup.WithContext(ctx) |
| 586 | sets = [][]string{} |
| 587 | warnings = annotations.Annotations(nil) |
| 588 | |
| 589 | resMtx sync.Mutex |
| 590 | ) |
| 591 | |
| 592 | for _, querier := range queriers { |
| 593 | // Need to reassign as the original variable will change and can't be relied on in a goroutine. |
| 594 | g.Go(func() error { |
| 595 | // NB: Names are sorted in Cortex already. |
| 596 | myNames, myWarnings, err := querier.LabelNames(ctx, hints, matchers...) |
| 597 | if err != nil { |
| 598 | return err |
| 599 | } |
| 600 | |
| 601 | resMtx.Lock() |
| 602 | sets = append(sets, myNames) |
| 603 | warnings.Merge(myWarnings) |
| 604 | resMtx.Unlock() |
| 605 | |
| 606 | return nil |
| 607 | }) |
| 608 | } |
| 609 | |
| 610 | if err := g.Wait(); err != nil { |
| 611 | return nil, nil, err |
nothing calls this directly
no test coverage detected