diff --git a/docs/sources/reference/loki-http-api.md b/docs/sources/reference/loki-http-api.md index e72a03ba51b0a..c9df1a2896d74 100644 --- a/docs/sources/reference/loki-http-api.md +++ b/docs/sources/reference/loki-http-api.md @@ -627,6 +627,7 @@ It accepts the following query parameters in the URL: - `start`: The start time for the query as a nanosecond Unix epoch. Defaults to 6 hours ago. - `end`: The end time for the query as a nanosecond Unix epoch. Defaults to now. - `since`: A `duration` used to calculate `start` relative to `end`. If `end` is in the future, `start` is calculated as this duration before now. Any value specified for `start` supersedes this parameter. +- `query`: A set of log stream selector that selects the streams to match and return label names. Example: `{"app": "myapp", "environment": "dev"}` In microservices mode, `/loki/api/v1/labels` is exposed by the querier. diff --git a/pkg/indexgateway/gateway.go b/pkg/indexgateway/gateway.go index 81f98662a1c3e..e2850e8c9317f 100644 --- a/pkg/indexgateway/gateway.go +++ b/pkg/indexgateway/gateway.go @@ -292,7 +292,22 @@ func (g *Gateway) LabelNamesForMetricName(ctx context.Context, req *logproto.Lab if err != nil { return nil, err } - names, err := g.indexQuerier.LabelNamesForMetricName(ctx, instanceID, req.From, req.Through, req.MetricName) + var matchers []*labels.Matcher + // An empty matchers string cannot be parsed, + // therefore we check the string representation of the matchers. + if req.Matchers != syntax.EmptyMatchers { + expr, err := syntax.ParseExprWithoutValidation(req.Matchers) + if err != nil { + return nil, err + } + + matcherExpr, ok := expr.(*syntax.MatchersExpr) + if !ok { + return nil, fmt.Errorf("invalid label matchers found of type %T", expr) + } + matchers = matcherExpr.Mts + } + names, err := g.indexQuerier.LabelNamesForMetricName(ctx, instanceID, req.From, req.Through, req.MetricName, matchers...) if err != nil { return nil, err } @@ -308,7 +323,7 @@ func (g *Gateway) LabelValuesForMetricName(ctx context.Context, req *logproto.La } var matchers []*labels.Matcher // An empty matchers string cannot be parsed, - // therefore we check the string representation of the the matchers. + // therefore we check the string representation of the matchers. if req.Matchers != syntax.EmptyMatchers { expr, err := syntax.ParseExprWithoutValidation(req.Matchers) if err != nil { diff --git a/pkg/ingester/ingester.go b/pkg/ingester/ingester.go index f23e1de227f6b..41b358906e0a1 100644 --- a/pkg/ingester/ingester.go +++ b/pkg/ingester/ingester.go @@ -1147,7 +1147,7 @@ func (i *Ingester) Label(ctx context.Context, req *logproto.LabelRequest) (*logp return } } else { - storeValues, err = cs.LabelNamesForMetricName(ctx, userID, from, through, "logs") + storeValues, err = cs.LabelNamesForMetricName(ctx, userID, from, through, "logs", matchers...) if err != nil { return } diff --git a/pkg/ingester/ingester_test.go b/pkg/ingester/ingester_test.go index 035a62e5a6414..1c438bd6bf2c0 100644 --- a/pkg/ingester/ingester_test.go +++ b/pkg/ingester/ingester_test.go @@ -465,7 +465,7 @@ func (s *mockStore) LabelValuesForMetricName(_ context.Context, _ string, _, _ m return []string{"val1", "val2"}, nil } -func (s *mockStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string) ([]string, error) { +func (s *mockStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string, _ ...*labels.Matcher) ([]string, error) { return nil, nil } diff --git a/pkg/logproto/logproto.pb.go b/pkg/logproto/logproto.pb.go index 0d0827f5a094c..e1c54358897e9 100644 --- a/pkg/logproto/logproto.pb.go +++ b/pkg/logproto/logproto.pb.go @@ -1866,6 +1866,7 @@ type LabelNamesForMetricNameRequest struct { MetricName string `protobuf:"bytes,1,opt,name=metric_name,json=metricName,proto3" json:"metric_name,omitempty"` From github_com_prometheus_common_model.Time `protobuf:"varint,2,opt,name=from,proto3,customtype=github.com/prometheus/common/model.Time" json:"from"` Through github_com_prometheus_common_model.Time `protobuf:"varint,3,opt,name=through,proto3,customtype=github.com/prometheus/common/model.Time" json:"through"` + Matchers string `protobuf:"bytes,4,opt,name=matchers,proto3" json:"matchers,omitempty"` } func (m *LabelNamesForMetricNameRequest) Reset() { *m = LabelNamesForMetricNameRequest{} } @@ -1907,6 +1908,13 @@ func (m *LabelNamesForMetricNameRequest) GetMetricName() string { return "" } +func (m *LabelNamesForMetricNameRequest) GetMatchers() string { + if m != nil { + return m.Matchers + } + return "" +} + // TODO(owen-d): fix. This will break rollouts as soon as the internal repr is changed. type LineFilter struct { Raw []byte `protobuf:"bytes,1,opt,name=raw,proto3" json:"raw,omitempty"` @@ -3113,174 +3121,175 @@ func init() { func init() { proto.RegisterFile("pkg/logproto/logproto.proto", fileDescriptor_c28a5f14f1f4c79a) } var fileDescriptor_c28a5f14f1f4c79a = []byte{ - // 2671 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3a, 0x4d, 0x6c, 0x1b, 0xc7, - 0xd5, 0x5c, 0x72, 0xf9, 0xf7, 0x48, 0xc9, 0xf2, 0x88, 0xb6, 0x09, 0xd9, 0xe1, 0x2a, 0x83, 0xef, - 0x4b, 0xdc, 0xd8, 0x11, 0x63, 0xa7, 0x49, 0x1d, 0xa7, 0x69, 0x6a, 0x4a, 0xb1, 0x63, 0x47, 0x71, - 0x9c, 0x91, 0xe3, 0xa4, 0x45, 0x83, 0x60, 0x4d, 0x8e, 0xa8, 0x85, 0xc9, 0x5d, 0x7a, 0x77, 0x18, - 0x47, 0xb7, 0x02, 0x3d, 0x17, 0x0d, 0xd0, 0x43, 0xdb, 0x4b, 0x81, 0x02, 0x05, 0x5a, 0xb4, 0xc8, - 0xa5, 0xe8, 0xa9, 0x28, 0xda, 0x4b, 0x0f, 0xe9, 0x2d, 0xbd, 0x05, 0x39, 0xb0, 0x8d, 0x72, 0x29, - 0x74, 0x0a, 0x50, 0xa0, 0x87, 0x9c, 0x8a, 0xf9, 0xdb, 0x9d, 0x5d, 0x91, 0x75, 0xe8, 0xb8, 0x48, - 0x7c, 0x21, 0x67, 0xde, 0xbc, 0x79, 0x33, 0xef, 0x67, 0xde, 0x1f, 0x09, 0xc7, 0x47, 0xb7, 0xfa, - 0xed, 0x41, 0xd0, 0x1f, 0x85, 0x01, 0x0b, 0xe2, 0xc1, 0x9a, 0xf8, 0x44, 0x15, 0x3d, 0x5f, 0x69, - 0xf4, 0x83, 0x7e, 0x20, 0x71, 0xf8, 0x48, 0xae, 0xaf, 0x38, 0xfd, 0x20, 0xe8, 0x0f, 0x68, 0x5b, - 0xcc, 0x6e, 0x8e, 0xb7, 0xdb, 0xcc, 0x1b, 0xd2, 0x88, 0xb9, 0xc3, 0x91, 0x42, 0x58, 0x55, 0xd4, - 0x6f, 0x0f, 0x86, 0x41, 0x8f, 0x0e, 0xda, 0x11, 0x73, 0x59, 0x24, 0x3f, 0x15, 0xc6, 0x32, 0xc7, - 0x18, 0x8d, 0xa3, 0x1d, 0xf1, 0x21, 0x81, 0xf8, 0xf7, 0x16, 0x1c, 0xd9, 0x74, 0x6f, 0xd2, 0xc1, - 0xf5, 0xe0, 0x86, 0x3b, 0x18, 0xd3, 0x88, 0xd0, 0x68, 0x14, 0xf8, 0x11, 0x45, 0xeb, 0x50, 0x1a, - 0xf0, 0x85, 0xa8, 0x69, 0xad, 0x16, 0x4e, 0xd6, 0xce, 0x9e, 0x5a, 0x8b, 0xaf, 0x3c, 0x75, 0x83, - 0x84, 0x46, 0x2f, 0xf8, 0x2c, 0xdc, 0x25, 0x6a, 0xeb, 0xca, 0x0d, 0xa8, 0x19, 0x60, 0xb4, 0x04, - 0x85, 0x5b, 0x74, 0xb7, 0x69, 0xad, 0x5a, 0x27, 0xab, 0x84, 0x0f, 0xd1, 0x19, 0x28, 0xbe, 0xcd, - 0xc9, 0x34, 0xf3, 0xab, 0xd6, 0xc9, 0xda, 0xd9, 0xe3, 0xc9, 0x21, 0xaf, 0xf9, 0xde, 0xed, 0x31, - 0x15, 0xbb, 0xd5, 0x41, 0x12, 0xf3, 0x7c, 0xfe, 0x9c, 0x85, 0x4f, 0xc1, 0xe1, 0x03, 0xeb, 0xe8, - 0x28, 0x94, 0x04, 0x86, 0xbc, 0x71, 0x95, 0xa8, 0x19, 0x6e, 0x00, 0xda, 0x62, 0x21, 0x75, 0x87, - 0xc4, 0x65, 0xfc, 0xbe, 0xb7, 0xc7, 0x34, 0x62, 0xf8, 0x65, 0x58, 0x4e, 0x41, 0x15, 0xdb, 0x4f, - 0x43, 0x2d, 0x4a, 0xc0, 0x8a, 0xf7, 0x46, 0x72, 0xad, 0x64, 0x0f, 0x31, 0x11, 0xf1, 0xcf, 0x2d, - 0x80, 0x64, 0x0d, 0xb5, 0x00, 0xe4, 0xea, 0x8b, 0x6e, 0xb4, 0x23, 0x18, 0xb6, 0x89, 0x01, 0x41, - 0xa7, 0xe1, 0x70, 0x32, 0xbb, 0x1a, 0x6c, 0xed, 0xb8, 0x61, 0x4f, 0xc8, 0xc0, 0x26, 0x07, 0x17, - 0x10, 0x02, 0x3b, 0x74, 0x19, 0x6d, 0x16, 0x56, 0xad, 0x93, 0x05, 0x22, 0xc6, 0x9c, 0x5b, 0x46, - 0x7d, 0xd7, 0x67, 0x4d, 0x5b, 0x88, 0x53, 0xcd, 0x38, 0x9c, 0xeb, 0x97, 0x46, 0xcd, 0xe2, 0xaa, - 0x75, 0x72, 0x81, 0xa8, 0x19, 0xfe, 0x77, 0x01, 0xea, 0xaf, 0x8e, 0x69, 0xb8, 0xab, 0x04, 0x80, - 0x5a, 0x50, 0x89, 0xe8, 0x80, 0x76, 0x59, 0x10, 0x4a, 0x8d, 0x74, 0xf2, 0x4d, 0x8b, 0xc4, 0x30, - 0xd4, 0x80, 0xe2, 0xc0, 0x1b, 0x7a, 0x4c, 0x5c, 0x6b, 0x81, 0xc8, 0x09, 0x3a, 0x0f, 0xc5, 0x88, - 0xb9, 0x21, 0x13, 0x77, 0xa9, 0x9d, 0x5d, 0x59, 0x93, 0x86, 0xb9, 0xa6, 0x0d, 0x73, 0xed, 0xba, - 0x36, 0xcc, 0x4e, 0xe5, 0xfd, 0x89, 0x93, 0x7b, 0xf7, 0xef, 0x8e, 0x45, 0xe4, 0x16, 0xf4, 0x34, - 0x14, 0xa8, 0xdf, 0x13, 0xf7, 0xfd, 0xbc, 0x3b, 0xf9, 0x06, 0x74, 0x06, 0xaa, 0x3d, 0x2f, 0xa4, - 0x5d, 0xe6, 0x05, 0xbe, 0xe0, 0x6a, 0xf1, 0xec, 0x72, 0xa2, 0x91, 0x0d, 0xbd, 0x44, 0x12, 0x2c, - 0x74, 0x1a, 0x4a, 0x11, 0x17, 0x5d, 0xd4, 0x2c, 0x73, 0x5b, 0xe8, 0x34, 0xf6, 0x27, 0xce, 0x92, - 0x84, 0x9c, 0x0e, 0x86, 0x1e, 0xa3, 0xc3, 0x11, 0xdb, 0x25, 0x0a, 0x07, 0x3d, 0x06, 0xe5, 0x1e, - 0x1d, 0x50, 0xae, 0xf0, 0x8a, 0x50, 0xf8, 0x92, 0x41, 0x5e, 0x2c, 0x10, 0x8d, 0x80, 0xde, 0x04, - 0x7b, 0x34, 0x70, 0xfd, 0x66, 0x55, 0x70, 0xb1, 0x98, 0x20, 0x5e, 0x1b, 0xb8, 0x7e, 0xe7, 0x99, - 0x8f, 0x26, 0xce, 0x53, 0x7d, 0x8f, 0xed, 0x8c, 0x6f, 0xae, 0x75, 0x83, 0x61, 0xbb, 0x1f, 0xba, - 0xdb, 0xae, 0xef, 0xb6, 0x07, 0xc1, 0x2d, 0xaf, 0xfd, 0xf6, 0x93, 0x6d, 0xfe, 0x06, 0x6f, 0x8f, - 0x69, 0xe8, 0xd1, 0xb0, 0xcd, 0xc9, 0xac, 0x09, 0x95, 0xf0, 0xad, 0x44, 0x90, 0x45, 0x57, 0xb8, - 0xfd, 0x05, 0x21, 0x5d, 0xdf, 0x19, 0xfb, 0xb7, 0xa2, 0x26, 0x88, 0x53, 0x8e, 0x25, 0xa7, 0x08, - 0x38, 0xa1, 0xdb, 0x97, 0xc2, 0x60, 0x3c, 0xea, 0x1c, 0xda, 0x9f, 0x38, 0x26, 0x3e, 0x31, 0x27, - 0x57, 0xec, 0x4a, 0x69, 0xa9, 0x8c, 0xdf, 0x2b, 0x00, 0xda, 0x72, 0x87, 0xa3, 0x01, 0x9d, 0x4b, - 0xfd, 0xb1, 0xa2, 0xf3, 0xf7, 0xac, 0xe8, 0xc2, 0xbc, 0x8a, 0x4e, 0xb4, 0x66, 0xcf, 0xa7, 0xb5, - 0xe2, 0xe7, 0xd5, 0x5a, 0xe9, 0x2b, 0xaf, 0x35, 0xdc, 0x04, 0x9b, 0x53, 0xe6, 0xce, 0x32, 0x74, - 0xef, 0x08, 0xdd, 0xd4, 0x09, 0x1f, 0xe2, 0x4d, 0x28, 0x49, 0xbe, 0xd0, 0x4a, 0x56, 0x79, 0xe9, - 0x77, 0x9b, 0x28, 0xae, 0xa0, 0x55, 0xb2, 0x94, 0xa8, 0xa4, 0x20, 0x84, 0x8d, 0xff, 0x68, 0xc1, - 0x82, 0xb2, 0x08, 0xe5, 0xfb, 0x6e, 0x42, 0x59, 0xfa, 0x1e, 0xed, 0xf7, 0x8e, 0x65, 0xfd, 0xde, - 0x85, 0x9e, 0x3b, 0x62, 0x34, 0xec, 0xb4, 0xdf, 0x9f, 0x38, 0xd6, 0x47, 0x13, 0xe7, 0xd1, 0x59, - 0x42, 0xd3, 0xb1, 0x46, 0xfb, 0x4b, 0x4d, 0x18, 0x9d, 0x12, 0xb7, 0x63, 0x91, 0x32, 0xab, 0x43, - 0x6b, 0x32, 0x44, 0x5d, 0xf6, 0xfb, 0x34, 0xe2, 0x94, 0x6d, 0x6e, 0x11, 0x44, 0xe2, 0x70, 0x36, - 0xef, 0xb8, 0xa1, 0xef, 0xf9, 0xfd, 0xa8, 0x59, 0x10, 0x3e, 0x3d, 0x9e, 0xe3, 0x9f, 0x5a, 0xb0, - 0x9c, 0x32, 0x6b, 0xc5, 0xc4, 0x39, 0x28, 0x45, 0x5c, 0x53, 0x9a, 0x07, 0xc3, 0x28, 0xb6, 0x04, - 0xbc, 0xb3, 0xa8, 0x2e, 0x5f, 0x92, 0x73, 0xa2, 0xf0, 0xef, 0xdf, 0xd5, 0xfe, 0x62, 0x41, 0x5d, - 0x04, 0x26, 0xfd, 0xd6, 0x10, 0xd8, 0xbe, 0x3b, 0xa4, 0x4a, 0x55, 0x62, 0x6c, 0x44, 0x2b, 0x7e, - 0x5c, 0x45, 0x47, 0xab, 0x79, 0x1d, 0xac, 0x75, 0xcf, 0x0e, 0xd6, 0x4a, 0xde, 0x5d, 0x03, 0x8a, - 0xdc, 0xbc, 0x77, 0x85, 0x73, 0xad, 0x12, 0x39, 0xc1, 0x8f, 0xc2, 0x82, 0xe2, 0x42, 0x89, 0x76, - 0x56, 0x80, 0x1d, 0x42, 0x49, 0x6a, 0x02, 0xfd, 0x1f, 0x54, 0xe3, 0xc4, 0x44, 0x70, 0x5b, 0xe8, - 0x94, 0xf6, 0x27, 0x4e, 0x9e, 0x45, 0x24, 0x59, 0x40, 0x8e, 0x19, 0xf4, 0xad, 0x4e, 0x75, 0x7f, - 0xe2, 0x48, 0x80, 0x0a, 0xf1, 0xe8, 0x04, 0xd8, 0x3b, 0x3c, 0x6e, 0x72, 0x11, 0xd8, 0x9d, 0xca, - 0xfe, 0xc4, 0x11, 0x73, 0x22, 0x3e, 0xf1, 0x25, 0xa8, 0x6f, 0xd2, 0xbe, 0xdb, 0xdd, 0x55, 0x87, - 0x36, 0x34, 0x39, 0x7e, 0xa0, 0xa5, 0x69, 0x3c, 0x0c, 0xf5, 0xf8, 0xc4, 0xb7, 0x86, 0x91, 0x7a, - 0x0d, 0xb5, 0x18, 0xf6, 0x72, 0x84, 0x7f, 0x66, 0x81, 0xb2, 0x01, 0x84, 0x8d, 0x6c, 0x87, 0xfb, - 0x42, 0xd8, 0x9f, 0x38, 0x0a, 0xa2, 0x93, 0x19, 0xf4, 0x2c, 0x94, 0x23, 0x71, 0x22, 0x27, 0x96, - 0x35, 0x2d, 0xb1, 0xd0, 0x39, 0xc4, 0x4d, 0x64, 0x7f, 0xe2, 0x68, 0x44, 0xa2, 0x07, 0x68, 0x2d, - 0x95, 0x10, 0x48, 0xc6, 0x16, 0xf7, 0x27, 0x8e, 0x01, 0x35, 0x13, 0x04, 0xfc, 0x99, 0x05, 0xb5, - 0xeb, 0xae, 0x17, 0x9b, 0x50, 0x53, 0xab, 0x28, 0xf1, 0xd5, 0x12, 0xc0, 0x2d, 0xb1, 0x47, 0x07, - 0xee, 0xee, 0xc5, 0x20, 0x14, 0x74, 0x17, 0x48, 0x3c, 0x4f, 0x62, 0xb8, 0x3d, 0x35, 0x86, 0x17, - 0xe7, 0x77, 0xed, 0xff, 0x5b, 0x47, 0x7a, 0xc5, 0xae, 0xe4, 0x97, 0x0a, 0xf8, 0x3d, 0x0b, 0xea, - 0x92, 0x79, 0x65, 0x79, 0xdf, 0x83, 0x92, 0x94, 0x8d, 0x60, 0xff, 0xbf, 0x38, 0xa6, 0x53, 0xf3, - 0x38, 0x25, 0x45, 0x13, 0x3d, 0x0f, 0x8b, 0xbd, 0x30, 0x18, 0x8d, 0x68, 0x6f, 0x4b, 0xb9, 0xbf, - 0x7c, 0xd6, 0xfd, 0x6d, 0x98, 0xeb, 0x24, 0x83, 0x8e, 0xff, 0x6a, 0xc1, 0x82, 0x72, 0x26, 0x4a, - 0x5d, 0xb1, 0x88, 0xad, 0x7b, 0x8e, 0x9e, 0xf9, 0x79, 0xa3, 0xe7, 0x51, 0x28, 0xf5, 0x79, 0x7c, - 0xd1, 0x0e, 0x49, 0xcd, 0xe6, 0x8b, 0xaa, 0xf8, 0x0a, 0x2c, 0x6a, 0x56, 0x66, 0x78, 0xd4, 0x95, - 0xac, 0x47, 0xbd, 0xdc, 0xa3, 0x3e, 0xf3, 0xb6, 0xbd, 0xd8, 0x47, 0x2a, 0x7c, 0xfc, 0x23, 0x0b, - 0x96, 0xb2, 0x28, 0x68, 0x23, 0x53, 0x58, 0x3c, 0x32, 0x9b, 0x9c, 0x59, 0x53, 0x68, 0xd2, 0xaa, - 0xb2, 0x78, 0xea, 0x6e, 0x95, 0x45, 0xc3, 0x74, 0x32, 0x55, 0xe5, 0x15, 0xf0, 0x4f, 0x2c, 0x58, - 0x48, 0xe9, 0x12, 0x9d, 0x03, 0x7b, 0x3b, 0x0c, 0x86, 0x73, 0x29, 0x4a, 0xec, 0x40, 0x5f, 0x87, - 0x3c, 0x0b, 0xe6, 0x52, 0x53, 0x9e, 0x05, 0x5c, 0x4b, 0x8a, 0xfd, 0x82, 0xcc, 0xdb, 0xe5, 0x0c, - 0x3f, 0x05, 0x55, 0xc1, 0xd0, 0x35, 0xd7, 0x0b, 0xa7, 0x06, 0x8c, 0xe9, 0x0c, 0x3d, 0x0b, 0x87, - 0xa4, 0x33, 0x9c, 0xbe, 0xb9, 0x3e, 0x6d, 0x73, 0x5d, 0x6f, 0x3e, 0x0e, 0x45, 0x91, 0x74, 0xf0, - 0x2d, 0x3d, 0x97, 0xb9, 0x7a, 0x0b, 0x1f, 0xe3, 0x23, 0xb0, 0xcc, 0xdf, 0x20, 0x0d, 0xa3, 0xf5, - 0x60, 0xec, 0x33, 0x5d, 0x37, 0x9d, 0x86, 0x46, 0x1a, 0xac, 0xac, 0xa4, 0x01, 0xc5, 0x2e, 0x07, - 0x08, 0x1a, 0x0b, 0x44, 0x4e, 0xf0, 0x2f, 0x2d, 0x40, 0x97, 0x28, 0x13, 0xa7, 0x5c, 0xde, 0x88, - 0x9f, 0xc7, 0x0a, 0x54, 0x86, 0x2e, 0xeb, 0xee, 0xd0, 0x30, 0xd2, 0xf9, 0x8b, 0x9e, 0x7f, 0x19, - 0x89, 0x27, 0x3e, 0x03, 0xcb, 0xa9, 0x5b, 0x2a, 0x9e, 0x56, 0xa0, 0xd2, 0x55, 0x30, 0x15, 0xf2, - 0xe2, 0x39, 0xfe, 0x5d, 0x1e, 0x2a, 0x3a, 0xad, 0x43, 0x67, 0xa0, 0xb6, 0xed, 0xf9, 0x7d, 0x1a, - 0x8e, 0x42, 0x4f, 0x89, 0xc0, 0x96, 0x69, 0x9e, 0x01, 0x26, 0xe6, 0x04, 0x3d, 0x0e, 0xe5, 0x71, - 0x44, 0xc3, 0xb7, 0x3c, 0xf9, 0xd2, 0xab, 0x9d, 0xc6, 0xde, 0xc4, 0x29, 0xbd, 0x16, 0xd1, 0xf0, - 0xf2, 0x06, 0x0f, 0x3e, 0x63, 0x31, 0x22, 0xf2, 0xbb, 0x87, 0x5e, 0x52, 0x66, 0x2a, 0x12, 0xb8, - 0xce, 0x37, 0xf8, 0xf5, 0x33, 0xae, 0x6e, 0x14, 0x06, 0x43, 0xca, 0x76, 0xe8, 0x38, 0x6a, 0x77, - 0x83, 0xe1, 0x30, 0xf0, 0xdb, 0xa2, 0x13, 0x20, 0x98, 0xe6, 0x11, 0x94, 0x6f, 0x57, 0x96, 0x7b, - 0x1d, 0xca, 0x6c, 0x27, 0x0c, 0xc6, 0xfd, 0x1d, 0x11, 0x18, 0x0a, 0x9d, 0xf3, 0xf3, 0xd3, 0xd3, - 0x14, 0x88, 0x1e, 0xa0, 0x87, 0xb9, 0xb4, 0x68, 0xf7, 0x56, 0x34, 0x1e, 0xca, 0xda, 0xb3, 0x53, - 0xdc, 0x9f, 0x38, 0xd6, 0xe3, 0x24, 0x06, 0xe3, 0x0b, 0xb0, 0x90, 0x4a, 0x85, 0xd1, 0x13, 0x60, - 0x87, 0x74, 0x5b, 0xbb, 0x02, 0x74, 0x30, 0x63, 0x96, 0xd1, 0x9f, 0xe3, 0x10, 0xf1, 0x89, 0x7f, - 0x98, 0x07, 0xc7, 0xa8, 0xfa, 0x2f, 0x06, 0xe1, 0xcb, 0x94, 0x85, 0x5e, 0xf7, 0xaa, 0x3b, 0xa4, - 0xda, 0xbc, 0x1c, 0xa8, 0x0d, 0x05, 0xf0, 0x2d, 0xe3, 0x15, 0xc1, 0x30, 0xc6, 0x43, 0x0f, 0x01, - 0x88, 0x67, 0x27, 0xd7, 0xe5, 0x83, 0xaa, 0x0a, 0x88, 0x58, 0x5e, 0x4f, 0x09, 0xbb, 0x3d, 0xa7, - 0x70, 0x94, 0x90, 0x2f, 0x67, 0x85, 0x3c, 0x37, 0x9d, 0x58, 0xb2, 0xe6, 0x73, 0x29, 0xa6, 0x9f, - 0x0b, 0xfe, 0x9b, 0x05, 0xad, 0x4d, 0x7d, 0xf3, 0x7b, 0x14, 0x87, 0xe6, 0x37, 0x7f, 0x9f, 0xf8, - 0x2d, 0x7c, 0x31, 0x7e, 0x71, 0x0b, 0x60, 0xd3, 0xf3, 0xe9, 0x45, 0x6f, 0xc0, 0x68, 0x38, 0xa5, - 0x10, 0xfa, 0x71, 0x21, 0xf1, 0x2a, 0x84, 0x6e, 0x6b, 0x3e, 0xd7, 0x0d, 0x57, 0x7e, 0x3f, 0xd8, - 0xc8, 0xdf, 0x47, 0xb5, 0x15, 0x32, 0x5e, 0xce, 0x87, 0xf2, 0xb6, 0x60, 0x4f, 0x46, 0xe5, 0x54, - 0x8f, 0x29, 0xe1, 0xbd, 0xf3, 0x2d, 0x75, 0xf8, 0xd3, 0x77, 0x49, 0xaa, 0x44, 0xe7, 0xaf, 0x1d, - 0xed, 0xfa, 0xcc, 0x7d, 0xc7, 0xd8, 0x4f, 0xf4, 0x21, 0xc8, 0x55, 0x79, 0x5b, 0x71, 0x6a, 0xde, - 0xf6, 0x9c, 0x3a, 0xe6, 0x8b, 0xe4, 0x6e, 0xf8, 0xb9, 0xc4, 0x89, 0x0a, 0xa5, 0x28, 0x27, 0xfa, - 0xc8, 0xdd, 0x9e, 0xb8, 0x7a, 0xd8, 0x7f, 0xb2, 0x60, 0xe9, 0x12, 0x65, 0xe9, 0x3c, 0xea, 0x01, - 0x52, 0x29, 0x7e, 0x11, 0x0e, 0x1b, 0xf7, 0x57, 0xdc, 0x3f, 0x99, 0x49, 0x9e, 0x8e, 0x24, 0xfc, - 0x5f, 0xf6, 0x7b, 0xf4, 0x1d, 0x55, 0x93, 0xa6, 0xf3, 0xa6, 0x6b, 0x50, 0x33, 0x16, 0xd1, 0x85, - 0x4c, 0xc6, 0xb4, 0x9c, 0x69, 0xc5, 0xf2, 0xa8, 0xdf, 0x69, 0x28, 0x9e, 0x64, 0xe5, 0xa9, 0xf2, - 0xe1, 0x38, 0xbb, 0xd8, 0x02, 0x24, 0xd4, 0x25, 0xc8, 0x9a, 0xf1, 0x4d, 0x40, 0x5f, 0x8a, 0x53, - 0xa7, 0x78, 0x8e, 0x1e, 0x06, 0x3b, 0x0c, 0xee, 0xe8, 0x54, 0x78, 0x21, 0x39, 0x92, 0x04, 0x77, - 0x88, 0x58, 0xc2, 0xcf, 0x42, 0x81, 0x04, 0x77, 0x50, 0x0b, 0x20, 0x74, 0xfd, 0x3e, 0xbd, 0x11, - 0x17, 0x61, 0x75, 0x62, 0x40, 0x66, 0xe4, 0x1e, 0xeb, 0x70, 0xd8, 0xbc, 0x91, 0x54, 0xf7, 0x1a, - 0x94, 0x5f, 0x1d, 0x9b, 0xe2, 0x6a, 0x64, 0xc4, 0x25, 0x6b, 0x7d, 0x8d, 0xc4, 0x6d, 0x06, 0x12, - 0x38, 0x3a, 0x01, 0x55, 0xe6, 0xde, 0x1c, 0xd0, 0xab, 0x89, 0x9b, 0x4b, 0x00, 0x7c, 0x95, 0xd7, - 0x8f, 0x37, 0x8c, 0x24, 0x2a, 0x01, 0xa0, 0xc7, 0x60, 0x29, 0xb9, 0xf3, 0xb5, 0x90, 0x6e, 0x7b, - 0xef, 0x08, 0x0d, 0xd7, 0xc9, 0x01, 0x38, 0x3a, 0x09, 0x87, 0x12, 0xd8, 0x96, 0x48, 0x56, 0x6c, - 0x81, 0x9a, 0x05, 0x73, 0xd9, 0x08, 0x76, 0x5f, 0xb8, 0x3d, 0x76, 0x07, 0xe2, 0xf1, 0xd5, 0x89, - 0x01, 0xc1, 0x7f, 0xb6, 0xe0, 0xb0, 0x54, 0x35, 0x73, 0xd9, 0x03, 0x69, 0xf5, 0xbf, 0xb2, 0x00, - 0x99, 0x1c, 0x28, 0xd3, 0xfa, 0x7f, 0xb3, 0x97, 0xc4, 0xb3, 0xa1, 0x9a, 0x28, 0x8b, 0x25, 0x28, - 0x69, 0x07, 0x61, 0x28, 0x75, 0x65, 0xcf, 0x4c, 0x34, 0xbf, 0x65, 0xdd, 0x2d, 0x21, 0x44, 0x7d, - 0x23, 0x07, 0x8a, 0x37, 0x77, 0x19, 0x8d, 0x54, 0xd5, 0x2c, 0xda, 0x05, 0x02, 0x40, 0xe4, 0x17, - 0x3f, 0x8b, 0xfa, 0x4c, 0x58, 0x8d, 0x9d, 0x9c, 0xa5, 0x40, 0x44, 0x0f, 0xf0, 0x6f, 0xf3, 0xb0, - 0x70, 0x23, 0x18, 0x8c, 0x93, 0xc0, 0xf8, 0x20, 0x05, 0x8c, 0x54, 0x29, 0x5f, 0xd4, 0xa5, 0x3c, - 0x02, 0x3b, 0x62, 0x74, 0x24, 0x2c, 0xab, 0x40, 0xc4, 0x18, 0x61, 0xa8, 0x33, 0x37, 0xec, 0x53, - 0x26, 0x0b, 0xa4, 0x66, 0x49, 0x64, 0xae, 0x29, 0x18, 0x5a, 0x85, 0x9a, 0xdb, 0xef, 0x87, 0xb4, - 0xef, 0x32, 0xda, 0xd9, 0x6d, 0x96, 0xc5, 0x61, 0x26, 0x08, 0xbf, 0x01, 0x8b, 0x5a, 0x58, 0x4a, - 0xa5, 0x4f, 0x40, 0xf9, 0x6d, 0x01, 0x99, 0xd2, 0x5a, 0x93, 0xa8, 0xca, 0x8d, 0x69, 0xb4, 0xf4, - 0x4f, 0x08, 0xfa, 0xce, 0xf8, 0x0a, 0x94, 0x24, 0x3a, 0x3a, 0x61, 0x96, 0x39, 0x32, 0xd3, 0xe3, - 0x73, 0x55, 0xb3, 0x60, 0x28, 0x49, 0x42, 0x4a, 0xf1, 0xc2, 0x36, 0x24, 0x84, 0xa8, 0x6f, 0xfc, - 0x2f, 0x0b, 0x8e, 0x6c, 0x50, 0x46, 0xbb, 0x8c, 0xf6, 0x2e, 0x7a, 0x74, 0xd0, 0xfb, 0x52, 0x2b, - 0xf0, 0xb8, 0x8f, 0x56, 0x30, 0xfa, 0x68, 0xdc, 0xef, 0x0c, 0x3c, 0x9f, 0x6e, 0x1a, 0x8d, 0x98, - 0x04, 0xc0, 0x3d, 0xc4, 0x36, 0xbf, 0xb8, 0x5c, 0x96, 0xbf, 0xd9, 0x18, 0x90, 0x58, 0xc3, 0xa5, - 0x44, 0xc3, 0xf8, 0x07, 0x16, 0x1c, 0xcd, 0x72, 0xad, 0x94, 0xd4, 0x86, 0x92, 0xd8, 0x3c, 0xa5, - 0x85, 0x9b, 0xda, 0x41, 0x14, 0x1a, 0x3a, 0x97, 0x3a, 0x5f, 0xfc, 0xd6, 0xd3, 0x69, 0xee, 0x4f, - 0x9c, 0x46, 0x02, 0x35, 0xba, 0x04, 0x06, 0x2e, 0xfe, 0x03, 0xaf, 0xa5, 0x4d, 0x9a, 0x42, 0xdf, - 0xdc, 0xbe, 0x94, 0xef, 0x95, 0x13, 0xf4, 0x35, 0xb0, 0xd9, 0xee, 0x48, 0xb9, 0xdc, 0xce, 0x91, - 0xcf, 0x26, 0xce, 0xe1, 0xd4, 0xb6, 0xeb, 0xbb, 0x23, 0x4a, 0x04, 0x0a, 0x37, 0xcb, 0xae, 0x1b, - 0xf6, 0x3c, 0xdf, 0x1d, 0x78, 0x4c, 0x8a, 0xd1, 0x26, 0x26, 0x08, 0x35, 0xa1, 0x3c, 0x72, 0xc3, - 0x48, 0xe7, 0x4d, 0x55, 0xa2, 0xa7, 0xa2, 0xcd, 0x71, 0x8b, 0xb2, 0xee, 0x8e, 0x74, 0xb3, 0xaa, - 0xcd, 0x21, 0x20, 0xa9, 0x36, 0x87, 0x80, 0xe0, 0x5f, 0x18, 0x86, 0x23, 0xdf, 0xc4, 0x57, 0xce, - 0x70, 0xf0, 0x77, 0x12, 0x2d, 0xeb, 0x2b, 0x2a, 0x2d, 0x3f, 0x0f, 0x8b, 0xbd, 0xd4, 0xca, 0x6c, - 0x6d, 0xcb, 0x16, 0x6e, 0x06, 0x1d, 0x8f, 0x13, 0xd5, 0x09, 0xc8, 0x0c, 0xd5, 0x65, 0xf4, 0x91, - 0x3f, 0xa8, 0x8f, 0x44, 0xea, 0x85, 0xbb, 0x4b, 0xfd, 0xb1, 0x47, 0xa0, 0x1a, 0xff, 0x5c, 0x87, - 0x6a, 0x50, 0xbe, 0xf8, 0x0a, 0x79, 0xfd, 0x02, 0xd9, 0x58, 0xca, 0xa1, 0x3a, 0x54, 0x3a, 0x17, - 0xd6, 0x5f, 0x12, 0x33, 0xeb, 0xec, 0x6f, 0x4a, 0x3a, 0x11, 0x08, 0xd1, 0x37, 0xa1, 0x28, 0xa3, - 0xfb, 0xd1, 0x84, 0x39, 0xf3, 0x97, 0xac, 0x95, 0x63, 0x07, 0xe0, 0x52, 0x4a, 0x38, 0xf7, 0x84, - 0x85, 0xae, 0x42, 0x4d, 0x00, 0x55, 0xaf, 0xf8, 0x44, 0xb6, 0x65, 0x9b, 0xa2, 0xf4, 0xd0, 0x8c, - 0x55, 0x83, 0xde, 0x79, 0x28, 0x4a, 0x81, 0x1d, 0xcd, 0x24, 0x61, 0x53, 0x6e, 0x93, 0xea, 0x9e, - 0xe3, 0x1c, 0x7a, 0x06, 0xec, 0xeb, 0xae, 0x37, 0x40, 0x46, 0x0e, 0x68, 0xb4, 0x78, 0x57, 0x8e, - 0x66, 0xc1, 0xc6, 0xb1, 0xcf, 0xc5, 0x9d, 0xea, 0x63, 0xd9, 0x76, 0x99, 0xde, 0xde, 0x3c, 0xb8, - 0x10, 0x9f, 0xfc, 0x8a, 0xec, 0xa7, 0xea, 0xa6, 0x0d, 0x7a, 0x28, 0x7d, 0x54, 0xa6, 0xc7, 0xb3, - 0xd2, 0x9a, 0xb5, 0x1c, 0x13, 0xdc, 0x84, 0x9a, 0xd1, 0x30, 0x31, 0xc5, 0x7a, 0xb0, 0xdb, 0x63, - 0x8a, 0x75, 0x4a, 0x97, 0x05, 0xe7, 0xd0, 0x25, 0xa8, 0xf0, 0xcc, 0x59, 0xfc, 0xb0, 0x72, 0x3c, - 0x9b, 0x20, 0x1b, 0x89, 0xd1, 0xca, 0x89, 0xe9, 0x8b, 0x31, 0xa1, 0x6f, 0x43, 0xf5, 0x12, 0x65, - 0x2a, 0xba, 0x1c, 0xcb, 0x86, 0xa7, 0x29, 0x92, 0x4a, 0x87, 0x38, 0x9c, 0x43, 0x6f, 0x88, 0x24, - 0x3e, 0xed, 0x5c, 0x91, 0x33, 0xc3, 0x89, 0xc6, 0xf7, 0x5a, 0x9d, 0x8d, 0x10, 0x53, 0x7e, 0x3d, - 0x45, 0x59, 0xc5, 0x61, 0x67, 0xc6, 0x83, 0x8d, 0x29, 0x3b, 0x77, 0xf9, 0xdb, 0x05, 0xce, 0x9d, - 0x7d, 0x53, 0xff, 0xf3, 0x60, 0xc3, 0x65, 0x2e, 0x7a, 0x05, 0x16, 0x85, 0x2c, 0xe3, 0xbf, 0x26, - 0xa4, 0x6c, 0xfe, 0xc0, 0xff, 0x20, 0x52, 0x36, 0x7f, 0xf0, 0xff, 0x10, 0x38, 0xd7, 0x79, 0xf3, - 0x83, 0x8f, 0x5b, 0xb9, 0x0f, 0x3f, 0x6e, 0xe5, 0x3e, 0xfd, 0xb8, 0x65, 0x7d, 0x7f, 0xaf, 0x65, - 0xfd, 0x7a, 0xaf, 0x65, 0xbd, 0xbf, 0xd7, 0xb2, 0x3e, 0xd8, 0x6b, 0x59, 0xff, 0xd8, 0x6b, 0x59, - 0xff, 0xdc, 0x6b, 0xe5, 0x3e, 0xdd, 0x6b, 0x59, 0xef, 0x7e, 0xd2, 0xca, 0x7d, 0xf0, 0x49, 0x2b, - 0xf7, 0xe1, 0x27, 0xad, 0xdc, 0x77, 0x1f, 0xbd, 0x7b, 0xc1, 0x2a, 0xdd, 0x62, 0x49, 0x7c, 0x3d, - 0xf9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xd4, 0xcd, 0x88, 0x1f, 0x23, 0x00, 0x00, + // 2673 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x1a, 0x4d, 0x8c, 0x5b, 0x47, + 0xd9, 0xcf, 0x7e, 0xfe, 0xfb, 0xec, 0xdd, 0x6c, 0x66, 0x9d, 0xc4, 0xda, 0xa4, 0x7e, 0xdb, 0x11, + 0xb4, 0xa1, 0x49, 0xd7, 0x4d, 0x4a, 0x4b, 0x9a, 0x52, 0x4a, 0xbc, 0xdb, 0xa4, 0x49, 0xb7, 0x69, + 0x3a, 0x9b, 0xa6, 0x05, 0x51, 0x55, 0x2f, 0xf6, 0xac, 0xf7, 0x29, 0xf6, 0x7b, 0xce, 0x7b, 0xe3, + 0xa6, 0x7b, 0x43, 0xe2, 0x8c, 0xa8, 0xc4, 0x01, 0xb8, 0x20, 0x21, 0x21, 0x81, 0x40, 0xbd, 0x20, + 0x4e, 0x08, 0xc1, 0x85, 0x43, 0xb9, 0xf5, 0x58, 0xf5, 0x60, 0xe8, 0xf6, 0x82, 0x56, 0x42, 0xaa, + 0x84, 0xc4, 0xa1, 0x27, 0x34, 0x7f, 0xef, 0xcd, 0x7b, 0x6b, 0x93, 0x3a, 0x04, 0xb5, 0xb9, 0xd8, + 0xf3, 0x7d, 0xf3, 0xcd, 0x37, 0xf3, 0xfd, 0xcc, 0xf7, 0x7d, 0xf3, 0xd9, 0x70, 0x7c, 0x74, 0xab, + 0xdf, 0x1e, 0x04, 0xfd, 0x51, 0x18, 0xb0, 0x20, 0x1e, 0xac, 0x89, 0x4f, 0x54, 0xd1, 0xf0, 0x4a, + 0xa3, 0x1f, 0xf4, 0x03, 0x49, 0xc3, 0x47, 0x72, 0x7e, 0xc5, 0xe9, 0x07, 0x41, 0x7f, 0x40, 0xdb, + 0x02, 0xba, 0x39, 0xde, 0x6e, 0x33, 0x6f, 0x48, 0x23, 0xe6, 0x0e, 0x47, 0x8a, 0x60, 0x55, 0x71, + 0xbf, 0x3d, 0x18, 0x06, 0x3d, 0x3a, 0x68, 0x47, 0xcc, 0x65, 0x91, 0xfc, 0x54, 0x14, 0xcb, 0x9c, + 0x62, 0x34, 0x8e, 0x76, 0xc4, 0x87, 0x44, 0xe2, 0xdf, 0x5b, 0x70, 0x64, 0xd3, 0xbd, 0x49, 0x07, + 0xd7, 0x83, 0x1b, 0xee, 0x60, 0x4c, 0x23, 0x42, 0xa3, 0x51, 0xe0, 0x47, 0x14, 0xad, 0x43, 0x69, + 0xc0, 0x27, 0xa2, 0xa6, 0xb5, 0x5a, 0x38, 0x59, 0x3b, 0x7b, 0x6a, 0x2d, 0x3e, 0xf2, 0xd4, 0x05, + 0x12, 0x1b, 0xbd, 0xe0, 0xb3, 0x70, 0x97, 0xa8, 0xa5, 0x2b, 0x37, 0xa0, 0x66, 0xa0, 0xd1, 0x12, + 0x14, 0x6e, 0xd1, 0xdd, 0xa6, 0xb5, 0x6a, 0x9d, 0xac, 0x12, 0x3e, 0x44, 0x67, 0xa0, 0xf8, 0x36, + 0x67, 0xd3, 0xcc, 0xaf, 0x5a, 0x27, 0x6b, 0x67, 0x8f, 0x27, 0x9b, 0xbc, 0xe6, 0x7b, 0xb7, 0xc7, + 0x54, 0xac, 0x56, 0x1b, 0x49, 0xca, 0xf3, 0xf9, 0x73, 0x16, 0x3e, 0x05, 0x87, 0x0f, 0xcc, 0xa3, + 0xa3, 0x50, 0x12, 0x14, 0xf2, 0xc4, 0x55, 0xa2, 0x20, 0xdc, 0x00, 0xb4, 0xc5, 0x42, 0xea, 0x0e, + 0x89, 0xcb, 0xf8, 0x79, 0x6f, 0x8f, 0x69, 0xc4, 0xf0, 0xcb, 0xb0, 0x9c, 0xc2, 0x2a, 0xb1, 0x9f, + 0x86, 0x5a, 0x94, 0xa0, 0x95, 0xec, 0x8d, 0xe4, 0x58, 0xc9, 0x1a, 0x62, 0x12, 0xe2, 0x9f, 0x5b, + 0x00, 0xc9, 0x1c, 0x6a, 0x01, 0xc8, 0xd9, 0x17, 0xdd, 0x68, 0x47, 0x08, 0x6c, 0x13, 0x03, 0x83, + 0x4e, 0xc3, 0xe1, 0x04, 0xba, 0x1a, 0x6c, 0xed, 0xb8, 0x61, 0x4f, 0xe8, 0xc0, 0x26, 0x07, 0x27, + 0x10, 0x02, 0x3b, 0x74, 0x19, 0x6d, 0x16, 0x56, 0xad, 0x93, 0x05, 0x22, 0xc6, 0x5c, 0x5a, 0x46, + 0x7d, 0xd7, 0x67, 0x4d, 0x5b, 0xa8, 0x53, 0x41, 0x1c, 0xcf, 0xed, 0x4b, 0xa3, 0x66, 0x71, 0xd5, + 0x3a, 0xb9, 0x40, 0x14, 0x84, 0xff, 0x5d, 0x80, 0xfa, 0xab, 0x63, 0x1a, 0xee, 0x2a, 0x05, 0xa0, + 0x16, 0x54, 0x22, 0x3a, 0xa0, 0x5d, 0x16, 0x84, 0xd2, 0x22, 0x9d, 0x7c, 0xd3, 0x22, 0x31, 0x0e, + 0x35, 0xa0, 0x38, 0xf0, 0x86, 0x1e, 0x13, 0xc7, 0x5a, 0x20, 0x12, 0x40, 0xe7, 0xa1, 0x18, 0x31, + 0x37, 0x64, 0xe2, 0x2c, 0xb5, 0xb3, 0x2b, 0x6b, 0xd2, 0x31, 0xd7, 0xb4, 0x63, 0xae, 0x5d, 0xd7, + 0x8e, 0xd9, 0xa9, 0xbc, 0x3f, 0x71, 0x72, 0xef, 0xfe, 0xcd, 0xb1, 0x88, 0x5c, 0x82, 0x9e, 0x86, + 0x02, 0xf5, 0x7b, 0xe2, 0xbc, 0x9f, 0x77, 0x25, 0x5f, 0x80, 0xce, 0x40, 0xb5, 0xe7, 0x85, 0xb4, + 0xcb, 0xbc, 0xc0, 0x17, 0x52, 0x2d, 0x9e, 0x5d, 0x4e, 0x2c, 0xb2, 0xa1, 0xa7, 0x48, 0x42, 0x85, + 0x4e, 0x43, 0x29, 0xe2, 0xaa, 0x8b, 0x9a, 0x65, 0xee, 0x0b, 0x9d, 0xc6, 0xfe, 0xc4, 0x59, 0x92, + 0x98, 0xd3, 0xc1, 0xd0, 0x63, 0x74, 0x38, 0x62, 0xbb, 0x44, 0xd1, 0xa0, 0xc7, 0xa0, 0xdc, 0xa3, + 0x03, 0xca, 0x0d, 0x5e, 0x11, 0x06, 0x5f, 0x32, 0xd8, 0x8b, 0x09, 0xa2, 0x09, 0xd0, 0x9b, 0x60, + 0x8f, 0x06, 0xae, 0xdf, 0xac, 0x0a, 0x29, 0x16, 0x13, 0xc2, 0x6b, 0x03, 0xd7, 0xef, 0x3c, 0xf3, + 0xd1, 0xc4, 0x79, 0xaa, 0xef, 0xb1, 0x9d, 0xf1, 0xcd, 0xb5, 0x6e, 0x30, 0x6c, 0xf7, 0x43, 0x77, + 0xdb, 0xf5, 0xdd, 0xf6, 0x20, 0xb8, 0xe5, 0xb5, 0xdf, 0x7e, 0xb2, 0xcd, 0xef, 0xe0, 0xed, 0x31, + 0x0d, 0x3d, 0x1a, 0xb6, 0x39, 0x9b, 0x35, 0x61, 0x12, 0xbe, 0x94, 0x08, 0xb6, 0xe8, 0x0a, 0xf7, + 0xbf, 0x20, 0xa4, 0xeb, 0x3b, 0x63, 0xff, 0x56, 0xd4, 0x04, 0xb1, 0xcb, 0xb1, 0x64, 0x17, 0x81, + 0x27, 0x74, 0xfb, 0x52, 0x18, 0x8c, 0x47, 0x9d, 0x43, 0xfb, 0x13, 0xc7, 0xa4, 0x27, 0x26, 0x70, + 0xc5, 0xae, 0x94, 0x96, 0xca, 0xf8, 0xbd, 0x02, 0xa0, 0x2d, 0x77, 0x38, 0x1a, 0xd0, 0xb9, 0xcc, + 0x1f, 0x1b, 0x3a, 0x7f, 0xcf, 0x86, 0x2e, 0xcc, 0x6b, 0xe8, 0xc4, 0x6a, 0xf6, 0x7c, 0x56, 0x2b, + 0x7e, 0x5e, 0xab, 0x95, 0xbe, 0xf4, 0x56, 0xc3, 0x4d, 0xb0, 0x39, 0x67, 0x1e, 0x2c, 0x43, 0xf7, + 0x8e, 0xb0, 0x4d, 0x9d, 0xf0, 0x21, 0xde, 0x84, 0x92, 0x94, 0x0b, 0xad, 0x64, 0x8d, 0x97, 0xbe, + 0xb7, 0x89, 0xe1, 0x0a, 0xda, 0x24, 0x4b, 0x89, 0x49, 0x0a, 0x42, 0xd9, 0xf8, 0x8f, 0x16, 0x2c, + 0x28, 0x8f, 0x50, 0xb1, 0xef, 0x26, 0x94, 0x65, 0xec, 0xd1, 0x71, 0xef, 0x58, 0x36, 0xee, 0x5d, + 0xe8, 0xb9, 0x23, 0x46, 0xc3, 0x4e, 0xfb, 0xfd, 0x89, 0x63, 0x7d, 0x34, 0x71, 0x1e, 0x9d, 0xa5, + 0x34, 0x9d, 0x6b, 0x74, 0xbc, 0xd4, 0x8c, 0xd1, 0x29, 0x71, 0x3a, 0x16, 0x29, 0xb7, 0x3a, 0xb4, + 0x26, 0x53, 0xd4, 0x65, 0xbf, 0x4f, 0x23, 0xce, 0xd9, 0xe6, 0x1e, 0x41, 0x24, 0x0d, 0x17, 0xf3, + 0x8e, 0x1b, 0xfa, 0x9e, 0xdf, 0x8f, 0x9a, 0x05, 0x11, 0xd3, 0x63, 0x18, 0xff, 0xd4, 0x82, 0xe5, + 0x94, 0x5b, 0x2b, 0x21, 0xce, 0x41, 0x29, 0xe2, 0x96, 0xd2, 0x32, 0x18, 0x4e, 0xb1, 0x25, 0xf0, + 0x9d, 0x45, 0x75, 0xf8, 0x92, 0x84, 0x89, 0xa2, 0xbf, 0x7f, 0x47, 0xfb, 0x8b, 0x05, 0x75, 0x91, + 0x98, 0xf4, 0x5d, 0x43, 0x60, 0xfb, 0xee, 0x90, 0x2a, 0x53, 0x89, 0xb1, 0x91, 0xad, 0xf8, 0x76, + 0x15, 0x9d, 0xad, 0xe6, 0x0d, 0xb0, 0xd6, 0x3d, 0x07, 0x58, 0x2b, 0xb9, 0x77, 0x0d, 0x28, 0x72, + 0xf7, 0xde, 0x15, 0xc1, 0xb5, 0x4a, 0x24, 0x80, 0x1f, 0x85, 0x05, 0x25, 0x85, 0x52, 0xed, 0xac, + 0x04, 0x3b, 0x84, 0x92, 0xb4, 0x04, 0xfa, 0x0a, 0x54, 0xe3, 0xc2, 0x44, 0x48, 0x5b, 0xe8, 0x94, + 0xf6, 0x27, 0x4e, 0x9e, 0x45, 0x24, 0x99, 0x40, 0x8e, 0x99, 0xf4, 0xad, 0x4e, 0x75, 0x7f, 0xe2, + 0x48, 0x84, 0x4a, 0xf1, 0xe8, 0x04, 0xd8, 0x3b, 0x3c, 0x6f, 0x72, 0x15, 0xd8, 0x9d, 0xca, 0xfe, + 0xc4, 0x11, 0x30, 0x11, 0x9f, 0xf8, 0x12, 0xd4, 0x37, 0x69, 0xdf, 0xed, 0xee, 0xaa, 0x4d, 0x1b, + 0x9a, 0x1d, 0xdf, 0xd0, 0xd2, 0x3c, 0x1e, 0x86, 0x7a, 0xbc, 0xe3, 0x5b, 0xc3, 0x48, 0xdd, 0x86, + 0x5a, 0x8c, 0x7b, 0x39, 0xc2, 0x3f, 0xb3, 0x40, 0xf9, 0x00, 0xc2, 0x46, 0xb5, 0xc3, 0x63, 0x21, + 0xec, 0x4f, 0x1c, 0x85, 0xd1, 0xc5, 0x0c, 0x7a, 0x16, 0xca, 0x91, 0xd8, 0x91, 0x33, 0xcb, 0xba, + 0x96, 0x98, 0xe8, 0x1c, 0xe2, 0x2e, 0xb2, 0x3f, 0x71, 0x34, 0x21, 0xd1, 0x03, 0xb4, 0x96, 0x2a, + 0x08, 0xa4, 0x60, 0x8b, 0xfb, 0x13, 0xc7, 0xc0, 0x9a, 0x05, 0x02, 0xfe, 0xcc, 0x82, 0xda, 0x75, + 0xd7, 0x8b, 0x5d, 0xa8, 0xa9, 0x4d, 0x94, 0xc4, 0x6a, 0x89, 0xe0, 0x9e, 0xd8, 0xa3, 0x03, 0x77, + 0xf7, 0x62, 0x10, 0x0a, 0xbe, 0x0b, 0x24, 0x86, 0x93, 0x1c, 0x6e, 0x4f, 0xcd, 0xe1, 0xc5, 0xf9, + 0x43, 0xfb, 0xff, 0x37, 0x90, 0x5e, 0xb1, 0x2b, 0xf9, 0xa5, 0x02, 0x7e, 0xcf, 0x82, 0xba, 0x14, + 0x5e, 0x79, 0xde, 0xf7, 0xa0, 0x24, 0x75, 0x23, 0xc4, 0xff, 0x2f, 0x81, 0xe9, 0xd4, 0x3c, 0x41, + 0x49, 0xf1, 0x44, 0xcf, 0xc3, 0x62, 0x2f, 0x0c, 0x46, 0x23, 0xda, 0xdb, 0x52, 0xe1, 0x2f, 0x9f, + 0x0d, 0x7f, 0x1b, 0xe6, 0x3c, 0xc9, 0x90, 0xe3, 0xbf, 0x5a, 0xb0, 0xa0, 0x82, 0x89, 0x32, 0x57, + 0xac, 0x62, 0xeb, 0x9e, 0xb3, 0x67, 0x7e, 0xde, 0xec, 0x79, 0x14, 0x4a, 0x7d, 0x9e, 0x5f, 0x74, + 0x40, 0x52, 0xd0, 0x7c, 0x59, 0x15, 0x5f, 0x81, 0x45, 0x2d, 0xca, 0x8c, 0x88, 0xba, 0x92, 0x8d, + 0xa8, 0x97, 0x7b, 0xd4, 0x67, 0xde, 0xb6, 0x17, 0xc7, 0x48, 0x45, 0x8f, 0x7f, 0x64, 0xc1, 0x52, + 0x96, 0x04, 0x6d, 0x64, 0x1e, 0x16, 0x8f, 0xcc, 0x66, 0x67, 0xbe, 0x29, 0x34, 0x6b, 0xf5, 0xb2, + 0x78, 0xea, 0x6e, 0x2f, 0x8b, 0x86, 0x19, 0x64, 0xaa, 0x2a, 0x2a, 0xe0, 0x9f, 0x58, 0xb0, 0x90, + 0xb2, 0x25, 0x3a, 0x07, 0xf6, 0x76, 0x18, 0x0c, 0xe7, 0x32, 0x94, 0x58, 0x81, 0xbe, 0x0e, 0x79, + 0x16, 0xcc, 0x65, 0xa6, 0x3c, 0x0b, 0xb8, 0x95, 0x94, 0xf8, 0x05, 0x59, 0xb7, 0x4b, 0x08, 0x3f, + 0x05, 0x55, 0x21, 0xd0, 0x35, 0xd7, 0x0b, 0xa7, 0x26, 0x8c, 0xe9, 0x02, 0x3d, 0x0b, 0x87, 0x64, + 0x30, 0x9c, 0xbe, 0xb8, 0x3e, 0x6d, 0x71, 0x5d, 0x2f, 0x3e, 0x0e, 0x45, 0x51, 0x74, 0xf0, 0x25, + 0x3d, 0x97, 0xb9, 0x7a, 0x09, 0x1f, 0xe3, 0x23, 0xb0, 0xcc, 0xef, 0x20, 0x0d, 0xa3, 0xf5, 0x60, + 0xec, 0x33, 0xfd, 0x6e, 0x3a, 0x0d, 0x8d, 0x34, 0x5a, 0x79, 0x49, 0x03, 0x8a, 0x5d, 0x8e, 0x10, + 0x3c, 0x16, 0x88, 0x04, 0xf0, 0x2f, 0x2d, 0x40, 0x97, 0x28, 0x13, 0xbb, 0x5c, 0xde, 0x88, 0xaf, + 0xc7, 0x0a, 0x54, 0x86, 0x2e, 0xeb, 0xee, 0xd0, 0x30, 0xd2, 0xf5, 0x8b, 0x86, 0xbf, 0x88, 0xc2, + 0x13, 0x9f, 0x81, 0xe5, 0xd4, 0x29, 0x95, 0x4c, 0x2b, 0x50, 0xe9, 0x2a, 0x9c, 0x4a, 0x79, 0x31, + 0x8c, 0x7f, 0x97, 0x87, 0x8a, 0x2e, 0xeb, 0xd0, 0x19, 0xa8, 0x6d, 0x7b, 0x7e, 0x9f, 0x86, 0xa3, + 0xd0, 0x53, 0x2a, 0xb0, 0x65, 0x99, 0x67, 0xa0, 0x89, 0x09, 0xa0, 0xc7, 0xa1, 0x3c, 0x8e, 0x68, + 0xf8, 0x96, 0x27, 0x6f, 0x7a, 0xb5, 0xd3, 0xd8, 0x9b, 0x38, 0xa5, 0xd7, 0x22, 0x1a, 0x5e, 0xde, + 0xe0, 0xc9, 0x67, 0x2c, 0x46, 0x44, 0x7e, 0xf7, 0xd0, 0x4b, 0xca, 0x4d, 0x45, 0x01, 0xd7, 0xf9, + 0x06, 0x3f, 0x7e, 0x26, 0xd4, 0x8d, 0xc2, 0x60, 0x48, 0xd9, 0x0e, 0x1d, 0x47, 0xed, 0x6e, 0x30, + 0x1c, 0x06, 0x7e, 0x5b, 0x74, 0x02, 0x84, 0xd0, 0x3c, 0x83, 0xf2, 0xe5, 0xca, 0x73, 0xaf, 0x43, + 0x99, 0xed, 0x84, 0xc1, 0xb8, 0xbf, 0x23, 0x12, 0x43, 0xa1, 0x73, 0x7e, 0x7e, 0x7e, 0x9a, 0x03, + 0xd1, 0x03, 0xf4, 0x30, 0xd7, 0x16, 0xed, 0xde, 0x8a, 0xc6, 0x43, 0xf9, 0xf6, 0xec, 0x14, 0xf7, + 0x27, 0x8e, 0xf5, 0x38, 0x89, 0xd1, 0xf8, 0x02, 0x2c, 0xa4, 0x4a, 0x61, 0xf4, 0x04, 0xd8, 0x21, + 0xdd, 0xd6, 0xa1, 0x00, 0x1d, 0xac, 0x98, 0x65, 0xf6, 0xe7, 0x34, 0x44, 0x7c, 0xe2, 0x1f, 0xe6, + 0xc1, 0x31, 0x5e, 0xfd, 0x17, 0x83, 0xf0, 0x65, 0xca, 0x42, 0xaf, 0x7b, 0xd5, 0x1d, 0x52, 0xed, + 0x5e, 0x0e, 0xd4, 0x86, 0x02, 0xf9, 0x96, 0x71, 0x8b, 0x60, 0x18, 0xd3, 0xa1, 0x87, 0x00, 0xc4, + 0xb5, 0x93, 0xf3, 0xf2, 0x42, 0x55, 0x05, 0x46, 0x4c, 0xaf, 0xa7, 0x94, 0xdd, 0x9e, 0x53, 0x39, + 0x4a, 0xc9, 0x97, 0xb3, 0x4a, 0x9e, 0x9b, 0x4f, 0xac, 0x59, 0xf3, 0xba, 0x14, 0xd3, 0xd7, 0x05, + 0xff, 0xd3, 0x82, 0xd6, 0xa6, 0x3e, 0xf9, 0x3d, 0xaa, 0x43, 0xcb, 0x9b, 0xbf, 0x4f, 0xf2, 0x16, + 0xee, 0xa3, 0xbc, 0x76, 0x46, 0xde, 0x16, 0xc0, 0xa6, 0xe7, 0xd3, 0x8b, 0xde, 0x80, 0xd1, 0x70, + 0xca, 0x23, 0xe9, 0xc7, 0x85, 0x24, 0xe2, 0x10, 0xba, 0xad, 0x75, 0xb0, 0x6e, 0x84, 0xf9, 0xfb, + 0x21, 0x62, 0xfe, 0x3e, 0x8a, 0x58, 0xc8, 0x44, 0x40, 0x1f, 0xca, 0xdb, 0x42, 0x3c, 0x99, 0xb1, + 0x53, 0xfd, 0xa7, 0x44, 0xf6, 0xce, 0xb7, 0xd4, 0xe6, 0x4f, 0xdf, 0xa5, 0xe0, 0x12, 0x5d, 0xc1, + 0x76, 0xb4, 0xeb, 0x33, 0xf7, 0x1d, 0x63, 0x3d, 0xd1, 0x9b, 0x20, 0x57, 0xd5, 0x74, 0xc5, 0xa9, + 0x35, 0xdd, 0x73, 0x6a, 0x9b, 0xff, 0xa5, 0xae, 0xc3, 0xcf, 0x25, 0x01, 0x56, 0x18, 0x45, 0x05, + 0xd8, 0x47, 0xee, 0x76, 0xfd, 0xd5, 0xa5, 0xff, 0x93, 0x05, 0x4b, 0x97, 0x28, 0x4b, 0xd7, 0x58, + 0x0f, 0x90, 0x49, 0xf1, 0x8b, 0x70, 0xd8, 0x38, 0xbf, 0x92, 0xfe, 0xc9, 0x4c, 0x61, 0x75, 0x24, + 0x91, 0xff, 0xb2, 0xdf, 0xa3, 0xef, 0xa8, 0xf7, 0x6a, 0xba, 0xa6, 0xba, 0x06, 0x35, 0x63, 0x12, + 0x5d, 0xc8, 0x54, 0x53, 0xcb, 0x99, 0x36, 0x2d, 0xaf, 0x08, 0x3a, 0x0d, 0x25, 0x93, 0x7c, 0x95, + 0xaa, 0x5a, 0x39, 0xae, 0x3c, 0xb6, 0x00, 0x09, 0x73, 0x09, 0xb6, 0x66, 0xee, 0x13, 0xd8, 0x97, + 0xe2, 0xb2, 0x2a, 0x86, 0xd1, 0xc3, 0x60, 0x87, 0xc1, 0x1d, 0x5d, 0x26, 0x2f, 0x24, 0x5b, 0x92, + 0xe0, 0x0e, 0x11, 0x53, 0xf8, 0x59, 0x28, 0x90, 0xe0, 0x0e, 0x6a, 0x01, 0x84, 0xae, 0xdf, 0xa7, + 0x37, 0xe2, 0x07, 0x5a, 0x9d, 0x18, 0x98, 0x19, 0x75, 0xc9, 0x3a, 0x1c, 0x36, 0x4f, 0x24, 0xcd, + 0xbd, 0x06, 0xe5, 0x57, 0xc7, 0xa6, 0xba, 0x1a, 0x19, 0x75, 0xc9, 0x3e, 0x80, 0x26, 0xe2, 0x3e, + 0x03, 0x09, 0x1e, 0x9d, 0x80, 0x2a, 0x73, 0x6f, 0x0e, 0xe8, 0xd5, 0x24, 0x04, 0x26, 0x08, 0x3e, + 0xcb, 0xdf, 0x96, 0x37, 0x8c, 0x02, 0x2b, 0x41, 0xa0, 0xc7, 0x60, 0x29, 0x39, 0xf3, 0xb5, 0x90, + 0x6e, 0x7b, 0xef, 0x08, 0x0b, 0xd7, 0xc9, 0x01, 0x3c, 0x3a, 0x09, 0x87, 0x12, 0xdc, 0x96, 0x28, + 0x64, 0x6c, 0x41, 0x9a, 0x45, 0x73, 0xdd, 0x08, 0x71, 0x5f, 0xb8, 0x3d, 0x76, 0x07, 0xe2, 0xf2, + 0xd5, 0x89, 0x81, 0xc1, 0x7f, 0xb6, 0xe0, 0xb0, 0x34, 0x35, 0x73, 0xd9, 0x03, 0xe9, 0xf5, 0xbf, + 0xb2, 0x00, 0x99, 0x12, 0x28, 0xd7, 0xfa, 0xaa, 0xd9, 0x67, 0xe2, 0x95, 0x52, 0x4d, 0x3c, 0x99, + 0x25, 0x2a, 0x69, 0x15, 0x61, 0x28, 0x75, 0x65, 0x3f, 0x4d, 0x34, 0xc6, 0xe5, 0x9b, 0x5c, 0x62, + 0x88, 0xfa, 0x46, 0x0e, 0x14, 0x6f, 0xee, 0x32, 0x1a, 0xa9, 0x17, 0xb5, 0x68, 0x25, 0x08, 0x04, + 0x91, 0x5f, 0x7c, 0x2f, 0xea, 0x33, 0xe1, 0x35, 0x76, 0xb2, 0x97, 0x42, 0x11, 0x3d, 0xc0, 0xbf, + 0xcd, 0xc3, 0xc2, 0x8d, 0x60, 0x30, 0x4e, 0x92, 0xe6, 0x83, 0x94, 0x30, 0x52, 0xcf, 0xfc, 0xa2, + 0x7e, 0xe6, 0x23, 0xb0, 0x23, 0x46, 0x47, 0xc2, 0xb3, 0x0a, 0x44, 0x8c, 0x11, 0x86, 0x3a, 0x73, + 0xc3, 0x3e, 0x65, 0xf2, 0xf1, 0xd4, 0x2c, 0x89, 0xaa, 0x36, 0x85, 0x43, 0xab, 0x50, 0x73, 0xfb, + 0xfd, 0x90, 0xf6, 0x5d, 0x46, 0x3b, 0xbb, 0xcd, 0xb2, 0xd8, 0xcc, 0x44, 0xe1, 0x37, 0x60, 0x51, + 0x2b, 0x4b, 0x99, 0xf4, 0x09, 0x28, 0xbf, 0x2d, 0x30, 0x53, 0xda, 0x6e, 0x92, 0x54, 0x85, 0x31, + 0x4d, 0x96, 0xfe, 0x79, 0x41, 0x9f, 0x19, 0x5f, 0x81, 0x92, 0x24, 0x47, 0x27, 0xcc, 0x27, 0x90, + 0xac, 0x02, 0x39, 0xac, 0xde, 0x33, 0x18, 0x4a, 0x92, 0x91, 0x32, 0xbc, 0xf0, 0x0d, 0x89, 0x21, + 0xea, 0x1b, 0xff, 0xcb, 0x82, 0x23, 0x1b, 0x94, 0xd1, 0x2e, 0xa3, 0xbd, 0x8b, 0x1e, 0x1d, 0xf4, + 0xbe, 0xd0, 0xd7, 0x79, 0xdc, 0x63, 0x2b, 0x18, 0x3d, 0x36, 0x1e, 0x77, 0x06, 0x9e, 0x4f, 0x37, + 0x8d, 0x26, 0x4d, 0x82, 0xe0, 0x11, 0x62, 0x9b, 0x1f, 0x5c, 0x4e, 0xcb, 0xdf, 0x73, 0x0c, 0x4c, + 0x6c, 0xe1, 0x52, 0x62, 0x61, 0xfc, 0x03, 0x0b, 0x8e, 0x66, 0xa5, 0x56, 0x46, 0x6a, 0x43, 0x49, + 0x2c, 0x9e, 0xd2, 0xde, 0x4d, 0xad, 0x20, 0x8a, 0x0c, 0x9d, 0x4b, 0xed, 0x2f, 0x7e, 0x07, 0xea, + 0x34, 0xf7, 0x27, 0x4e, 0x23, 0xc1, 0x1a, 0x1d, 0x04, 0x83, 0x16, 0xff, 0x81, 0xbf, 0xb3, 0x4d, + 0x9e, 0xc2, 0xde, 0xdc, 0xbf, 0x54, 0xec, 0x95, 0x00, 0xfa, 0x1a, 0xd8, 0x6c, 0x77, 0xa4, 0x42, + 0x6e, 0xe7, 0xc8, 0x67, 0x13, 0xe7, 0x70, 0x6a, 0xd9, 0xf5, 0xdd, 0x11, 0x25, 0x82, 0x84, 0xbb, + 0x65, 0xd7, 0x0d, 0x7b, 0x9e, 0xef, 0x0e, 0x3c, 0x26, 0xd5, 0x68, 0x13, 0x13, 0x85, 0x9a, 0x50, + 0x1e, 0xb9, 0x61, 0xa4, 0xeb, 0xa6, 0x2a, 0xd1, 0xa0, 0x68, 0x81, 0xdc, 0xa2, 0xac, 0xbb, 0x23, + 0xc3, 0xac, 0x6a, 0x81, 0x08, 0x4c, 0xaa, 0x05, 0x22, 0x30, 0xf8, 0x17, 0x86, 0xe3, 0xc8, 0x3b, + 0xf1, 0xa5, 0x73, 0x1c, 0xfc, 0x9d, 0xc4, 0xca, 0xfa, 0x88, 0xca, 0xca, 0xcf, 0xc3, 0x62, 0x2f, + 0x35, 0x33, 0xdb, 0xda, 0xb2, 0xbd, 0x9b, 0x21, 0xc7, 0xe3, 0xc4, 0x74, 0x02, 0x33, 0xc3, 0x74, + 0x19, 0x7b, 0xe4, 0x0f, 0xda, 0x23, 0xd1, 0x7a, 0xe1, 0xee, 0x5a, 0x7f, 0xec, 0x11, 0xa8, 0xc6, + 0x3f, 0xe5, 0xa1, 0x1a, 0x94, 0x2f, 0xbe, 0x42, 0x5e, 0xbf, 0x40, 0x36, 0x96, 0x72, 0xa8, 0x0e, + 0x95, 0xce, 0x85, 0xf5, 0x97, 0x04, 0x64, 0x9d, 0xfd, 0x4d, 0x49, 0x17, 0x02, 0x21, 0xfa, 0x26, + 0x14, 0x65, 0x76, 0x3f, 0x9a, 0x08, 0x67, 0xfe, 0xca, 0xb5, 0x72, 0xec, 0x00, 0x5e, 0x6a, 0x09, + 0xe7, 0x9e, 0xb0, 0xd0, 0x55, 0xa8, 0x09, 0xa4, 0xea, 0x23, 0x9f, 0xc8, 0xb6, 0x73, 0x53, 0x9c, + 0x1e, 0x9a, 0x31, 0x6b, 0xf0, 0x3b, 0x0f, 0x45, 0xa9, 0xb0, 0xa3, 0x99, 0x22, 0x6c, 0xca, 0x69, + 0x52, 0x9d, 0x75, 0x9c, 0x43, 0xcf, 0x80, 0x7d, 0xdd, 0xf5, 0x06, 0xc8, 0xa8, 0x01, 0x8d, 0xf6, + 0xef, 0xca, 0xd1, 0x2c, 0xda, 0xd8, 0xf6, 0xb9, 0xb8, 0x8b, 0x7d, 0x2c, 0xdb, 0x4a, 0xd3, 0xcb, + 0x9b, 0x07, 0x27, 0xe2, 0x9d, 0x5f, 0x91, 0xbd, 0x56, 0xdd, 0xd0, 0x41, 0x0f, 0xa5, 0xb7, 0xca, + 0xf4, 0x7f, 0x56, 0x5a, 0xb3, 0xa6, 0x63, 0x86, 0x9b, 0x50, 0x33, 0x9a, 0x29, 0xa6, 0x5a, 0x0f, + 0x76, 0x82, 0x4c, 0xb5, 0x4e, 0xe9, 0xc0, 0xe0, 0x1c, 0xba, 0x04, 0x15, 0x5e, 0x39, 0x8b, 0x1f, + 0x5d, 0x8e, 0x67, 0x0b, 0x64, 0xa3, 0x30, 0x5a, 0x39, 0x31, 0x7d, 0x32, 0x66, 0xf4, 0x6d, 0xa8, + 0x5e, 0xa2, 0x4c, 0x65, 0x97, 0x63, 0xd9, 0xf4, 0x34, 0x45, 0x53, 0xe9, 0x14, 0x87, 0x73, 0xe8, + 0x0d, 0x51, 0xc4, 0xa7, 0x83, 0x2b, 0x72, 0x66, 0x04, 0xd1, 0xf8, 0x5c, 0xab, 0xb3, 0x09, 0x62, + 0xce, 0xaf, 0xa7, 0x38, 0xab, 0x3c, 0xec, 0xcc, 0xb8, 0xb0, 0x31, 0x67, 0xe7, 0x2e, 0x7f, 0xc9, + 0xc0, 0xb9, 0xb3, 0x6f, 0xea, 0x7f, 0x25, 0x6c, 0xb8, 0xcc, 0x45, 0xaf, 0xc0, 0xa2, 0xd0, 0x65, + 0xfc, 0xb7, 0x85, 0x94, 0xcf, 0x1f, 0xf8, 0x8f, 0x44, 0xca, 0xe7, 0x0f, 0xfe, 0x57, 0x02, 0xe7, + 0x3a, 0x6f, 0x7e, 0xf0, 0x71, 0x2b, 0xf7, 0xe1, 0xc7, 0xad, 0xdc, 0xa7, 0x1f, 0xb7, 0xac, 0xef, + 0xef, 0xb5, 0xac, 0x5f, 0xef, 0xb5, 0xac, 0xf7, 0xf7, 0x5a, 0xd6, 0x07, 0x7b, 0x2d, 0xeb, 0xef, + 0x7b, 0x2d, 0xeb, 0x1f, 0x7b, 0xad, 0xdc, 0xa7, 0x7b, 0x2d, 0xeb, 0xdd, 0x4f, 0x5a, 0xb9, 0x0f, + 0x3e, 0x69, 0xe5, 0x3e, 0xfc, 0xa4, 0x95, 0xfb, 0xee, 0xa3, 0x77, 0x7f, 0xb0, 0xca, 0xb0, 0x58, + 0x12, 0x5f, 0x4f, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xb0, 0x55, 0xf6, 0x50, 0x3b, 0x23, 0x00, + 0x00, } func (x Direction) String() string { @@ -4396,6 +4405,9 @@ func (this *LabelNamesForMetricNameRequest) Equal(that interface{}) bool { if !this.Through.Equal(that1.Through) { return false } + if this.Matchers != that1.Matchers { + return false + } return true } func (this *LineFilter) Equal(that interface{}) bool { @@ -5506,11 +5518,12 @@ func (this *LabelNamesForMetricNameRequest) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 7) + s := make([]string, 0, 8) s = append(s, "&logproto.LabelNamesForMetricNameRequest{") s = append(s, "MetricName: "+fmt.Sprintf("%#v", this.MetricName)+",\n") s = append(s, "From: "+fmt.Sprintf("%#v", this.From)+",\n") s = append(s, "Through: "+fmt.Sprintf("%#v", this.Through)+",\n") + s = append(s, "Matchers: "+fmt.Sprintf("%#v", this.Matchers)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -7903,6 +7916,13 @@ func (m *LabelNamesForMetricNameRequest) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if len(m.Matchers) > 0 { + i -= len(m.Matchers) + copy(dAtA[i:], m.Matchers) + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Matchers))) + i-- + dAtA[i] = 0x22 + } if m.Through != 0 { i = encodeVarintLogproto(dAtA, i, uint64(m.Through)) i-- @@ -9525,6 +9545,10 @@ func (m *LabelNamesForMetricNameRequest) Size() (n int) { if m.Through != 0 { n += 1 + sovLogproto(uint64(m.Through)) } + l = len(m.Matchers) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } return n } @@ -10395,6 +10419,7 @@ func (this *LabelNamesForMetricNameRequest) String() string { `MetricName:` + fmt.Sprintf("%v", this.MetricName) + `,`, `From:` + fmt.Sprintf("%v", this.From) + `,`, `Through:` + fmt.Sprintf("%v", this.Through) + `,`, + `Matchers:` + fmt.Sprintf("%v", this.Matchers) + `,`, `}`, }, "") return s @@ -15166,6 +15191,38 @@ func (m *LabelNamesForMetricNameRequest) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Matchers", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Matchers = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLogproto(dAtA[iNdEx:]) diff --git a/pkg/logproto/logproto.proto b/pkg/logproto/logproto.proto index 189cec5d948ca..949861ee8ae4c 100644 --- a/pkg/logproto/logproto.proto +++ b/pkg/logproto/logproto.proto @@ -320,6 +320,7 @@ message LabelNamesForMetricNameRequest { (gogoproto.customtype) = "github.com/prometheus/common/model.Time", (gogoproto.nullable) = false ]; + string matchers = 4; } // TODO(owen-d): fix. This will break rollouts as soon as the internal repr is changed. diff --git a/pkg/querier/querier.go b/pkg/querier/querier.go index f2fe80566b461..8662f85c73f93 100644 --- a/pkg/querier/querier.go +++ b/pkg/querier/querier.go @@ -431,7 +431,7 @@ func (q *SingleTenantQuerier) Label(ctx context.Context, req *logproto.LabelRequ if req.Values { storeValues, err = q.store.LabelValuesForMetricName(ctx, userID, from, through, "logs", req.Name, matchers...) } else { - storeValues, err = q.store.LabelNamesForMetricName(ctx, userID, from, through, "logs") + storeValues, err = q.store.LabelNamesForMetricName(ctx, userID, from, through, "logs", matchers...) } return err }) diff --git a/pkg/querier/querier_mock_test.go b/pkg/querier/querier_mock_test.go index 51e4a6a9d8dd1..b70ba0cc3963b 100644 --- a/pkg/querier/querier_mock_test.go +++ b/pkg/querier/querier_mock_test.go @@ -352,7 +352,7 @@ func (s *storeMock) LabelValuesForMetricName(ctx context.Context, userID string, return args.Get(0).([]string), args.Error(1) } -func (s *storeMock) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (s *storeMock) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, _ ...*labels.Matcher) ([]string, error) { args := s.Called(ctx, userID, from, through, metricName) return args.Get(0).([]string), args.Error(1) } diff --git a/pkg/querier/queryrange/codec_test.go b/pkg/querier/queryrange/codec_test.go index 1363792922382..af047d8e84e1e 100644 --- a/pkg/querier/queryrange/codec_test.go +++ b/pkg/querier/queryrange/codec_test.go @@ -115,8 +115,8 @@ func Test_codec_EncodeDecodeRequest(t *testing.T) { }, false}, {"labels", func() (*http.Request, error) { return http.NewRequest(http.MethodGet, - fmt.Sprintf(`/label?start=%d&end=%d`, start.UnixNano(), end.UnixNano()), nil) - }, NewLabelRequest(start, end, "", "", "/label"), + fmt.Sprintf(`/label?start=%d&end=%d&query={foo="bar"}`, start.UnixNano(), end.UnixNano()), nil) + }, NewLabelRequest(start, end, `{foo="bar"}`, "", "/label"), false}, {"label_values", func() (*http.Request, error) { req, err := http.NewRequest(http.MethodGet, @@ -875,22 +875,26 @@ func Test_codec_series_EncodeRequest(t *testing.T) { func Test_codec_labels_EncodeRequest(t *testing.T) { ctx := user.InjectOrgID(context.Background(), "1") - toEncode := NewLabelRequest(start, end, "", "", "/loki/api/v1/labels") + + // Test labels endpoint + toEncode := NewLabelRequest(start, end, `{foo="bar"}`, "", "/loki/api/v1/labels") got, err := DefaultCodec.EncodeRequest(ctx, toEncode) require.NoError(t, err) require.Equal(t, ctx, got.Context()) require.Equal(t, "/loki/api/v1/labels", got.URL.Path) require.Equal(t, fmt.Sprintf("%d", start.UnixNano()), got.URL.Query().Get("start")) require.Equal(t, fmt.Sprintf("%d", end.UnixNano()), got.URL.Query().Get("end")) + require.Equal(t, `{foo="bar"}`, got.URL.Query().Get("query")) // testing a full roundtrip req, err := DefaultCodec.DecodeRequest(context.TODO(), got, nil) require.NoError(t, err) require.Equal(t, toEncode.Start, req.(*LabelRequest).Start) require.Equal(t, toEncode.End, req.(*LabelRequest).End) + require.Equal(t, toEncode.Query, req.(*LabelRequest).Query) require.Equal(t, "/loki/api/v1/labels", req.(*LabelRequest).Path()) - // Test labels values endpoint + // Test label values endpoint toEncode = NewLabelRequest(start, end, `{foo="bar"}`, "__name__", "/loki/api/v1/label/__name__/values") got, err = DefaultCodec.EncodeRequest(ctx, toEncode) require.NoError(t, err) @@ -912,21 +916,43 @@ func Test_codec_labels_EncodeRequest(t *testing.T) { func Test_codec_labels_DecodeRequest(t *testing.T) { ctx := user.InjectOrgID(context.Background(), "1") - u, err := url.Parse(`/loki/api/v1/label/__name__/values?start=1575285010000000010&end=1575288610000000010&query={foo="bar"}`) + + // Test labels endpoint + u, err := url.Parse(`/loki/api/v1/labels?start=1575285010000000010&end=1575288610000000010&query={foo="bar"}`) require.NoError(t, err) r := &http.Request{URL: u} - r = mux.SetURLVars(r, map[string]string{"name": "__name__"}) req, err := DefaultCodec.DecodeRequest(context.TODO(), r, nil) require.NoError(t, err) require.Equal(t, start, *req.(*LabelRequest).Start) require.Equal(t, end, *req.(*LabelRequest).End) require.Equal(t, `{foo="bar"}`, req.(*LabelRequest).Query) - require.Equal(t, "/loki/api/v1/label/__name__/values", req.(*LabelRequest).Path()) + require.Equal(t, "/loki/api/v1/labels", req.(*LabelRequest).Path()) got, err := DefaultCodec.EncodeRequest(ctx, req) require.NoError(t, err) require.Equal(t, ctx, got.Context()) + require.Equal(t, "/loki/api/v1/labels", got.URL.Path) + require.Equal(t, fmt.Sprintf("%d", start.UnixNano()), got.URL.Query().Get("start")) + require.Equal(t, fmt.Sprintf("%d", end.UnixNano()), got.URL.Query().Get("end")) + require.Equal(t, `{foo="bar"}`, got.URL.Query().Get("query")) + + // Test label values endpoint + u, err = url.Parse(`/loki/api/v1/label/__name__/values?start=1575285010000000010&end=1575288610000000010&query={foo="bar"}`) + require.NoError(t, err) + + r = &http.Request{URL: u} + r = mux.SetURLVars(r, map[string]string{"name": "__name__"}) + req, err = DefaultCodec.DecodeRequest(context.TODO(), r, nil) + require.NoError(t, err) + require.Equal(t, start, *req.(*LabelRequest).Start) + require.Equal(t, end, *req.(*LabelRequest).End) + require.Equal(t, `{foo="bar"}`, req.(*LabelRequest).Query) + require.Equal(t, "/loki/api/v1/label/__name__/values", req.(*LabelRequest).Path()) + + got, err = DefaultCodec.EncodeRequest(ctx, req) + require.NoError(t, err) + require.Equal(t, ctx, got.Context()) require.Equal(t, "/loki/api/v1/label/__name__/values", got.URL.Path) require.Equal(t, fmt.Sprintf("%d", start.UnixNano()), got.URL.Query().Get("start")) require.Equal(t, fmt.Sprintf("%d", end.UnixNano()), got.URL.Query().Get("end")) diff --git a/pkg/querier/queryrange/labels_cache.go b/pkg/querier/queryrange/labels_cache.go index 5979a0c2f91e1..2b946760aa1fd 100644 --- a/pkg/querier/queryrange/labels_cache.go +++ b/pkg/querier/queryrange/labels_cache.go @@ -61,7 +61,7 @@ func (i cacheKeyLabels) GenerateCacheKey(ctx context.Context, userID string, r r return fmt.Sprintf("labelvalues:%s:%s:%s:%d:%d", userID, lr.GetName(), lr.GetQuery(), currentInterval, split) } - return fmt.Sprintf("labels:%s:%d:%d", userID, currentInterval, split) + return fmt.Sprintf("labels:%s:%s:%d:%d", userID, lr.GetQuery(), currentInterval, split) } type labelsExtractor struct{} diff --git a/pkg/querier/queryrange/labels_cache_test.go b/pkg/querier/queryrange/labels_cache_test.go index 22e967a113762..d73f90cb63095 100644 --- a/pkg/querier/queryrange/labels_cache_test.go +++ b/pkg/querier/queryrange/labels_cache_test.go @@ -43,13 +43,17 @@ func TestCacheKeyLabels_GenerateCacheKey(t *testing.T) { expectedInterval := testTime.UnixMilli() / time.Hour.Milliseconds() t.Run("labels", func(t *testing.T) { - require.Equal(t, fmt.Sprintf(`labels:fake:%d:%d`, expectedInterval, time.Hour.Nanoseconds()), k.GenerateCacheKey(context.Background(), "fake", &req)) + require.Equal(t, fmt.Sprintf(`labels:fake::%d:%d`, expectedInterval, time.Hour.Nanoseconds()), k.GenerateCacheKey(context.Background(), "fake", &req)) + + req.Query = `{cluster="eu-west1"}` + require.Equal(t, fmt.Sprintf(`labels:fake:{cluster="eu-west1"}:%d:%d`, expectedInterval, time.Hour.Nanoseconds()), k.GenerateCacheKey(context.Background(), "fake", &req)) }) t.Run("label values", func(t *testing.T) { req := req req.Name = "foo" req.Values = true + req.Query = `` require.Equal(t, fmt.Sprintf(`labelvalues:fake:foo::%d:%d`, expectedInterval, time.Hour.Nanoseconds()), k.GenerateCacheKey(context.Background(), "fake", &req)) req.Query = `{cluster="eu-west1"}` @@ -361,20 +365,20 @@ func TestLabelQueryCacheKey(t *testing.T) { t.Run(fmt.Sprintf("%s (values: %v)", tc.name, values), func(t *testing.T) { keyGen := cacheKeyLabels{tc.limits, nil} + const labelName = "foo" + const query = `{cluster="eu-west1"}` + r := &LabelRequest{ LabelRequest: logproto.LabelRequest{ Start: &tc.start, End: &tc.end, + Query: query, }, } - const labelName = "foo" - const query = `{cluster="eu-west1"}` - if values { r.LabelRequest.Values = true r.LabelRequest.Name = labelName - r.LabelRequest.Query = query } // we use regex here because cache key always refers to the current time to get the ingester query window, @@ -383,7 +387,7 @@ func TestLabelQueryCacheKey(t *testing.T) { if values { pattern = regexp.MustCompile(fmt.Sprintf(`labelvalues:%s:%s:%s:(\d+):%d`, tenantID, labelName, regexp.QuoteMeta(query), tc.expectedSplit)) } else { - pattern = regexp.MustCompile(fmt.Sprintf(`labels:%s:(\d+):%d`, tenantID, tc.expectedSplit)) + pattern = regexp.MustCompile(fmt.Sprintf(`labels:%s:%s:(\d+):%d`, tenantID, regexp.QuoteMeta(query), tc.expectedSplit)) } require.Regexp(t, pattern, keyGen.GenerateCacheKey(context.Background(), tenantID, r)) diff --git a/pkg/storage/stores/composite_store.go b/pkg/storage/stores/composite_store.go index 62ba7f12df8ad..b975873c3043d 100644 --- a/pkg/storage/stores/composite_store.go +++ b/pkg/storage/stores/composite_store.go @@ -149,10 +149,10 @@ func (c CompositeStore) LabelValuesForMetricName(ctx context.Context, userID str } // LabelNamesForMetricName retrieves all label names for a metric name. -func (c CompositeStore) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (c CompositeStore) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { var result util.UniqueStrings err := c.forStores(ctx, from, through, func(innerCtx context.Context, from, through model.Time, store Store) error { - labelNames, err := store.LabelNamesForMetricName(innerCtx, userID, from, through, metricName) + labelNames, err := store.LabelNamesForMetricName(innerCtx, userID, from, through, metricName, matchers...) if err != nil { return err } diff --git a/pkg/storage/stores/composite_store_entry.go b/pkg/storage/stores/composite_store_entry.go index fd214543ef03d..2c6e3c5e4a90c 100644 --- a/pkg/storage/stores/composite_store_entry.go +++ b/pkg/storage/stores/composite_store_entry.go @@ -108,7 +108,7 @@ func (c *storeEntry) SetChunkFilterer(chunkFilter chunk.RequestChunkFilterer) { } // LabelNamesForMetricName retrieves all label names for a metric name. -func (c *storeEntry) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (c *storeEntry) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SeriesStore.LabelNamesForMetricName") defer sp.Finish() log := spanlogger.FromContext(ctx) @@ -122,7 +122,7 @@ func (c *storeEntry) LabelNamesForMetricName(ctx context.Context, userID string, } level.Debug(log).Log("metric", metricName) - return c.indexReader.LabelNamesForMetricName(ctx, userID, from, through, metricName) + return c.indexReader.LabelNamesForMetricName(ctx, userID, from, through, metricName, matchers...) } func (c *storeEntry) LabelValuesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, labelName string, matchers ...*labels.Matcher) ([]string, error) { diff --git a/pkg/storage/stores/composite_store_test.go b/pkg/storage/stores/composite_store_test.go index 203057c60845f..ab44f6b69d3c2 100644 --- a/pkg/storage/stores/composite_store_test.go +++ b/pkg/storage/stores/composite_store_test.go @@ -45,7 +45,7 @@ func (m mockStore) GetSeries(_ context.Context, _ string, _, _ model.Time, _ ... return nil, nil } -func (m mockStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string) ([]string, error) { +func (m mockStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string, _ ...*labels.Matcher) ([]string, error) { return nil, nil } @@ -210,7 +210,7 @@ func (m mockStoreLabel) LabelValuesForMetricName(_ context.Context, _ string, _, return m.values, nil } -func (m mockStoreLabel) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string) ([]string, error) { +func (m mockStoreLabel) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string, _ ...*labels.Matcher) ([]string, error) { return m.values, nil } diff --git a/pkg/storage/stores/index/index.go b/pkg/storage/stores/index/index.go index 99e5b35978837..4014fca8c3e7b 100644 --- a/pkg/storage/stores/index/index.go +++ b/pkg/storage/stores/index/index.go @@ -25,7 +25,7 @@ type Filterable interface { type BaseReader interface { GetSeries(ctx context.Context, userID string, from, through model.Time, matchers ...*labels.Matcher) ([]labels.Labels, error) LabelValuesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, labelName string, matchers ...*labels.Matcher) ([]string, error) - LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) + LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) } type StatsReader interface { @@ -112,11 +112,11 @@ func (m MonitoredReaderWriter) LabelValuesForMetricName(ctx context.Context, use return values, nil } -func (m MonitoredReaderWriter) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (m MonitoredReaderWriter) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { var values []string if err := loki_instrument.TimeRequest(ctx, "label_names", instrument.NewHistogramCollector(m.metrics.indexQueryLatency), instrument.ErrorCode, func(ctx context.Context) error { var err error - values, err = m.rw.LabelNamesForMetricName(ctx, userID, from, through, metricName) + values, err = m.rw.LabelNamesForMetricName(ctx, userID, from, through, metricName, matchers...) return err }); err != nil { return nil, err diff --git a/pkg/storage/stores/series/series_index_gateway_store.go b/pkg/storage/stores/series/series_index_gateway_store.go index b58979bd11a13..0202494ae6e1d 100644 --- a/pkg/storage/stores/series/series_index_gateway_store.go +++ b/pkg/storage/stores/series/series_index_gateway_store.go @@ -80,11 +80,12 @@ func (c *IndexGatewayClientStore) GetSeries(ctx context.Context, _ string, from, } // LabelNamesForMetricName retrieves all label names for a metric name. -func (c *IndexGatewayClientStore) LabelNamesForMetricName(ctx context.Context, _ string, from, through model.Time, metricName string) ([]string, error) { +func (c *IndexGatewayClientStore) LabelNamesForMetricName(ctx context.Context, _ string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { resp, err := c.client.LabelNamesForMetricName(ctx, &logproto.LabelNamesForMetricNameRequest{ MetricName: metricName, From: from, Through: through, + Matchers: (&syntax.MatchersExpr{Mts: matchers}).String(), }) if err != nil { return nil, err diff --git a/pkg/storage/stores/series/series_index_store.go b/pkg/storage/stores/series/series_index_store.go index 535f6a5249501..c3ef58266e82f 100644 --- a/pkg/storage/stores/series/series_index_store.go +++ b/pkg/storage/stores/series/series_index_store.go @@ -316,14 +316,14 @@ func (c *IndexReaderWriter) chunksToSeries(ctx context.Context, in []logproto.Ch } // LabelNamesForMetricName retrieves all label names for a metric name. -func (c *IndexReaderWriter) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string) ([]string, error) { +func (c *IndexReaderWriter) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, metricName string, matchers ...*labels.Matcher) ([]string, error) { sp, ctx := opentracing.StartSpanFromContext(ctx, "SeriesStore.LabelNamesForMetricName") defer sp.Finish() log := spanlogger.FromContext(ctx) defer log.Span.Finish() // Fetch the series IDs from the index - seriesIDs, err := c.lookupSeriesByMetricNameMatchers(ctx, from, through, userID, metricName, nil) + seriesIDs, err := c.lookupSeriesByMetricNameMatchers(ctx, from, through, userID, metricName, matchers) if err != nil { return nil, err } diff --git a/pkg/storage/stores/series/series_store_test.go b/pkg/storage/stores/series/series_store_test.go index f5948e8ef60d0..15ecb1623eebb 100644 --- a/pkg/storage/stores/series/series_store_test.go +++ b/pkg/storage/stores/series/series_store_test.go @@ -246,14 +246,24 @@ func TestChunkStore_LabelNamesForMetricName(t *testing.T) { for _, tc := range []struct { metricName string expect []string + matchers []*labels.Matcher }{ { `foo`, []string{"bar", "flip", "toms"}, + nil, }, { `bar`, []string{"bar", "toms"}, + nil, + }, + { + `foo`, + []string{"bar", "toms"}, + []*labels.Matcher{ + labels.MustNewMatcher(labels.MatchRegexp, "bar", "beep"), + }, }, } { for _, schema := range schemas { @@ -286,7 +296,7 @@ func TestChunkStore_LabelNamesForMetricName(t *testing.T) { } // Query with ordinary time-range - labelNames1, err := store.LabelNamesForMetricName(ctx, userID, now.Add(-time.Hour), now, tc.metricName) + labelNames1, err := store.LabelNamesForMetricName(ctx, userID, now.Add(-time.Hour), now, tc.metricName, tc.matchers...) require.NoError(t, err) if !reflect.DeepEqual(tc.expect, labelNames1) { @@ -294,7 +304,7 @@ func TestChunkStore_LabelNamesForMetricName(t *testing.T) { } // Pushing end of time-range into future should yield exact same resultset - labelNames2, err := store.LabelNamesForMetricName(ctx, userID, now.Add(-time.Hour), now.Add(time.Hour*24*10), tc.metricName) + labelNames2, err := store.LabelNamesForMetricName(ctx, userID, now.Add(-time.Hour), now.Add(time.Hour*24*10), tc.metricName, tc.matchers...) require.NoError(t, err) if !reflect.DeepEqual(tc.expect, labelNames2) { @@ -302,7 +312,7 @@ func TestChunkStore_LabelNamesForMetricName(t *testing.T) { } // Query with both begin & end of time-range in future should yield empty resultset - labelNames3, err := store.LabelNamesForMetricName(ctx, userID, now.Add(time.Hour), now.Add(time.Hour*2), tc.metricName) + labelNames3, err := store.LabelNamesForMetricName(ctx, userID, now.Add(time.Hour), now.Add(time.Hour*2), tc.metricName, tc.matchers...) require.NoError(t, err) if len(labelNames3) != 0 { t.Fatalf("%s: future query should yield empty resultset ... actually got %v label names: %#v", diff --git a/pkg/storage/stores/shipper/indexshipper/tsdb/index_client.go b/pkg/storage/stores/shipper/indexshipper/tsdb/index_client.go index 47d33fe632faf..4eade57899101 100644 --- a/pkg/storage/stores/shipper/indexshipper/tsdb/index_client.go +++ b/pkg/storage/stores/shipper/indexshipper/tsdb/index_client.go @@ -170,8 +170,8 @@ func (c *IndexClient) LabelValuesForMetricName(ctx context.Context, userID strin } // tsdb no longer uses the __metric_name__="logs" hack, so we can ignore metric names! -func (c *IndexClient) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, _ string) ([]string, error) { - return c.idx.LabelNames(ctx, userID, from, through) +func (c *IndexClient) LabelNamesForMetricName(ctx context.Context, userID string, from, through model.Time, _ string, matchers ...*labels.Matcher) ([]string, error) { + return c.idx.LabelNames(ctx, userID, from, through, matchers...) } func (c *IndexClient) Stats(ctx context.Context, userID string, from, through model.Time, matchers ...*labels.Matcher) (*stats.Stats, error) { diff --git a/pkg/storage/util_test.go b/pkg/storage/util_test.go index 23f89b7a9dfe2..7c325cc4da6bb 100644 --- a/pkg/storage/util_test.go +++ b/pkg/storage/util_test.go @@ -220,7 +220,7 @@ func (m *mockChunkStore) LabelValuesForMetricName(_ context.Context, _ string, _ return nil, nil } -func (m *mockChunkStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string) ([]string, error) { +func (m *mockChunkStore) LabelNamesForMetricName(_ context.Context, _ string, _, _ model.Time, _ string, _ ...*labels.Matcher) ([]string, error) { return nil, nil }