(r *http.Request)
| 971 | ) |
| 972 | |
| 973 | func (api *API) series(r *http.Request) (result apiFuncResult) { |
| 974 | ctx := r.Context() |
| 975 | |
| 976 | if err := r.ParseForm(); err != nil { |
| 977 | return apiFuncResult{nil, &apiError{errorBadData, fmt.Errorf("error parsing form values: %w", err)}, nil, nil} |
| 978 | } |
| 979 | if len(r.Form["match[]"]) == 0 { |
| 980 | return apiFuncResult{nil, &apiError{errorBadData, errors.New("no match[] parameter provided")}, nil, nil} |
| 981 | } |
| 982 | |
| 983 | limit, err := parseLimitParam(r.FormValue("limit")) |
| 984 | if err != nil { |
| 985 | return invalidParamError(err, "limit") |
| 986 | } |
| 987 | |
| 988 | start, err := parseTimeParam(r, "start", MinTime) |
| 989 | if err != nil { |
| 990 | return invalidParamError(err, "start") |
| 991 | } |
| 992 | end, err := parseTimeParam(r, "end", MaxTime) |
| 993 | if err != nil { |
| 994 | return invalidParamError(err, "end") |
| 995 | } |
| 996 | |
| 997 | matcherSets, err := api.parseMatchersParam(r.Form["match[]"]) |
| 998 | if err != nil { |
| 999 | return invalidParamError(err, "match[]") |
| 1000 | } |
| 1001 | |
| 1002 | q, err := api.Queryable.Querier(timestamp.FromTime(start), timestamp.FromTime(end)) |
| 1003 | if err != nil { |
| 1004 | return apiFuncResult{nil, returnAPIError(err), nil, nil} |
| 1005 | } |
| 1006 | // From now on, we must only return with a finalizer in the result (to |
| 1007 | // be called by the caller) or call q.Close ourselves (which is required |
| 1008 | // in the case of a panic). |
| 1009 | defer func() { |
| 1010 | if result.finalizer == nil { |
| 1011 | q.Close() |
| 1012 | } |
| 1013 | }() |
| 1014 | closer := func() { |
| 1015 | q.Close() |
| 1016 | } |
| 1017 | |
| 1018 | hints := &storage.SelectHints{ |
| 1019 | Start: timestamp.FromTime(start), |
| 1020 | End: timestamp.FromTime(end), |
| 1021 | Func: "series", // There is no series function, this token is used for lookups that don't need samples. |
| 1022 | Limit: toHintLimit(limit), |
| 1023 | } |
| 1024 | var set storage.SeriesSet |
| 1025 | |
| 1026 | if len(matcherSets) > 1 { |
| 1027 | var sets []storage.SeriesSet |
| 1028 | for _, mset := range matcherSets { |
| 1029 | // We need to sort this select results to merge (deduplicate) the series sets later. |
| 1030 | s := q.Select(ctx, true, hints, mset...) |
nothing calls this directly
no test coverage detected