Tsdb/index sampling endpoint (#6347)

* index sampling endpoint

* fix bug in withTenantLabelMatcher

* show zero values in stats

* handles new errcase

* fixes comments
pull/6356/head
Owen Diehl 3 years ago committed by GitHub
parent 6cbcd6aa76
commit 3f4a663dbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 34
      docs/sources/api/_index.md
  2. 2
      pkg/loki/modules.go
  3. 32
      pkg/querier/http.go
  4. 28
      pkg/querier/multi_tenant_querier.go
  5. 36
      pkg/querier/querier.go
  6. 5
      pkg/querier/querier_mock_test.go
  7. 122
      pkg/storage/stores/shipper/indexgateway/indexgatewaypb/gateway.pb.go
  8. 8
      pkg/storage/stores/shipper/indexgateway/indexgatewaypb/gateway.proto
  9. 4
      pkg/storage/stores/tsdb/multitenant.go
  10. 10
      pkg/util/marshal/marshal.go

@ -28,6 +28,8 @@ These endpoints are exposed by the querier and the query frontend:
- [`GET /loki/api/v1/query_range`](#get-lokiapiv1query_range)
- [`GET /loki/api/v1/labels`](#get-lokiapiv1labels)
- [`GET /loki/api/v1/label/<name>/values`](#get-lokiapiv1labelnamevalues)
- [`GET /loki/api/v1/series`](#series)
- [`GET /loki/api/v1/index/stats`](#index-stats)
- [`GET /loki/api/v1/tail`](#get-lokiapiv1tail)
- [`POST /loki/api/v1/push`](#post-lokiapiv1push)
- [`GET /ready`](#get-ready)
@ -920,6 +922,38 @@ $ curl -s "http://localhost:3100/loki/api/v1/series" --data-urlencode 'match[]={
}
```
## Index Stats
The `/loki/api/v1/index/stats` endpoint can be used to query the index for the number of `streams`, `chunks`, `entries`, and `bytes` that a query resolves to.
URL query parameters:
- `query`: The [LogQL](../logql/) matchers to check (i.e. `{job="foo", env!="dev"}`)
- `start=<nanosecond Unix epoch>`: Start timestamp.
- `end=<nanosecond Unix epoch>`: End timestamp.
You can URL-encode these parameters directly in the request body by using the POST method and `Content-Type: application/x-www-form-urlencoded` header. This is useful when specifying a large or dynamic number of stream selectors that may breach server-side URL character limits.
Response:
```json
{
"streams": 100,
"chunks": 1000,
"entries": 5000,
"bytes": 100000,
}
```
It is an approximation with the following caveats:
* It does not include data from the ingesters
* It is a probabilistic technique
* streams/chunks which span multiple period configurations may be counted twice.
These make it generally more helpful for larger queries.
It can be used for better understanding the throughput requirements and data topology for a list of matchers over a period of time.
## Statistics
Query endpoints such as `/api/prom/query`, `/loki/api/v1/query` and `/loki/api/v1/query_range` return a set of statistics about the query execution. Those statistics allow users to understand the amount of data processed and at which speed.

@ -282,6 +282,7 @@ func (t *Loki) initQuerier() (services.Service, error) {
"/loki/api/v1/labels": http.HandlerFunc(t.querierAPI.LabelHandler),
"/loki/api/v1/label/{name}/values": http.HandlerFunc(t.querierAPI.LabelHandler),
"/loki/api/v1/series": http.HandlerFunc(t.querierAPI.SeriesHandler),
"/loki/api/v1/index/stats": http.HandlerFunc(t.querierAPI.IndexStatsHandler),
"/api/prom/query": httpMiddleware.Wrap(http.HandlerFunc(t.querierAPI.LogQueryHandler)),
"/api/prom/label": http.HandlerFunc(t.querierAPI.LabelHandler),
@ -675,6 +676,7 @@ func (t *Loki) initQueryFrontend() (_ services.Service, err error) {
t.Server.HTTP.Path("/loki/api/v1/labels").Methods("GET", "POST").Handler(frontendHandler)
t.Server.HTTP.Path("/loki/api/v1/label/{name}/values").Methods("GET", "POST").Handler(frontendHandler)
t.Server.HTTP.Path("/loki/api/v1/series").Methods("GET", "POST").Handler(frontendHandler)
t.Server.HTTP.Path("/loki/api/v1/index/stats").Methods("GET", "POST").Handler(frontendHandler)
t.Server.HTTP.Path("/api/prom/query").Methods("GET", "POST").Handler(frontendHandler)
t.Server.HTTP.Path("/api/prom/label").Methods("GET", "POST").Handler(frontendHandler)
t.Server.HTTP.Path("/api/prom/label/{name}/values").Methods("GET", "POST").Handler(frontendHandler)

@ -22,6 +22,7 @@ import (
"github.com/grafana/loki/pkg/logql/syntax"
"github.com/grafana/loki/pkg/logqlmodel"
"github.com/grafana/loki/pkg/logqlmodel/stats"
index_stats "github.com/grafana/loki/pkg/storage/stores/index/stats"
"github.com/grafana/loki/pkg/util/httpreq"
util_log "github.com/grafana/loki/pkg/util/log"
"github.com/grafana/loki/pkg/util/marshal"
@ -419,6 +420,37 @@ func (q *QuerierAPI) SeriesHandler(w http.ResponseWriter, r *http.Request) {
}
}
// IndexStatsHandler queries the index for the data statistics related to a query
func (q *QuerierAPI) IndexStatsHandler(w http.ResponseWriter, r *http.Request) {
// TODO(owen-d): use a specific type/validation instead
// of using range query parameters (superset)
req, err := loghttp.ParseRangeQuery(r)
if err != nil {
serverutil.WriteError(httpgrpc.Errorf(http.StatusBadRequest, err.Error()), w)
return
}
_, ctx := spanlogger.New(r.Context(), "query.IndexStats")
// TODO(owen-d): log metadata, record stats?
resp, err := q.querier.IndexStats(ctx, req)
if resp == nil {
// Some stores don't implement this
resp = &index_stats.Stats{}
}
if err != nil {
serverutil.WriteError(err, w)
return
}
err = marshal.WriteIndexStatsResponseJSON(resp, w)
if err != nil {
serverutil.WriteError(err, w)
return
}
}
// parseRegexQuery parses regex and query querystring from httpRequest and returns the combined LogQL query.
// This is used only to keep regexp query string support until it gets fully deprecated.
func parseRegexQuery(httpRequest *http.Request) (string, error) {

@ -10,9 +10,11 @@ import (
"github.com/grafana/dskit/tenant"
"github.com/grafana/loki/pkg/iter"
"github.com/grafana/loki/pkg/loghttp"
"github.com/grafana/loki/pkg/logproto"
"github.com/grafana/loki/pkg/logql"
"github.com/grafana/loki/pkg/logql/syntax"
"github.com/grafana/loki/pkg/storage/stores/index/stats"
)
const (
@ -158,6 +160,32 @@ func (q *MultiTenantQuerier) Series(ctx context.Context, req *logproto.SeriesReq
return logproto.MergeSeriesResponses(responses)
}
func (q *MultiTenantQuerier) IndexStats(ctx context.Context, req *loghttp.RangeQuery) (*stats.Stats, error) {
tenantIDs, err := tenant.TenantIDs(ctx)
if err != nil {
return nil, err
}
if len(tenantIDs) == 1 {
return q.Querier.IndexStats(ctx, req)
}
responses := make([]*stats.Stats, len(tenantIDs))
for i, id := range tenantIDs {
singleContext := user.InjectOrgID(ctx, id)
resp, err := q.Querier.IndexStats(singleContext, req)
if err != nil {
return nil, err
}
responses[i] = resp
}
merged := stats.MergeStats(responses...)
return &merged, nil
}
// removeTenantSelector filters the given tenant IDs based on any tenant ID filter the in passed selector.
func removeTenantSelector(params logql.SelectSampleParams, tenantIDs []string) (map[string]struct{}, syntax.Expr, error) {
expr, err := params.Expr()

@ -8,8 +8,6 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/grafana/loki/pkg/storage/stores/shipper/compactor/deletion"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
"github.com/prometheus/common/model"
@ -22,7 +20,10 @@ import (
"github.com/grafana/loki/pkg/loghttp"
"github.com/grafana/loki/pkg/logproto"
"github.com/grafana/loki/pkg/logql"
"github.com/grafana/loki/pkg/logql/syntax"
"github.com/grafana/loki/pkg/storage"
"github.com/grafana/loki/pkg/storage/stores/index/stats"
"github.com/grafana/loki/pkg/storage/stores/shipper/compactor/deletion"
listutil "github.com/grafana/loki/pkg/util"
"github.com/grafana/loki/pkg/util/spanlogger"
util_validation "github.com/grafana/loki/pkg/util/validation"
@ -83,6 +84,7 @@ type Querier interface {
Label(ctx context.Context, req *logproto.LabelRequest) (*logproto.LabelResponse, error)
Series(ctx context.Context, req *logproto.SeriesRequest) (*logproto.SeriesResponse, error)
Tail(ctx context.Context, req *logproto.TailRequest) (*Tailer, error)
IndexStats(ctx context.Context, req *loghttp.RangeQuery) (*stats.Stats, error)
}
// SingleTenantQuerier handles single tenant queries.
@ -677,3 +679,33 @@ func (q *SingleTenantQuerier) checkTailRequestLimit(ctx context.Context) error {
return nil
}
func (q *SingleTenantQuerier) IndexStats(ctx context.Context, req *loghttp.RangeQuery) (*stats.Stats, error) {
userID, err := tenant.TenantID(ctx)
if err != nil {
return nil, err
}
start, end, err := validateQueryTimeRangeLimits(ctx, userID, q.limits, req.Start, req.End)
if err != nil {
return nil, err
}
matchers, err := syntax.ParseMatchers(req.Query)
if err != nil {
return nil, err
}
// Enforce the query timeout while querying backends
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(q.cfg.QueryTimeout))
defer cancel()
return q.store.Stats(
ctx,
userID,
model.TimeFromUnixNano(start.UnixNano()),
model.TimeFromUnixNano(end.UnixNano()),
matchers...,
)
}

@ -19,6 +19,7 @@ import (
"github.com/grafana/loki/pkg/distributor/clientpool"
"github.com/grafana/loki/pkg/ingester/client"
"github.com/grafana/loki/pkg/iter"
"github.com/grafana/loki/pkg/loghttp"
"github.com/grafana/loki/pkg/logproto"
"github.com/grafana/loki/pkg/logql"
"github.com/grafana/loki/pkg/storage/chunk"
@ -486,3 +487,7 @@ func (q *querierMock) Series(ctx context.Context, req *logproto.SeriesRequest) (
func (q *querierMock) Tail(ctx context.Context, req *logproto.TailRequest) (*Tailer, error) {
return nil, errors.New("querierMock.Tail() has not been mocked")
}
func (q *querierMock) IndexStats(ctx context.Context, req *loghttp.RangeQuery) (*stats.Stats, error) {
return nil, nil
}

@ -660,10 +660,10 @@ func (m *IndexStatsRequest) GetMatchers() string {
}
type IndexStatsResponse struct {
Streams uint64 `protobuf:"varint,1,opt,name=streams,proto3" json:"streams,omitempty"`
Chunks uint64 `protobuf:"varint,2,opt,name=chunks,proto3" json:"chunks,omitempty"`
Bytes uint64 `protobuf:"varint,3,opt,name=bytes,proto3" json:"bytes,omitempty"`
Entries uint64 `protobuf:"varint,4,opt,name=entries,proto3" json:"entries,omitempty"`
Streams uint64 `protobuf:"varint,1,opt,name=streams,proto3" json:"streams"`
Chunks uint64 `protobuf:"varint,2,opt,name=chunks,proto3" json:"chunks"`
Bytes uint64 `protobuf:"varint,3,opt,name=bytes,proto3" json:"bytes"`
Entries uint64 `protobuf:"varint,4,opt,name=entries,proto3" json:"entries"`
}
func (m *IndexStatsResponse) Reset() { *m = IndexStatsResponse{} }
@ -748,63 +748,65 @@ func init() {
}
var fileDescriptor_33a7bd4603d312b2 = []byte{
// 894 bytes of a gzipped FileDescriptorProto
// 920 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0xdf, 0xb1, 0xb7, 0x4e, 0xfc, 0x62, 0xa0, 0x9d, 0xa2, 0x62, 0x2d, 0x74, 0x93, 0x2e, 0x12,
0x89, 0x90, 0xf0, 0x42, 0xc9, 0x05, 0x21, 0x0e, 0xa4, 0x40, 0x14, 0x51, 0xaa, 0x32, 0x81, 0x0a,
0x4e, 0x68, 0xec, 0x8c, 0x77, 0x97, 0xec, 0x7a, 0xb6, 0xb3, 0xb3, 0x4d, 0x73, 0xe3, 0x0b, 0x20,
0xf1, 0x31, 0xf8, 0x14, 0x80, 0x38, 0xf5, 0x18, 0x6e, 0x15, 0x87, 0x8a, 0x38, 0x17, 0x8e, 0xfd,
0x08, 0x68, 0xdf, 0xfe, 0xb5, 0x9d, 0x04, 0xa9, 0xcd, 0x25, 0x27, 0xcf, 0xfb, 0xbd, 0x3f, 0xf3,
0x7e, 0x33, 0x6f, 0x7e, 0x5e, 0xf8, 0x2c, 0xde, 0xf7, 0xdc, 0x44, 0x4b, 0xc5, 0x3d, 0x81, 0xbf,
0x22, 0x71, 0x13, 0x3f, 0x88, 0x63, 0xa1, 0xdc, 0x60, 0xb2, 0x27, 0x1e, 0x7b, 0x5c, 0x8b, 0x03,
0x7e, 0x38, 0x63, 0xc4, 0x43, 0xb7, 0x58, 0x0d, 0x62, 0x25, 0xb5, 0xa4, 0xaf, 0xce, 0x7a, 0xad,
0xf7, 0xbc, 0x40, 0xfb, 0xe9, 0x70, 0x30, 0x92, 0x91, 0xeb, 0x49, 0x4f, 0xba, 0x18, 0x36, 0x4c,
0xc7, 0x68, 0xa1, 0x81, 0xab, 0x3c, 0xdd, 0x7a, 0x33, 0x6b, 0x22, 0x94, 0x5e, 0xee, 0x28, 0x17,
0xb9, 0xd3, 0xf9, 0xb9, 0x05, 0xab, 0x77, 0xf9, 0x50, 0x84, 0x0f, 0x78, 0x98, 0x8a, 0xe4, 0x0b,
0xa9, 0xbe, 0x12, 0x5a, 0x05, 0xa3, 0x7b, 0x3c, 0x12, 0x4c, 0x3c, 0x4c, 0x45, 0xa2, 0xe9, 0x2a,
0xac, 0x44, 0x08, 0xfe, 0x30, 0xe1, 0x91, 0xe8, 0x93, 0x35, 0xb2, 0xd1, 0x65, 0x10, 0x55, 0x71,
0xf4, 0x26, 0x40, 0x98, 0xd5, 0xc8, 0xfd, 0x2d, 0xf4, 0x77, 0x11, 0x41, 0xf7, 0x1d, 0x30, 0xc7,
0x4a, 0x46, 0xfd, 0xf6, 0x1a, 0xd9, 0x68, 0x6f, 0xb9, 0x4f, 0x9e, 0xad, 0x1a, 0x7f, 0x3f, 0x5b,
0x5d, 0x6f, 0xb0, 0x88, 0x95, 0x8c, 0x84, 0xf6, 0x45, 0x9a, 0xb8, 0x23, 0x19, 0x45, 0x72, 0xe2,
0x46, 0x72, 0x4f, 0x84, 0x83, 0x6f, 0x82, 0x48, 0x30, 0x4c, 0xa6, 0x3b, 0xb0, 0xa4, 0x7d, 0x25,
0x53, 0xcf, 0xef, 0x9b, 0x2f, 0x56, 0xa7, 0xcc, 0xa7, 0x16, 0x2c, 0x47, 0x5c, 0x8f, 0x7c, 0xa1,
0x92, 0xfe, 0x15, 0x6c, 0xb6, 0xb2, 0x9d, 0xbf, 0x08, 0xd8, 0x77, 0xcb, 0xce, 0x5f, 0xf0, 0x38,
0x4a, 0xbe, 0xad, 0x0b, 0xe2, 0xdb, 0x7e, 0x39, 0xbe, 0xce, 0x3a, 0xbc, 0x82, 0x94, 0x98, 0x48,
0x62, 0x39, 0x49, 0x04, 0xbd, 0x01, 0x9d, 0x47, 0x78, 0xdd, 0x7d, 0xb2, 0xd6, 0xde, 0xe8, 0xb2,
0xc2, 0x72, 0xfe, 0x20, 0x40, 0xb7, 0x85, 0xbe, 0xe3, 0xa7, 0x93, 0x7d, 0x26, 0xc6, 0x25, 0xe1,
0x92, 0x0f, 0xb9, 0x20, 0x3e, 0xad, 0x0b, 0xbc, 0xbf, 0xf6, 0xdc, 0xfd, 0x7d, 0x02, 0xd7, 0x67,
0x18, 0x14, 0x8c, 0xdf, 0x01, 0x53, 0x89, 0x71, 0xce, 0x77, 0xe5, 0x36, 0x1d, 0x54, 0xaf, 0xa0,
0x8a, 0x44, 0xbf, 0xf3, 0x1b, 0x81, 0xab, 0xdb, 0x42, 0xef, 0x0a, 0x15, 0x88, 0xe4, 0x32, 0xf2,
0xdf, 0x81, 0x6b, 0x8d, 0xfe, 0x0b, 0xf6, 0x9b, 0xd0, 0x49, 0x10, 0x29, 0xf8, 0xdf, 0x18, 0xcc,
0x2a, 0xca, 0x20, 0x8f, 0xdf, 0x32, 0xb3, 0x96, 0x58, 0x11, 0xeb, 0xc4, 0xd0, 0xc9, 0x71, 0x3a,
0x86, 0x0e, 0xbe, 0xe6, 0x32, 0xff, 0x7a, 0x7d, 0x7e, 0x38, 0x58, 0xf7, 0x79, 0xa0, 0xb6, 0x3e,
0x2a, 0xf8, 0x7c, 0xd0, 0x54, 0x27, 0xc5, 0xc7, 0x7c, 0xc2, 0xdd, 0x50, 0xee, 0x07, 0x6e, 0x53,
0x86, 0xf2, 0xbc, 0x4f, 0xf7, 0x78, 0xac, 0x85, 0x62, 0x45, 0x75, 0xe7, 0x7b, 0xa0, 0x5f, 0xa7,
0x42, 0x1d, 0xee, 0x64, 0xdd, 0x55, 0xdd, 0x5b, 0xb0, 0x8c, 0xe8, 0x97, 0xe2, 0xb0, 0x78, 0x6c,
0x95, 0x4d, 0xd7, 0xc1, 0x54, 0xf2, 0x20, 0xe9, 0xb7, 0x8a, 0xbe, 0xe6, 0x78, 0x31, 0x79, 0xc0,
0x30, 0xc0, 0xf9, 0x18, 0xda, 0x4c, 0x1e, 0x50, 0x1b, 0x40, 0xf1, 0x89, 0x27, 0x50, 0xed, 0xb0,
0x5a, 0x8f, 0x35, 0x10, 0xfa, 0x3a, 0x5c, 0xc1, 0xb7, 0x80, 0x77, 0xd4, 0x63, 0xb9, 0x91, 0x1d,
0x6a, 0xb3, 0xaf, 0x7c, 0x2a, 0x36, 0x61, 0x29, 0x03, 0xeb, 0x53, 0xb5, 0xe6, 0x77, 0xc7, 0x70,
0x4c, 0x64, 0x65, 0x68, 0x36, 0x60, 0x50, 0xe3, 0xf4, 0x2d, 0xe8, 0x6a, 0x3e, 0x0c, 0xc5, 0xbd,
0x5a, 0x49, 0x6a, 0x20, 0xf3, 0xfa, 0x3c, 0xf1, 0x1f, 0x54, 0x1d, 0x75, 0x59, 0x0d, 0xd0, 0x77,
0xe1, 0x6a, 0xdd, 0xf9, 0x7d, 0x25, 0xc6, 0xc1, 0x63, 0x1c, 0x87, 0x1e, 0x5b, 0xc0, 0xe9, 0x06,
0xbc, 0x56, 0x63, 0xbb, 0x9a, 0x2b, 0x8d, 0x2a, 0xda, 0x63, 0xf3, 0x70, 0x76, 0x42, 0x48, 0xfa,
0xf3, 0x87, 0x29, 0x0f, 0x51, 0x1e, 0x7b, 0xac, 0x81, 0x38, 0xbf, 0x13, 0xb8, 0x86, 0x04, 0x76,
0x35, 0xd7, 0x97, 0xf2, 0x89, 0x3c, 0x02, 0xda, 0x24, 0x50, 0x4c, 0x59, 0x1f, 0x96, 0x12, 0xad,
0x04, 0x8f, 0x12, 0x24, 0x61, 0xb2, 0xd2, 0xcc, 0xd4, 0x72, 0x94, 0xa9, 0x44, 0x82, 0x5d, 0x99,
0xac, 0xb0, 0xb2, 0x59, 0x19, 0x1e, 0x6a, 0x91, 0x6f, 0x60, 0xb2, 0xdc, 0xc8, 0xea, 0x88, 0x89,
0xc6, 0xb1, 0x30, 0xf3, 0x3a, 0x85, 0x79, 0xfb, 0x4f, 0x13, 0x7a, 0xb8, 0xf1, 0x76, 0x3e, 0x21,
0xf4, 0x5b, 0x80, 0x7a, 0xac, 0xe8, 0xad, 0xf9, 0xf1, 0x59, 0x18, 0x39, 0xcb, 0x39, 0x2f, 0x24,
0xe7, 0xf1, 0x3e, 0xa1, 0xdf, 0xc1, 0x4a, 0x43, 0x02, 0xe9, 0x42, 0xd2, 0xa2, 0xc2, 0x5b, 0x6f,
0x9f, 0x1b, 0x93, 0x57, 0x76, 0x0c, 0xca, 0xa0, 0x5b, 0x89, 0x0b, 0x5d, 0x3b, 0x25, 0x67, 0x46,
0x37, 0xad, 0x5b, 0xe7, 0x44, 0x54, 0x35, 0x7f, 0x84, 0x37, 0xce, 0xf8, 0xbf, 0xa5, 0x83, 0xf9,
0xfc, 0xf3, 0xff, 0x98, 0xad, 0x9b, 0xa7, 0xc6, 0x37, 0xf6, 0x0a, 0xa1, 0x7f, 0xd6, 0xb7, 0x0e,
0x75, 0x4f, 0x4d, 0x3e, 0xfb, 0xab, 0xe8, 0xff, 0x77, 0xdb, 0x85, 0xe5, 0x8c, 0x70, 0x36, 0x65,
0x8b, 0x97, 0xbb, 0xf0, 0x84, 0x16, 0x2f, 0x77, 0x71, 0x48, 0x1d, 0x63, 0x6b, 0xf3, 0xe8, 0xd8,
0x36, 0x9e, 0x1e, 0xdb, 0xc6, 0xf3, 0x63, 0x9b, 0xfc, 0x34, 0xb5, 0xc9, 0xaf, 0x53, 0x9b, 0x3c,
0x99, 0xda, 0xe4, 0x68, 0x6a, 0x93, 0x7f, 0xa6, 0x36, 0xf9, 0x77, 0x6a, 0x1b, 0xcf, 0xa7, 0x36,
0xf9, 0xe5, 0xc4, 0x36, 0x8e, 0x4e, 0x6c, 0xe3, 0xe9, 0x89, 0x6d, 0x0c, 0x3b, 0x28, 0xba, 0x1f,
0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0x62, 0xcc, 0xc6, 0x11, 0x90, 0x0a, 0x00, 0x00,
0x14, 0xf7, 0xd8, 0x5b, 0x27, 0x7e, 0x31, 0xd0, 0x4e, 0x51, 0xb1, 0x0c, 0x5d, 0xa7, 0x8b, 0x20,
0x11, 0x12, 0x5e, 0x28, 0xb9, 0x20, 0xc4, 0x01, 0x17, 0x88, 0x22, 0x4a, 0x55, 0x26, 0x50, 0xc1,
0x09, 0x8d, 0x9d, 0xf1, 0xee, 0x92, 0x5d, 0xcf, 0x76, 0x76, 0x96, 0x34, 0x37, 0xbe, 0x00, 0x12,
0xdf, 0x02, 0x3e, 0x05, 0x20, 0x4e, 0x3d, 0x86, 0x5b, 0xc5, 0xc1, 0x22, 0xce, 0x05, 0xe5, 0xd4,
0x8f, 0x80, 0xf6, 0xed, 0x5f, 0xdb, 0x49, 0x90, 0x4a, 0x2e, 0x3d, 0xed, 0xbc, 0xdf, 0x7b, 0x6f,
0xe6, 0xf7, 0x9b, 0x79, 0xf3, 0x66, 0xe1, 0xe3, 0x70, 0xdf, 0xb1, 0x23, 0x2d, 0x15, 0x77, 0x04,
0x7e, 0x45, 0x64, 0x47, 0xae, 0x17, 0x86, 0x42, 0xd9, 0xde, 0x64, 0x4f, 0x3c, 0x72, 0xb8, 0x16,
0x07, 0xfc, 0x70, 0xce, 0x08, 0x87, 0x76, 0x36, 0xea, 0x87, 0x4a, 0x6a, 0x49, 0x5f, 0x9c, 0xf7,
0x76, 0xdf, 0x76, 0x3c, 0xed, 0xc6, 0xc3, 0xfe, 0x48, 0x06, 0xb6, 0x23, 0x1d, 0x69, 0x63, 0xd8,
0x30, 0x1e, 0xa3, 0x85, 0x06, 0x8e, 0xd2, 0xf4, 0xee, 0xab, 0x09, 0x09, 0x5f, 0x3a, 0xa9, 0x23,
0x1f, 0xa4, 0x4e, 0xeb, 0xc7, 0x3a, 0xf4, 0xee, 0xf2, 0xa1, 0xf0, 0x1f, 0x70, 0x3f, 0x16, 0xd1,
0xa7, 0x52, 0x7d, 0x2e, 0xb4, 0xf2, 0x46, 0xf7, 0x78, 0x20, 0x98, 0x78, 0x18, 0x8b, 0x48, 0xd3,
0x1e, 0xac, 0x05, 0x08, 0x7e, 0x3b, 0xe1, 0x81, 0xe8, 0x90, 0x75, 0xb2, 0xd9, 0x62, 0x10, 0x14,
0x71, 0xf4, 0x26, 0x80, 0x9f, 0xcc, 0x91, 0xfa, 0xeb, 0xe8, 0x6f, 0x21, 0x82, 0xee, 0x3b, 0x60,
0x8c, 0x95, 0x0c, 0x3a, 0x8d, 0x75, 0xb2, 0xd9, 0x18, 0xd8, 0x8f, 0xa7, 0xbd, 0xda, 0x5f, 0xd3,
0xde, 0x46, 0x45, 0x45, 0xa8, 0x64, 0x20, 0xb4, 0x2b, 0xe2, 0xc8, 0x1e, 0xc9, 0x20, 0x90, 0x13,
0x3b, 0x90, 0x7b, 0xc2, 0xef, 0x7f, 0xe9, 0x05, 0x82, 0x61, 0x32, 0xdd, 0x81, 0x15, 0xed, 0x2a,
0x19, 0x3b, 0x6e, 0xc7, 0x78, 0xb6, 0x79, 0xf2, 0x7c, 0xda, 0x85, 0xd5, 0x80, 0xeb, 0x91, 0x2b,
0x54, 0xd4, 0xb9, 0x82, 0x64, 0x0b, 0xdb, 0xfa, 0x93, 0x80, 0x79, 0x37, 0x67, 0xfe, 0x8c, 0xdb,
0x91, 0xeb, 0xad, 0x5f, 0x92, 0xde, 0xc6, 0xff, 0xd3, 0x6b, 0x6d, 0xc0, 0x0b, 0x28, 0x89, 0x89,
0x28, 0x94, 0x93, 0x48, 0xd0, 0x1b, 0xd0, 0xfc, 0x1e, 0x8f, 0xbb, 0x43, 0xd6, 0x1b, 0x9b, 0x2d,
0x96, 0x59, 0xd6, 0xef, 0x04, 0xe8, 0xb6, 0xd0, 0x77, 0xdc, 0x78, 0xb2, 0xcf, 0xc4, 0x38, 0x17,
0x9c, 0xeb, 0x21, 0x97, 0xa4, 0xa7, 0x7e, 0x89, 0xe7, 0xd7, 0x58, 0x38, 0xbf, 0x0f, 0xe1, 0xfa,
0x9c, 0x82, 0x4c, 0xf1, 0x9b, 0x60, 0x28, 0x31, 0x4e, 0xf5, 0xae, 0xdd, 0xa6, 0xfd, 0xe2, 0x16,
0x14, 0x91, 0xe8, 0xb7, 0x7e, 0x25, 0x70, 0x75, 0x5b, 0xe8, 0x5d, 0xa1, 0x3c, 0x11, 0x3d, 0x8f,
0xfa, 0x77, 0xe0, 0x5a, 0x85, 0x7f, 0xa6, 0x7e, 0x0b, 0x9a, 0x11, 0x22, 0x99, 0xfe, 0x1b, 0xfd,
0xf9, 0x8e, 0xd2, 0x4f, 0xe3, 0x07, 0x46, 0x42, 0x89, 0x65, 0xb1, 0x56, 0x08, 0xcd, 0x14, 0xa7,
0x63, 0x68, 0xe2, 0x6d, 0xce, 0xf3, 0xaf, 0x97, 0xfb, 0x87, 0x85, 0x75, 0x9f, 0x7b, 0x6a, 0xf0,
0x7e, 0xa6, 0xe7, 0xdd, 0x6a, 0x77, 0x52, 0x7c, 0xcc, 0x27, 0xdc, 0xf6, 0xe5, 0xbe, 0x67, 0x57,
0xdb, 0x50, 0x9a, 0xf7, 0xd1, 0x1e, 0x0f, 0xb5, 0x50, 0x2c, 0x9b, 0xdd, 0xfa, 0x06, 0xe8, 0x17,
0xb1, 0x50, 0x87, 0x3b, 0x09, 0xbb, 0x82, 0x7d, 0x17, 0x56, 0x11, 0xfd, 0x4c, 0x1c, 0x66, 0x97,
0xad, 0xb0, 0xe9, 0x06, 0x18, 0x4a, 0x1e, 0x44, 0x9d, 0x7a, 0xc6, 0x6b, 0x41, 0x17, 0x93, 0x07,
0x0c, 0x03, 0xac, 0x0f, 0xa0, 0xc1, 0xe4, 0x01, 0x35, 0x01, 0x14, 0x9f, 0x38, 0x02, 0xbb, 0x1d,
0xce, 0xd6, 0x66, 0x15, 0x84, 0xbe, 0x0c, 0x57, 0xf0, 0x2e, 0xe0, 0x19, 0xb5, 0x59, 0x6a, 0x24,
0x9b, 0x5a, 0xe5, 0x95, 0x56, 0xc5, 0x16, 0xac, 0x24, 0x60, 0xb9, 0xab, 0xdd, 0xc5, 0xd5, 0x31,
0x1c, 0x13, 0x59, 0x1e, 0x9a, 0x14, 0x18, 0x94, 0x38, 0x7d, 0x0d, 0x5a, 0x9a, 0x0f, 0x7d, 0x71,
0xaf, 0xec, 0x24, 0x25, 0x90, 0x78, 0x5d, 0x1e, 0xb9, 0x0f, 0x0a, 0x46, 0x2d, 0x56, 0x02, 0xf4,
0x2d, 0xb8, 0x5a, 0x32, 0xbf, 0xaf, 0xc4, 0xd8, 0x7b, 0x84, 0xe5, 0xd0, 0x66, 0x4b, 0x38, 0xdd,
0x84, 0x97, 0x4a, 0x6c, 0x57, 0x73, 0xa5, 0xb1, 0x8b, 0xb6, 0xd9, 0x22, 0x9c, 0xec, 0x10, 0x8a,
0xfe, 0xe4, 0x61, 0xcc, 0x7d, 0x6c, 0x8f, 0x6d, 0x56, 0x41, 0xac, 0xdf, 0x08, 0x5c, 0x43, 0x01,
0xbb, 0x9a, 0xeb, 0xe7, 0xf2, 0x8a, 0xfc, 0x4c, 0x80, 0x56, 0x15, 0x64, 0x65, 0xf6, 0x06, 0xac,
0x44, 0x5a, 0x09, 0x1e, 0x44, 0xa8, 0xc2, 0x18, 0xac, 0x9d, 0x4e, 0x7b, 0x39, 0xc4, 0xf2, 0x01,
0xb5, 0xa0, 0x39, 0x4a, 0x7a, 0x46, 0x84, 0x1c, 0x8d, 0x01, 0x9c, 0x4e, 0x7b, 0x19, 0xc2, 0xb2,
0x2f, 0xed, 0xc1, 0x95, 0xe1, 0xa1, 0x16, 0xe9, 0xd2, 0xc6, 0xa0, 0x75, 0x3a, 0xed, 0xa5, 0x00,
0x4b, 0x3f, 0xc9, 0x5a, 0x62, 0xa2, 0xb1, 0x76, 0x8c, 0x72, 0xad, 0x0c, 0x62, 0xf9, 0xe0, 0xf6,
0x1f, 0x06, 0xb4, 0x91, 0xe9, 0x76, 0x5a, 0x53, 0xf4, 0x2b, 0x80, 0xb2, 0x10, 0xe9, 0xad, 0xc5,
0x82, 0x5b, 0x2a, 0xd2, 0xae, 0x75, 0x51, 0x48, 0x2a, 0xfc, 0x1d, 0x42, 0xbf, 0x86, 0xb5, 0x4a,
0xd3, 0xa4, 0x4b, 0x49, 0xcb, 0x6f, 0x42, 0xf7, 0xf5, 0x0b, 0x63, 0xd2, 0x99, 0xad, 0x1a, 0x65,
0xd0, 0x2a, 0xda, 0x11, 0x5d, 0x3f, 0x23, 0x67, 0xae, 0xd3, 0x76, 0x6f, 0x5d, 0x10, 0x51, 0xcc,
0xf9, 0x1d, 0xbc, 0x72, 0xce, 0x0b, 0x4d, 0xfb, 0x8b, 0xf9, 0x17, 0x3f, 0xe5, 0xdd, 0x9b, 0x67,
0xc6, 0x57, 0xd6, 0xf2, 0xa1, 0x73, 0xde, 0xdf, 0x11, 0xb5, 0xcf, 0x4c, 0x3e, 0xff, 0x3f, 0xea,
0xbf, 0x57, 0xdb, 0x85, 0xd5, 0x44, 0x70, 0x52, 0x96, 0xcb, 0x87, 0xbb, 0x74, 0xe9, 0x96, 0x0f,
0x77, 0xb9, 0xaa, 0xad, 0xda, 0x60, 0xeb, 0xe8, 0xd8, 0xac, 0x3d, 0x39, 0x36, 0x6b, 0x4f, 0x8f,
0x4d, 0xf2, 0xc3, 0xcc, 0x24, 0xbf, 0xcc, 0x4c, 0xf2, 0x78, 0x66, 0x92, 0xa3, 0x99, 0x49, 0xfe,
0x9e, 0x99, 0xe4, 0x9f, 0x99, 0x59, 0x7b, 0x3a, 0x33, 0xc9, 0x4f, 0x27, 0x66, 0xed, 0xe8, 0xc4,
0xac, 0x3d, 0x39, 0x31, 0x6b, 0xc3, 0x26, 0xb6, 0xe9, 0xf7, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff,
0x79, 0x39, 0x20, 0x44, 0xc2, 0x0a, 0x00, 0x00,
}
func (this *LabelValuesForMetricNameRequest) Equal(that interface{}) bool {

@ -125,8 +125,8 @@ message IndexStatsRequest {
}
message IndexStatsResponse {
uint64 streams = 1;
uint64 chunks = 2;
uint64 bytes = 3;
uint64 entries = 4;
uint64 streams = 1 [(gogoproto.jsontag) = "streams"];
uint64 chunks = 2 [(gogoproto.jsontag) = "chunks"];
uint64 bytes = 3 [(gogoproto.jsontag) = "bytes"];
uint64 entries = 4 [(gogoproto.jsontag) = "entries"];
}

@ -29,8 +29,8 @@ func NewMultiTenantIndex(idx Index) *MultiTenantIndex {
func withTenantLabelMatcher(userID string, matchers []*labels.Matcher) []*labels.Matcher {
cpy := make([]*labels.Matcher, len(matchers)+1)
copy(cpy, matchers)
cpy = append(cpy, labels.MustNewMatcher(labels.MatchEqual, TenantLabel, userID))
cpy[0] = labels.MustNewMatcher(labels.MatchEqual, TenantLabel, userID)
copy(cpy[1:], matchers)
return cpy
}

@ -5,14 +5,14 @@ package marshal
import (
"io"
"github.com/grafana/loki/pkg/logqlmodel"
"github.com/gorilla/websocket"
jsoniter "github.com/json-iterator/go"
"github.com/grafana/loki/pkg/loghttp"
legacy "github.com/grafana/loki/pkg/loghttp/legacy"
"github.com/grafana/loki/pkg/logproto"
"github.com/grafana/loki/pkg/logqlmodel"
"github.com/grafana/loki/pkg/storage/stores/index/stats"
)
// WriteQueryResponseJSON marshals the promql.Value to v1 loghttp JSON and then
@ -86,3 +86,9 @@ type seriesResponseAdapter struct {
Status string `json:"status"`
Data []map[string]string `json:"data"`
}
// WriteIndexStatsResponseJSON marshals a gatewaypb.Stats to JSON and then
// writes it to the provided io.Writer.
func WriteIndexStatsResponseJSON(r *stats.Stats, w io.Writer) error {
return jsoniter.NewEncoder(w).Encode(r)
}

Loading…
Cancel
Save