Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
loki/pkg/loghttp/series.go

78 lines
1.7 KiB

package loghttp
import (
"net/http"
"sort"
"strings"
"github.com/grafana/loki/pkg/logproto"
"github.com/grafana/loki/pkg/logql"
)
type SeriesResponse struct {
Status string `json:"status"`
Data []LabelSet `json:"data"`
}
func ParseSeriesQuery(r *http.Request) (*logproto.SeriesRequest, error) {
start, end, err := bounds(r)
if err != nil {
return nil, err
}
xs := r.Form["match"]
// Prometheus encodes with `match[]`; we use both for compatibility.
ys := r.Form["match[]"]
deduped := union(xs, ys)
sort.Strings(deduped)
// Special case to allow for an empty label matcher `{}` in a Series query,
// we support either not specifying the `match` query parameter at all or specifying it with a single `{}`
// empty label matcher, we treat the latter case here as if no `match` was supplied at all.
if len(deduped) == 1 {
matcher := deduped[0]
matcher = strings.Replace(matcher, " ", "", -1)
if matcher == "{}" {
deduped = deduped[:0]
}
}
return &logproto.SeriesRequest{
Start: start,
End: end,
Groups: deduped,
Shards: shards(r),
}, nil
}
func union(cols ...[]string) []string {
m := map[string]struct{}{}
for _, col := range cols {
for _, s := range col {
m[s] = struct{}{}
}
}
res := make([]string, 0, len(m))
for k := range m {
res = append(res, k)
}
return res
}
func ParseAndValidateSeriesQuery(r *http.Request) (*logproto.SeriesRequest, error) {
req, err := ParseSeriesQuery(r)
if err != nil {
return nil, err
}
// ensure matchers are valid before fanning out to ingesters/store as well as returning valuable parsing errors
// instead of 500s
if _, err = logql.MatchForSeriesRequest(req.Groups); err != nil {
return nil, err
}
return req, nil
}