Skip to content

Commit

Permalink
feat: Detected labels - get and filter labels from ingesters (#12432)
Browse files Browse the repository at this point in the history
  • Loading branch information
shantanualsi authored Apr 3, 2024
1 parent bf0dd9d commit 643f353
Show file tree
Hide file tree
Showing 7 changed files with 1,180 additions and 295 deletions.
37 changes: 37 additions & 0 deletions pkg/ingester/ingester.go
Original file line number Diff line number Diff line change
Expand Up @@ -1371,3 +1371,40 @@ func (i *Ingester) GetDetectedFields(_ context.Context, _ *logproto.DetectedFiel
},
}, nil
}

// GetDetectedLabels returns map of detected labels and unique values from this ingester
func (i *Ingester) GetDetectedLabels(ctx context.Context, req *logproto.DetectedLabelsRequest) (*logproto.LabelToValuesResponse, error) {
userID, err := tenant.TenantID(ctx)
if err != nil {
return nil, err
}

instance, err := i.GetOrCreateInstance(userID)
if err != nil {
return nil, err
}
var matchers []*labels.Matcher
if req.Query != "" {
matchers, err := syntax.ParseMatchers(req.Query, true)
if err != nil {
return nil, err
}
level.Info(i.logger).Log("msg", matchers)
}

labelMap, err := instance.LabelsWithValues(ctx, *req.Start, matchers...)

if err != nil {
return nil, err
}
result := make(map[string]*logproto.UniqueLabelValues)
for label, values := range labelMap {
uniqueValues := make([]string, len(values))
for v := range values {
uniqueValues = append(uniqueValues, v)
}

result[label] = &logproto.UniqueLabelValues{Values: uniqueValues}
}
return &logproto.LabelToValuesResponse{Labels: result}, nil
}
28 changes: 28 additions & 0 deletions pkg/ingester/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ func (i *instance) Label(ctx context.Context, req *logproto.LabelRequest, matche
}

labels := util.NewUniqueStrings(0)
// (shantanu) can create a map here to store label names::values and count the unique values
// just return a string to int map
err := i.forMatchingStreams(ctx, *req.Start, matchers, nil, func(s *stream) error {
for _, label := range s.labels {
if req.Values && label.Name == req.Name {
Expand All @@ -583,6 +585,32 @@ func (i *instance) Label(ctx context.Context, req *logproto.LabelRequest, matche
}, nil
}

type UniqueValues map[string]struct{}

// LabelsWithValues returns the label names with all the unique values depending on the request
func (i *instance) LabelsWithValues(ctx context.Context, startTime time.Time, matchers ...*labels.Matcher) (map[string]UniqueValues, error) {
// TODO (shantanu): Figure out how to get the label names from index directly when no matchers are given.

labelMap := make(map[string]UniqueValues)
err := i.forMatchingStreams(ctx, startTime, matchers, nil, func(s *stream) error {
for _, label := range s.labels {
v, exists := labelMap[label.Name]
if !exists {
v = make(map[string]struct{})
}
if label.Value != "" {
v[label.Value] = struct{}{}
}
labelMap[label.Name] = v
}
return nil
})
if err != nil {
return nil, err
}
return labelMap, nil
}

func (i *instance) Series(ctx context.Context, req *logproto.SeriesRequest) (*logproto.SeriesResponse, error) {
groups, err := logql.MatchForSeriesRequest(req.GetGroups())
if err != nil {
Expand Down
Loading

0 comments on commit 643f353

Please sign in to comment.