diff --git a/api/dashboards/v1/dashboards.proto b/api/dashboards/v1/dashboards.proto index 379ec52..d944558 100644 --- a/api/dashboards/v1/dashboards.proto +++ b/api/dashboards/v1/dashboards.proto @@ -82,7 +82,7 @@ message DeleteRequest { message DeleteResponse {} -message SearchRequest{ +message SearchRequest { message Filter { optional string owner_name = 1; } @@ -93,7 +93,7 @@ message SearchRequest{ optional Filter filter = 4; } -message SearchResponse{ +message SearchResponse { message Dashboard { string uuid = 1; string name = 2; @@ -101,4 +101,4 @@ message SearchResponse{ } repeated Dashboard dashboards = 1; -} \ No newline at end of file +} diff --git a/api/massexport/v1/massexport.proto b/api/massexport/v1/massexport.proto index 7540dc2..ff2104f 100644 --- a/api/massexport/v1/massexport.proto +++ b/api/massexport/v1/massexport.proto @@ -2,8 +2,8 @@ syntax = "proto3"; package massexport.v1; -import "google/protobuf/timestamp.proto"; import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; option go_package = "github.com/ozontech/seq-ui/pkg/massexport/v1;massexport"; diff --git a/api/seqapi/v1/seq_api.proto b/api/seqapi/v1/seq_api.proto index 76c6d71..ab53f02 100644 --- a/api/seqapi/v1/seq_api.proto +++ b/api/seqapi/v1/seq_api.proto @@ -128,6 +128,7 @@ message SearchRequest { repeated AggregationQuery aggregations = 8; Order order = 9; string offset_id = 10; + uint32 downsample = 11; } message SearchResponse { @@ -152,6 +153,7 @@ message GetHistogramRequest { string interval = 2; google.protobuf.Timestamp from = 3; google.protobuf.Timestamp to = 4; + uint32 downsample = 5; } message GetHistogramResponse { @@ -166,6 +168,7 @@ message GetAggregationRequest { google.protobuf.Timestamp to = 3; string agg_field = 4 [deprecated = true]; repeated AggregationQuery aggregations = 5; + uint32 downsample = 6; } message GetAggregationResponse { @@ -207,6 +210,7 @@ message ExportRequest { int32 offset = 5; ExportFormat format = 6; repeated string fields = 7; + uint32 downsample = 8; } message GetLimitsRequest {} @@ -257,6 +261,7 @@ message StartAsyncSearchRequest { bool with_docs = 7; int32 size = 8; string meta = 9; + uint32 downsample = 10; } message StartAsyncSearchResponse { diff --git a/api/userprofile/v1/userprofile.proto b/api/userprofile/v1/userprofile.proto index 4391901..fe51f5d 100644 --- a/api/userprofile/v1/userprofile.proto +++ b/api/userprofile/v1/userprofile.proto @@ -36,7 +36,6 @@ message UpdateUserProfileRequest { message UpdateUserProfileResponse {} - message GetFavoriteQueriesRequest {} message GetFavoriteQueriesResponse { @@ -66,7 +65,6 @@ message DeleteFavoriteQueryRequest { message DeleteFavoriteQueryResponse {} - message GetDashboardsRequest {} message GetDashboardsResponse { @@ -109,4 +107,4 @@ message DeleteDashboardRequest { string uuid = 1; } -message DeleteDashboardResponse {} \ No newline at end of file +message DeleteDashboardResponse {} diff --git a/docs/en/03-seq-api.md b/docs/en/03-seq-api.md index 81a0597..ad71231 100644 --- a/docs/en/03-seq-api.md +++ b/docs/en/03-seq-api.md @@ -72,6 +72,8 @@ Returns a list of events that satisfy the [search query](https://github.com/ozon - `offset` (*int*, *optional*): Search offset. - `withTotal` (*bool*, *optional*): If set, returns the total number of events found. - `order` (*enum*, *optional*): Search order. One of `"desc"|"asc"` (`"desc"` by default). +- `offset_id` (*string*, *optional*): Pagination cursor. The response contains events that come after specified identifier. Mutually exclusive with offset: only one of these fields can be set per request. +- `downsample` (*uint32*, *optional*): Random sampling coefficient. Higher values yield a smaller fraction of returned events. #### Request @@ -178,6 +180,7 @@ Downloads events to file in the specified format. - `limit` (*int*, *required*): Export limit. - `offset` (*int*, *optional*): Export offset. - `fields` (*[]string*, *optional*): List of fields to export (only for `format:csv`, must be non-empty in this case). +- `downsample` (*uint32*, *optional*): Random sampling coefficient. Higher values yield a smaller fraction of returned events. #### Request @@ -252,6 +255,7 @@ Calculates aggregations based on events that satisfy the search query. - `field` (*string*, *required*): Aggregation calculation field. - `group_by` (*string*, *optional*): Field for grouping the aggregation results. - `quantiles` (*[]int*, *optional*): List of quantiles (only for `agg_func:quantile`, must be non-empty in this case). +- `downsample` (*uint32*, *optional*): Random sampling coefficient. Higher values yield a smaller fraction of returned events. #### Request @@ -414,6 +418,7 @@ Calculates histogram based on events that satisfy the search query. - `from` (*string*, *required*): Timestamp of the start of search in `date-time` format. - `to` (*string*, *required*): Timestamp of the end of search in `date-time` format. - `interval` (*string*, *required*): Interval for calculating the bucket in `duration` format. +- `downsample` (*uint32*, *optional*): Random sampling coefficient. Higher values yield a smaller fraction of returned events. #### Request diff --git a/docs/ru/03-seq-api.md b/docs/ru/03-seq-api.md index 361b936..4e724ea 100644 --- a/docs/ru/03-seq-api.md +++ b/docs/ru/03-seq-api.md @@ -72,6 +72,9 @@ curl -X GET \ - `offset` (*int*, *optional*): Смещение поиска. - `withTotal` (*bool*, *optional*): Если задано, то возвращает общее количество найденных событий. - `order` (*enum*, *optional*): Порядок поиска. Одно из `"desc"|"asc"` (по умолчанию `"desc"`). +- `offset_id` (*string*, *optional*): Курсор пагинации. Ответ запроса содержит события, следующие за указанным идентификатором. +Альтернатива `offset`: в одном запросе можно задать только одно из этих полей. +- `downsample` (*uint32*, *optional*): коэффициент случайного семплирования результата. Чем больше значение, тем меньше доля возвращаемых событий. #### Запрос @@ -178,6 +181,7 @@ curl -X GET \ - `limit` (*int*, *required*): Ограничение поиска. - `offset` (*int*, *optional*): Смещение поиска. - `fields` (*[]string*, *optional*): Список полей для экспорта (только для `format:csv`, в этом случае список должен быть непустым). +- `downsample` (*uint32*, *optional*): коэффициент случайного семплирования результата. Чем больше значение, тем меньше доля возвращаемых событий. #### Запрос @@ -252,6 +256,7 @@ level,message - `field` (*string*, *required*): Поле для расчета агрегации. - `group_by` (*string*, *optional*): Поле для группировки результатов агрегирования. - `quantiles` (*[]int*, *optional*): Список квантилей (только для `agg_func:quantile`, в этом случае список должен быть непустым). +- `downsample` (*uint32*, *optional*): коэффициент случайного семплирования результата. Чем больше значение, тем меньше доля возвращаемых событий. #### Запрос @@ -414,6 +419,7 @@ curl -X POST \ - `from` (*string*, *required*): Временная метка начала поиска в `date-time` формате. - `to` (*string*, *required*): Временная метка окончания поиска в `date-time` формате. - `interval` (*string*, *required*): Интервал гистограммы в `duration` формате. +- `downsample` (*uint32*, *optional*): коэффициент случайного семплирования результата. Чем больше значение, тем меньше доля возвращаемых событий. #### Запрос diff --git a/internal/api/seqapi/v1/grpc/aggregation.go b/internal/api/seqapi/v1/grpc/aggregation.go index 369b48c..e8fd760 100644 --- a/internal/api/seqapi/v1/grpc/aggregation.go +++ b/internal/api/seqapi/v1/grpc/aggregation.go @@ -42,6 +42,10 @@ func (a *API) GetAggregation(ctx context.Context, req *seqapi.GetAggregationRequ Key: "aggregations", Value: attribute.StringValue(string(aggregations)), }, + { + Key: "downsample", + Value: attribute.IntValue(int(req.GetDownsample())), + }, } if env != "" { diff --git a/internal/api/seqapi/v1/grpc/histogram.go b/internal/api/seqapi/v1/grpc/histogram.go index c196ba8..0d82303 100644 --- a/internal/api/seqapi/v1/grpc/histogram.go +++ b/internal/api/seqapi/v1/grpc/histogram.go @@ -34,6 +34,10 @@ func (a *API) GetHistogram(ctx context.Context, req *seqapi.GetHistogramRequest) Key: "interval", Value: attribute.StringValue(req.GetInterval()), }, + { + Key: "downsample", + Value: attribute.IntValue(int(req.GetDownsample())), + }, } if env != "" { diff --git a/internal/api/seqapi/v1/grpc/search.go b/internal/api/seqapi/v1/grpc/search.go index 7adb6a7..7fb45fb 100644 --- a/internal/api/seqapi/v1/grpc/search.go +++ b/internal/api/seqapi/v1/grpc/search.go @@ -53,6 +53,10 @@ func (a *API) Search(ctx context.Context, req *seqapi.SearchRequest) (*seqapi.Se Key: "offset_id", Value: attribute.StringValue(req.GetOffsetId()), }, + { + Key: "downsample", + Value: attribute.IntValue(int(req.GetDownsample())), + }, } if env != "" { diff --git a/internal/api/seqapi/v1/grpc/start_async_search.go b/internal/api/seqapi/v1/grpc/start_async_search.go index 4c31659..b2d6381 100644 --- a/internal/api/seqapi/v1/grpc/start_async_search.go +++ b/internal/api/seqapi/v1/grpc/start_async_search.go @@ -50,6 +50,10 @@ func (a *API) StartAsyncSearch( Key: "size", Value: attribute.Int64Value(int64(req.GetSize())), }, + { + Key: "downsample", + Value: attribute.IntValue(int(req.GetDownsample())), + }, } if req.Hist != nil && req.Hist.Interval != "" { spanAttributes = append(spanAttributes, attribute.KeyValue{ diff --git a/internal/api/seqapi/v1/http/aggregation.go b/internal/api/seqapi/v1/http/aggregation.go index dfd9605..b4ffebb 100644 --- a/internal/api/seqapi/v1/http/aggregation.go +++ b/internal/api/seqapi/v1/http/aggregation.go @@ -63,6 +63,10 @@ func (a *API) serveGetAggregation(w http.ResponseWriter, r *http.Request) { Key: "aggregations", Value: attribute.StringValue(string(aggsRaw)), }, + { + Key: "downsample", + Value: attribute.IntValue(int(httpReq.Downsample)), + }, } if env != "" { @@ -202,6 +206,7 @@ type getAggregationRequest struct { To time.Time `json:"to" format:"date-time"` AggField string `json:"aggField"` Aggregations aggregationQueries `json:"aggregations"` + Downsample uint32 `json:"downsample"` } // @name seqapi.v1.GetAggregationRequest func (r getAggregationRequest) toProto() *seqapi.GetAggregationRequest { @@ -211,6 +216,7 @@ func (r getAggregationRequest) toProto() *seqapi.GetAggregationRequest { To: timestamppb.New(r.To), AggField: r.AggField, Aggregations: r.Aggregations.toProto(), + Downsample: r.Downsample, } } diff --git a/internal/api/seqapi/v1/http/export.go b/internal/api/seqapi/v1/http/export.go index fa2fa43..379f17b 100644 --- a/internal/api/seqapi/v1/http/export.go +++ b/internal/api/seqapi/v1/http/export.go @@ -79,6 +79,10 @@ func (a *API) serveExport(w http.ResponseWriter, r *http.Request) { Key: "fields", Value: attribute.StringSliceValue(httpReq.Fields), }, + { + Key: "downsample", + Value: attribute.IntValue(int(httpReq.Downsample)), + }, } if env != "" { @@ -144,24 +148,26 @@ func (f exportFormat) toProto() seqapi.ExportFormat { } type exportRequest struct { - Query string `json:"query"` - From time.Time `json:"from" format:"date-time"` - To time.Time `json:"to" format:"date-time"` - Limit int32 `json:"limit" format:"int32"` - Offset int32 `json:"offset" format:"int32"` - Format exportFormat `json:"format" default:"jsonl"` - Fields []string `json:"fields,omitempty"` + Query string `json:"query"` + From time.Time `json:"from" format:"date-time"` + To time.Time `json:"to" format:"date-time"` + Limit int32 `json:"limit" format:"int32"` + Offset int32 `json:"offset" format:"int32"` + Format exportFormat `json:"format" default:"jsonl"` + Fields []string `json:"fields,omitempty"` + Downsample uint32 `json:"downsample"` } // @name seqapi.v1.ExportRequest func (r exportRequest) toProto() *seqapi.ExportRequest { return &seqapi.ExportRequest{ - Query: r.Query, - From: timestamppb.New(r.From), - To: timestamppb.New(r.To), - Limit: r.Limit, - Offset: r.Offset, - Format: r.Format.toProto(), - Fields: r.Fields, + Query: r.Query, + From: timestamppb.New(r.From), + To: timestamppb.New(r.To), + Limit: r.Limit, + Offset: r.Offset, + Format: r.Format.toProto(), + Fields: r.Fields, + Downsample: r.Downsample, } } diff --git a/internal/api/seqapi/v1/http/fetch_async_search_result_test.go b/internal/api/seqapi/v1/http/fetch_async_search_result_test.go index c884917..3e0e19d 100644 --- a/internal/api/seqapi/v1/http/fetch_async_search_result_test.go +++ b/internal/api/seqapi/v1/http/fetch_async_search_result_test.go @@ -174,7 +174,7 @@ func TestServeFetchAsyncSearchResult(t *testing.T) { Meta: meta, }, }, - wantRespBody: `{"status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","aggregations":[{"field":"x","group_by":"level","agg_func":"avg","quantiles":[0.9,0.5]},{"field":"y","group_by":"level","agg_func":"sum","interval":"30s"}],"histogram":{"interval":"1s"},"with_docs":true,"size":100},"response":{"events":[{"id":"017a854298010000-850287cfa326a7fc","data":{"level":"3","message":"some error","x":"2"},"time":"2025-08-06T17:51:12.000000123Z"},{"id":"017a854298010000-8502fe7f2aa33df3","data":{"level":"2","message":"some error 2","x":"8"},"time":"2025-08-06T17:50:12.000000123Z"}],"histogram":{"buckets":[{"key":"1","docCount":"7"},{"key":"2","docCount":"9"}]},"aggregations":[{"buckets":[{"key":"3","value":2,"quantiles":[2,1]},{"key":"2","value":8,"not_exists":1,"quantiles":[7,4]}]}],"aggregations_ts":[{"data":{"result":[{"metric":{"level":"33"},"values":[{"timestamp":1754502702,"value":2},{"timestamp":1754502732,"value":5}]},{"metric":{"level":"22"},"values":[{"timestamp":1754502672,"value":8}]}]}}],"total":"2","error":{"code":"ERROR_CODE_UNSPECIFIED","message":"some error"}},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","meta":"{\"some\":\"meta\"}","error":{"code":"ERROR_CODE_NO"}}`, + wantRespBody: `{"status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","aggregations":[{"field":"x","group_by":"level","agg_func":"avg","quantiles":[0.9,0.5]},{"field":"y","group_by":"level","agg_func":"sum","interval":"30s"}],"histogram":{"interval":"1s"},"with_docs":true,"size":100,"downsample":0},"response":{"events":[{"id":"017a854298010000-850287cfa326a7fc","data":{"level":"3","message":"some error","x":"2"},"time":"2025-08-06T17:51:12.000000123Z"},{"id":"017a854298010000-8502fe7f2aa33df3","data":{"level":"2","message":"some error 2","x":"8"},"time":"2025-08-06T17:50:12.000000123Z"}],"histogram":{"buckets":[{"key":"1","docCount":"7"},{"key":"2","docCount":"9"}]},"aggregations":[{"buckets":[{"key":"3","value":2,"quantiles":[2,1]},{"key":"2","value":8,"not_exists":1,"quantiles":[7,4]}]}],"aggregations_ts":[{"data":{"result":[{"metric":{"level":"33"},"values":[{"timestamp":1754502702,"value":2},{"timestamp":1754502732,"value":5}]},{"metric":{"level":"22"},"values":[{"timestamp":1754502672,"value":8}]}]}}],"total":"2","error":{"code":"ERROR_CODE_UNSPECIFIED","message":"some error"}},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","meta":"{\"some\":\"meta\"}","error":{"code":"ERROR_CODE_NO"}}`, wantStatus: http.StatusOK, }, { @@ -238,7 +238,7 @@ func TestServeFetchAsyncSearchResult(t *testing.T) { Meta: meta, }, }, - wantRespBody: `{"status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100},"response":{"events":[{"id":"017a854298010000-850287cfa326a7fc","data":{"level":"3","message":"some error","x":"2"},"time":"2025-08-06T17:51:12.000000123Z"},{"id":"017a854298010000-8502fe7f2aa33df3","data":{"level":"2","message":"some error 2","x":"8"},"time":"2025-08-06T17:50:12.000000123Z"}],"total":"2","error":{"code":"ERROR_CODE_UNSPECIFIED","message":"some error"}},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","meta":"{\"some\":\"meta\"}","error":{"code":"ERROR_CODE_PARTIAL_RESPONSE","message":"partial response"}}`, + wantRespBody: `{"status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100,"downsample":0},"response":{"events":[{"id":"017a854298010000-850287cfa326a7fc","data":{"level":"3","message":"some error","x":"2"},"time":"2025-08-06T17:51:12.000000123Z"},{"id":"017a854298010000-8502fe7f2aa33df3","data":{"level":"2","message":"some error 2","x":"8"},"time":"2025-08-06T17:50:12.000000123Z"}],"total":"2","error":{"code":"ERROR_CODE_UNSPECIFIED","message":"some error"}},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","meta":"{\"some\":\"meta\"}","error":{"code":"ERROR_CODE_PARTIAL_RESPONSE","message":"partial response"}}`, wantStatus: http.StatusOK, }, { diff --git a/internal/api/seqapi/v1/http/get_async_searches_list.go b/internal/api/seqapi/v1/http/get_async_searches_list.go index 50e6161..18e71c5 100644 --- a/internal/api/seqapi/v1/http/get_async_searches_list.go +++ b/internal/api/seqapi/v1/http/get_async_searches_list.go @@ -176,6 +176,7 @@ func startAsyncSearchRequestFromProto(r *seqapi.StartAsyncSearchRequest) startAs Histogram: hist, WithDocs: r.WithDocs, Size: r.Size, + Downsample: r.Downsample, } } diff --git a/internal/api/seqapi/v1/http/get_async_searches_list_test.go b/internal/api/seqapi/v1/http/get_async_searches_list_test.go index 1811ae6..580c395 100644 --- a/internal/api/seqapi/v1/http/get_async_searches_list_test.go +++ b/internal/api/seqapi/v1/http/get_async_searches_list_test.go @@ -66,12 +66,13 @@ func TestServeGetAsyncSearchesList(t *testing.T) { SearchId: mockSearchID1, Status: seqapi.AsyncSearchStatus_ASYNC_SEARCH_STATUS_DONE, Request: &seqapi.StartAsyncSearchRequest{ - Retention: durationpb.New(60 * time.Second), - Query: "message:error", - From: timestamppb.New(mockTime.Add(-15 * time.Minute)), - To: timestamppb.New(mockTime), - WithDocs: true, - Size: 100, + Retention: durationpb.New(60 * time.Second), + Query: "message:error", + From: timestamppb.New(mockTime.Add(-15 * time.Minute)), + To: timestamppb.New(mockTime), + WithDocs: true, + Size: 100, + Downsample: 2, }, StartedAt: timestamppb.New(mockTime.Add(-30 * time.Second)), ExpiresAt: timestamppb.New(mockTime.Add(30 * time.Second)), @@ -99,7 +100,8 @@ func TestServeGetAsyncSearchesList(t *testing.T) { Hist: &seqapi.StartAsyncSearchRequest_HistQuery{ Interval: "1s", }, - WithDocs: false, + WithDocs: false, + Downsample: 3, }, StartedAt: timestamppb.New(mockTime.Add(-60 * time.Second)), ExpiresAt: timestamppb.New(mockTime.Add(300 * time.Second)), @@ -128,7 +130,7 @@ func TestServeGetAsyncSearchesList(t *testing.T) { }, searchIDs: []string{mockSearchID1, mockSearchID2}, }, - wantRespBody: `{"searches":[{"search_id":"c9a34cf8-4c66-484e-9cc2-42979d848656","status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","owner_name":"some_user_1","error":"some error"},{"search_id":"9e4c068e-d4f4-4a5d-be27-a6524a70d70d","status":"canceled","request":{"retention":"seconds:360","query":"message:error and level:3","from":"2025-08-06T16:52:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","aggregations":[{"field":"x","group_by":"level","agg_func":"avg","interval":"30s"}],"histogram":{"interval":"1s"},"with_docs":false,"size":0},"started_at":"2025-08-06T17:51:12.000000123Z","expires_at":"2025-08-06T17:57:12.000000123Z","canceled_at":"2025-08-06T17:52:12.000000123Z","progress":1,"disk_usage":"256","owner_name":"some_user_2"}],"error":{"code":"ERROR_CODE_NO"}}`, + wantRespBody: `{"searches":[{"search_id":"c9a34cf8-4c66-484e-9cc2-42979d848656","status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100,"downsample":2},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","owner_name":"some_user_1","error":"some error"},{"search_id":"9e4c068e-d4f4-4a5d-be27-a6524a70d70d","status":"canceled","request":{"retention":"seconds:360","query":"message:error and level:3","from":"2025-08-06T16:52:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","aggregations":[{"field":"x","group_by":"level","agg_func":"avg","interval":"30s"}],"histogram":{"interval":"1s"},"with_docs":false,"size":0,"downsample":3},"started_at":"2025-08-06T17:51:12.000000123Z","expires_at":"2025-08-06T17:57:12.000000123Z","canceled_at":"2025-08-06T17:52:12.000000123Z","progress":1,"disk_usage":"256","owner_name":"some_user_2"}],"error":{"code":"ERROR_CODE_NO"}}`, wantStatus: http.StatusOK, }, { @@ -177,7 +179,7 @@ func TestServeGetAsyncSearchesList(t *testing.T) { }, searchIDs: []string{mockSearchID1}, }, - wantRespBody: `{"searches":[{"search_id":"c9a34cf8-4c66-484e-9cc2-42979d848656","status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","owner_name":"some_user_1"}],"error":{"code":"ERROR_CODE_NO"}}`, + wantRespBody: `{"searches":[{"search_id":"c9a34cf8-4c66-484e-9cc2-42979d848656","status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100,"downsample":0},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","owner_name":"some_user_1"}],"error":{"code":"ERROR_CODE_NO"}}`, wantStatus: http.StatusOK, }, { @@ -220,7 +222,7 @@ func TestServeGetAsyncSearchesList(t *testing.T) { }, searchIDs: []string{mockSearchID1}, }, - wantRespBody: `{"searches":[{"search_id":"c9a34cf8-4c66-484e-9cc2-42979d848656","status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","owner_name":"some_user_1"}],"error":{"code":"ERROR_CODE_PARTIAL_RESPONSE","message":"partial response"}}`, + wantRespBody: `{"searches":[{"search_id":"c9a34cf8-4c66-484e-9cc2-42979d848656","status":"done","request":{"retention":"seconds:60","query":"message:error","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100,"downsample":0},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","owner_name":"some_user_1"}],"error":{"code":"ERROR_CODE_PARTIAL_RESPONSE","message":"partial response"}}`, wantStatus: http.StatusOK, }, { @@ -280,7 +282,7 @@ func TestServeGetAsyncSearchesList(t *testing.T) { }, searchIDs: []string{mockSearchID1}, }, - wantRespBody: `{"searches":[{"search_id":"c9a34cf8-4c66-484e-9cc2-42979d848656","status":"done","request":{"retention":"seconds:60","query":"` + TruncatedQuery + `...","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","owner_name":"some_user_1"}],"error":{"code":"ERROR_CODE_PARTIAL_RESPONSE","message":"partial response"}}`, + wantRespBody: `{"searches":[{"search_id":"c9a34cf8-4c66-484e-9cc2-42979d848656","status":"done","request":{"retention":"seconds:60","query":"` + TruncatedQuery + `...","from":"2025-08-06T17:37:12.000000123Z","to":"2025-08-06T17:52:12.000000123Z","with_docs":true,"size":100,"downsample":0},"started_at":"2025-08-06T17:51:42.000000123Z","expires_at":"2025-08-06T17:52:42.000000123Z","progress":1,"disk_usage":"512","owner_name":"some_user_1"}],"error":{"code":"ERROR_CODE_PARTIAL_RESPONSE","message":"partial response"}}`, wantStatus: http.StatusOK, }, } diff --git a/internal/api/seqapi/v1/http/histogram.go b/internal/api/seqapi/v1/http/histogram.go index a48cf98..c163b13 100644 --- a/internal/api/seqapi/v1/http/histogram.go +++ b/internal/api/seqapi/v1/http/histogram.go @@ -56,6 +56,10 @@ func (a *API) serveGetHistogram(w http.ResponseWriter, r *http.Request) { Key: "interval", Value: attribute.StringValue(httpReq.Interval), }, + { + Key: "downsample", + Value: attribute.IntValue(int(httpReq.Downsample)), + }, } if env != "" { @@ -80,18 +84,20 @@ func (a *API) serveGetHistogram(w http.ResponseWriter, r *http.Request) { } type getHistogramRequest struct { - Query string `json:"query"` - From time.Time `json:"from" format:"date-time"` - To time.Time `json:"to" format:"date-time"` - Interval string `json:"interval"` + Query string `json:"query"` + From time.Time `json:"from" format:"date-time"` + To time.Time `json:"to" format:"date-time"` + Interval string `json:"interval"` + Downsample uint32 `json:"downsample"` } // @name seqapi.v1.GetHistogramRequest func (r getHistogramRequest) toProto() *seqapi.GetHistogramRequest { return &seqapi.GetHistogramRequest{ - Query: r.Query, - From: timestamppb.New(r.From), - To: timestamppb.New(r.To), - Interval: r.Interval, + Query: r.Query, + From: timestamppb.New(r.From), + To: timestamppb.New(r.To), + Interval: r.Interval, + Downsample: r.Downsample, } } diff --git a/internal/api/seqapi/v1/http/search.go b/internal/api/seqapi/v1/http/search.go index a526a58..fd19854 100644 --- a/internal/api/seqapi/v1/http/search.go +++ b/internal/api/seqapi/v1/http/search.go @@ -77,6 +77,10 @@ func (a *API) serveSearch(w http.ResponseWriter, r *http.Request) { Key: "offset_id", Value: attribute.StringValue(httpReq.OffsetID), }, + { + Key: "downsample", + Value: attribute.IntValue(int(httpReq.Downsample)), + }, } if env != "" { @@ -172,8 +176,9 @@ type searchRequest struct { Histogram struct { Interval string `json:"interval"` } `json:"histogram"` - Order order `json:"order" default:"desc"` - OffsetID string `json:"offset_id"` + Order order `json:"order" default:"desc"` + OffsetID string `json:"offset_id"` + Downsample uint32 `json:"downsample"` } // @name seqapi.v1.SearchRequest func (r searchRequest) toProto() *seqapi.SearchRequest { @@ -185,6 +190,7 @@ func (r searchRequest) toProto() *seqapi.SearchRequest { Offset: r.Offset, OffsetId: r.OffsetID, WithTotal: r.WithTotal, + Downsample: r.Downsample, Aggregations: r.Aggregations.toProto(), Order: r.Order.toProto(), } diff --git a/internal/api/seqapi/v1/http/start_async_search.go b/internal/api/seqapi/v1/http/start_async_search.go index 0904cc1..3262164 100644 --- a/internal/api/seqapi/v1/http/start_async_search.go +++ b/internal/api/seqapi/v1/http/start_async_search.go @@ -86,6 +86,10 @@ func (a *API) serveStartAsyncSearch(w http.ResponseWriter, r *http.Request) { Key: "size", Value: attribute.Int64Value(int64(httpReq.Size)), }, + { + Key: "downsample", + Value: attribute.IntValue(int(httpReq.Downsample)), + }, } if httpReq.Histogram != nil && httpReq.Histogram.Interval != "" { spanAttributes = append(spanAttributes, attribute.KeyValue{ @@ -132,18 +136,20 @@ type startAsyncSearchRequest struct { WithDocs bool `json:"with_docs"` Size int32 `json:"size"` Meta string `json:"meta,omitempty"` + Downsample uint32 `json:"downsample"` } // @name seqapi.v1.StartAsyncSearchRequest func (r startAsyncSearchRequest) toProto(parsedRetention time.Duration) *seqapi.StartAsyncSearchRequest { req := &seqapi.StartAsyncSearchRequest{ - Retention: durationpb.New(parsedRetention), - Query: r.Query, - From: timestamppb.New(r.From), - To: timestamppb.New(r.To), - Aggs: r.Aggregations.toProto(), - WithDocs: r.WithDocs, - Size: r.Size, - Meta: r.Meta, + Retention: durationpb.New(parsedRetention), + Query: r.Query, + From: timestamppb.New(r.From), + To: timestamppb.New(r.To), + Aggs: r.Aggregations.toProto(), + WithDocs: r.WithDocs, + Size: r.Size, + Meta: r.Meta, + Downsample: r.Downsample, } if r.Histogram != nil && r.Histogram.Interval != "" { req.Hist = &seqapi.StartAsyncSearchRequest_HistQuery{ diff --git a/internal/pkg/client/seqdb/export_test.go b/internal/pkg/client/seqdb/export_test.go index fe6e7b7..0b8e9ac 100644 --- a/internal/pkg/client/seqdb/export_test.go +++ b/internal/pkg/client/seqdb/export_test.go @@ -39,7 +39,7 @@ func Test_GRPCClient_Export(t *testing.T) { if req != nil { proxyReq = &seqproxyapi.ExportRequest{ - Query: makeProxySearchQuery(req.Query, req.From, req.To), + Query: makeProxySearchQuery(req.Query, req.From, req.To, req.Downsample), Size: int64(req.Limit), Offset: int64(req.Offset), } @@ -162,6 +162,23 @@ func Test_GRPCClient_Export(t *testing.T) { }, wantResp: "key1,key3\r\n\"val1,a\",\"test \"\"quoted\"\"\"\r\n", }, + { + name: "ok_downsample", + req: &seqapi.ExportRequest{ + Query: "test_ok_escaped", + From: timestamppb.New(from), + To: timestamppb.New(to), + Limit: limit, + Offset: 0, + Format: seqapi.ExportFormat_EXPORT_FORMAT_CSV, + Fields: []string{"key1", "key3"}, + Downsample: 10, + }, + docs: []seqproxyapi.Document{ + {Id: "test1", Data: []byte(`{"key1":"val1,a","key2":"val2,b","key3":"test \"quoted\""}`), Time: eventTimePB}, + }, + wantResp: "key1,key3\r\n\"val1,a\",\"test \"\"quoted\"\"\"\r\n", + }, { name: "err_proxy", req: &seqapi.ExportRequest{ @@ -185,18 +202,20 @@ func Test_GRPCClient_Export(t *testing.T) { wantErr: streamErrRecv, }, } + for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() ctx := context.Background() ctrl := gomock.NewController(t) mArgs := prepareMockArgs(ctrl, tt.req, tt.docs, tt.wantErr) - seqProxyMock := mock.NewMockSeqProxyApiClient(ctrl) - seqProxyMock.EXPECT().Export(ctx, mArgs.req). - Return(mArgs.resp, mArgs.err).Times(1) + + seqProxyMock.EXPECT(). + Export(ctx, mArgs.req). + Return(mArgs.resp, mArgs.err). + Times(1) c := initGRPCClient(seqProxyMock) diff --git a/internal/pkg/client/seqdb/get_aggregation_test.go b/internal/pkg/client/seqdb/get_aggregation_test.go index 8e6b9f4..f8e7587 100644 --- a/internal/pkg/client/seqdb/get_aggregation_test.go +++ b/internal/pkg/client/seqdb/get_aggregation_test.go @@ -31,7 +31,7 @@ func Test_GRPCClient_GetAggregation(t *testing.T) { if req != nil { proxyReq = &seqproxyapi.GetAggregationRequest{ - Query: makeProxySearchQuery(req.Query, req.From, req.To), + Query: makeProxySearchQuery(req.Query, req.From, req.To, req.Downsample), } if len(req.Aggregations) == 0 && req.AggField != "" { @@ -153,6 +153,23 @@ func Test_GRPCClient_GetAggregation(t *testing.T) { }, }, }, + { + name: "ok_downsample", + req: &seqapi.GetAggregationRequest{ + Query: "test_downsample", + From: timestamppb.New(from), + To: timestamppb.New(to), + AggField: "test1", + Downsample: 10, + }, + wantResp: &seqapi.GetAggregationResponse{ + Aggregation: makeAggregation(2, nil), + Aggregations: makeAggregations(1, 2, nil), + Error: &seqapi.Error{ + Code: seqapi.ErrorCode_ERROR_CODE_NO, + }, + }, + }, { name: "ok_partial_response", req: &seqapi.GetAggregationRequest{ @@ -180,18 +197,20 @@ func Test_GRPCClient_GetAggregation(t *testing.T) { wantErr: errors.New("proxy error"), }, } + for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() ctx := context.Background() mArgs := prepareMockArgs(tt.req, tt.wantResp, tt.wantErr) - ctrl := gomock.NewController(t) seqProxyMock := mock.NewMockSeqProxyApiClient(ctrl) - seqProxyMock.EXPECT().GetAggregation(ctx, mArgs.req). - Return(mArgs.resp, mArgs.err).Times(1) + + seqProxyMock.EXPECT(). + GetAggregation(ctx, mArgs.req). + Return(mArgs.resp, mArgs.err). + Times(1) c := initGRPCClient(seqProxyMock) diff --git a/internal/pkg/client/seqdb/get_event_test.go b/internal/pkg/client/seqdb/get_event_test.go index 15acffb..b53b8c1 100644 --- a/internal/pkg/client/seqdb/get_event_test.go +++ b/internal/pkg/client/seqdb/get_event_test.go @@ -159,17 +159,18 @@ func Test_GRPCClient_GetEvent(t *testing.T) { wantErr: streamErrConvert, }, } + for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) - mArgs := prepareMockArgs(ctrl, tt.req, tt.doc, tt.wantErr) - seqProxyMock := mock.NewMockSeqProxyApiClient(ctrl) - seqProxyMock.EXPECT().Fetch(gomock.Any(), mArgs.req). - Return(mArgs.resp, mArgs.err).Times(1) + + seqProxyMock.EXPECT(). + Fetch(gomock.Any(), mArgs.req). + Return(mArgs.resp, mArgs.err). + Times(1) c := initGRPCClient(seqProxyMock) diff --git a/internal/pkg/client/seqdb/get_fields_test.go b/internal/pkg/client/seqdb/get_fields_test.go index 31e6faf..942e990 100644 --- a/internal/pkg/client/seqdb/get_fields_test.go +++ b/internal/pkg/client/seqdb/get_fields_test.go @@ -55,18 +55,20 @@ func Test_GRPCClient_GetFields(t *testing.T) { wantErr: errors.New("proxy error"), }, } + for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() ctx := context.Background() mArgs := prepareMockArgs(tt.wantFields, tt.wantErr) - ctrl := gomock.NewController(t) seqProxyMock := mock.NewMockSeqProxyApiClient(ctrl) - seqProxyMock.EXPECT().Mapping(ctx, &seqproxyapi.MappingRequest{}). - Return(mArgs.resp, mArgs.err).Times(1) + + seqProxyMock.EXPECT(). + Mapping(ctx, &seqproxyapi.MappingRequest{}). + Return(mArgs.resp, mArgs.err). + Times(1) c := initGRPCClient(seqProxyMock) diff --git a/internal/pkg/client/seqdb/get_histogram_test.go b/internal/pkg/client/seqdb/get_histogram_test.go index 481f7e0..d32d4cb 100644 --- a/internal/pkg/client/seqdb/get_histogram_test.go +++ b/internal/pkg/client/seqdb/get_histogram_test.go @@ -31,7 +31,7 @@ func Test_GRPCClient_GetHistogram(t *testing.T) { if req != nil { proxyReq = &seqproxyapi.GetHistogramRequest{ - Query: makeProxySearchQuery(req.Query, req.From, req.To), + Query: makeProxySearchQuery(req.Query, req.From, req.To, req.Downsample), Hist: &seqproxyapi.HistQuery{ Interval: req.Interval, }, @@ -89,6 +89,22 @@ func Test_GRPCClient_GetHistogram(t *testing.T) { }, }, }, + { + name: "ok_downsample", + req: &seqapi.GetHistogramRequest{ + Query: "test_downsample", + From: timestamppb.New(from), + To: timestamppb.New(to), + Interval: "5s", + Downsample: 3, + }, + wantResp: &seqapi.GetHistogramResponse{ + Histogram: makeHistogram(2), + Error: &seqapi.Error{ + Code: seqapi.ErrorCode_ERROR_CODE_NO, + }, + }, + }, { name: "ok_partial_response", req: &seqapi.GetHistogramRequest{ @@ -115,18 +131,20 @@ func Test_GRPCClient_GetHistogram(t *testing.T) { wantErr: errors.New("proxy error"), }, } + for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() ctx := context.Background() mArgs := prepareMockArgs(tt.req, tt.wantResp, tt.wantErr) - ctrl := gomock.NewController(t) seqProxyMock := mock.NewMockSeqProxyApiClient(ctrl) - seqProxyMock.EXPECT().GetHistogram(ctx, mArgs.req). - Return(mArgs.resp, mArgs.err).Times(1) + + seqProxyMock.EXPECT(). + GetHistogram(ctx, mArgs.req). + Return(mArgs.resp, mArgs.err). + Times(1) c := initGRPCClient(seqProxyMock) diff --git a/internal/pkg/client/seqdb/grpc_types.go b/internal/pkg/client/seqdb/grpc_types.go index 19dad20..9d1cf65 100644 --- a/internal/pkg/client/seqdb/grpc_types.go +++ b/internal/pkg/client/seqdb/grpc_types.go @@ -143,6 +143,7 @@ type ( GetQuery() string GetFrom() *timestamppb.Timestamp GetTo() *timestamppb.Timestamp + GetDownsample() uint32 } seqAPIHistQ interface { @@ -152,9 +153,10 @@ type ( func newProxySearchQuery(q seqAPISearchQ) *seqproxyapi.SearchQuery { return &seqproxyapi.SearchQuery{ - Query: q.GetQuery(), - From: q.GetFrom(), - To: q.GetTo(), + Query: q.GetQuery(), + From: q.GetFrom(), + To: q.GetTo(), + Downsample: q.GetDownsample(), } } @@ -347,15 +349,11 @@ func asyncSearchStatusFromProto(s seqapi.AsyncSearchStatus) seqproxyapi.AsyncSea func newProxyStartAsyncSearchRequest(req *seqapi.StartAsyncSearchRequest) *seqproxyapi.StartAsyncSearchRequest { return &seqproxyapi.StartAsyncSearchRequest{ Retention: req.Retention, - Query: &seqproxyapi.SearchQuery{ - Query: req.Query, - From: req.From, - To: req.To, - }, - Aggs: newProxyAggQuerySlice(req.Aggs), - Hist: newProxyHistQuery(req.Hist), - WithDocs: req.WithDocs, - Size: int64(req.Size), + Query: newProxySearchQuery(req), + Aggs: newProxyAggQuerySlice(req.Aggs), + Hist: newProxyHistQuery(req.Hist), + WithDocs: req.WithDocs, + Size: int64(req.Size), } } @@ -451,14 +449,15 @@ func newSeqapiStartAsyncSearchRequest(r *seqproxyapi.StartAsyncSearchRequest) *s } return &seqapi.StartAsyncSearchRequest{ - Retention: r.Retention, - Query: r.Query.Query, - From: r.Query.From, - To: r.Query.To, - Aggs: newSeqapiAggQuerySlice(r.Aggs), - Hist: hist, - WithDocs: r.WithDocs, - Size: int32(r.Size), + Retention: r.Retention, + Query: r.Query.Query, + From: r.Query.From, + To: r.Query.To, + Aggs: newSeqapiAggQuerySlice(r.Aggs), + Hist: hist, + WithDocs: r.WithDocs, + Size: int32(r.Size), + Downsample: r.Query.Downsample, } } diff --git a/internal/pkg/client/seqdb/search_test.go b/internal/pkg/client/seqdb/search_test.go index 1108226..2fdc64c 100644 --- a/internal/pkg/client/seqdb/search_test.go +++ b/internal/pkg/client/seqdb/search_test.go @@ -25,12 +25,12 @@ func Test_GRPCClient_Search(t *testing.T) { eventTime := timestamppb.New(time.Date(2024, time.December, 31, 10, 20, 30, 400000, time.UTC)) events := make([]*seqapi.Event, limit) - for i := 0; i < len(events); i++ { + for i := range len(events) { events[i] = makeEvent(fmt.Sprintf("test%d", i+1), i+1, eventTime) } docs := make([]*seqproxyapi.Document, 0, len(events)) - for i := 0; i < len(events); i++ { + for i := range len(events) { data, err := json.Marshal(events[i].Data) assert.NoError(t, err) docs = append(docs, &seqproxyapi.Document{ @@ -52,7 +52,7 @@ func Test_GRPCClient_Search(t *testing.T) { if req != nil { proxyReq = &seqproxyapi.ComplexSearchRequest{ - Query: makeProxySearchQuery(req.Query, req.From, req.To), + Query: makeProxySearchQuery(req.Query, req.From, req.To, req.Downsample), Size: int64(req.Limit), Offset: int64(req.Offset), WithTotal: req.WithTotal, @@ -218,6 +218,25 @@ func Test_GRPCClient_Search(t *testing.T) { }, }, }, + { + name: "ok_downsample", + req: &seqapi.SearchRequest{ + Query: "test_downsample", + From: timestamppb.New(from), + To: timestamppb.New(to), + Limit: limit, + Offset: 0, + Downsample: 10, + }, + docs: docs, + wantResp: &seqapi.SearchResponse{ + Events: events, + Aggregations: makeAggregations(0, 0, nil), + Error: &seqapi.Error{ + Code: seqapi.ErrorCode_ERROR_CODE_NO, + }, + }, + }, { name: "ok_invalid_utf8", req: &seqapi.SearchRequest{ @@ -272,18 +291,20 @@ func Test_GRPCClient_Search(t *testing.T) { wantErr: errors.New("proxy error"), }, } + for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() ctx := context.Background() mArgs := prepareMockArgs(tt.req, tt.docs, tt.wantResp, tt.wantErr) - ctrl := gomock.NewController(t) seqProxyMock := mock.NewMockSeqProxyApiClient(ctrl) - seqProxyMock.EXPECT().ComplexSearch(ctx, mArgs.req). - Return(mArgs.resp, mArgs.err).Times(1) + + seqProxyMock.EXPECT(). + ComplexSearch(ctx, mArgs.req). + Return(mArgs.resp, mArgs.err). + Times(1) c := initGRPCClient(seqProxyMock) diff --git a/internal/pkg/client/seqdb/seqproxyapi/v1/seq_proxy_api.pb.go b/internal/pkg/client/seqdb/seqproxyapi/v1/seq_proxy_api.pb.go index 3cfd476..eeba398 100644 --- a/internal/pkg/client/seqdb/seqproxyapi/v1/seq_proxy_api.pb.go +++ b/internal/pkg/client/seqdb/seqproxyapi/v1/seq_proxy_api.pb.go @@ -472,10 +472,11 @@ type SearchQuery struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` // Search query. - From *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` // Lower bound for search (inclusive). - To *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` // Upper bound for search (inclusive). - Explain bool `protobuf:"varint,4,opt,name=explain,proto3" json:"explain,omitempty"` // Should request be explained (tracing will be provided with the result). + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` // Search query. + From *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` // Lower bound for search (inclusive). + To *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` // Upper bound for search (inclusive). + Explain bool `protobuf:"varint,4,opt,name=explain,proto3" json:"explain,omitempty"` // Should request be explained (tracing will be provided with the result). + Downsample uint32 `protobuf:"varint,5,opt,name=downsample,proto3" json:"downsample,omitempty"` // If set, returns roughly 1 in N documents on a probabilistic basis } func (x *SearchQuery) Reset() { @@ -538,6 +539,13 @@ func (x *SearchQuery) GetExplain() bool { return false } +func (x *SearchQuery) GetDownsample() uint32 { + if x != nil { + return x.Downsample + } + return 0 +} + // Aggregation query. Generally uses `field` and `group_by`, for details, refer to AggFunc definition. type AggQuery struct { state protoimpl.MessageState @@ -2613,11 +2621,11 @@ var File_v1_seq_proxy_api_proto protoreflect.FileDescriptor var file_v1_seq_proxy_api_proto_rawDesc = []byte{ 0x0a, 0x16, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x71, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x73, 0x65, 0x71, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x78, 0x79, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x50, 0x0a, 0x05, 0x45, 0x72, 0x72, + 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x50, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x65, 0x71, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, @@ -2656,7 +2664,7 @@ var file_v1_seq_proxy_api_proto_rawDesc = []byte{ 0x6f, 0x63, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x02, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x02, 0x74, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x51, 0x75, + 0x02, 0x74, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, @@ -2665,7 +2673,9 @@ var file_v1_seq_proxy_api_proto_rawDesc = []byte{ 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x22, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x12, + 0x1e, 0x0a, 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x22, 0xba, 0x01, 0x0a, 0x08, 0x41, 0x67, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x62, 0x79, 0x18, 0x03, diff --git a/internal/pkg/client/seqdb/seqproxyapi/v1/seq_proxy_api.proto b/internal/pkg/client/seqdb/seqproxyapi/v1/seq_proxy_api.proto index 360f438..2602162 100644 --- a/internal/pkg/client/seqdb/seqproxyapi/v1/seq_proxy_api.proto +++ b/internal/pkg/client/seqdb/seqproxyapi/v1/seq_proxy_api.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -option go_package = "github.com/ozontech/seq-ui/internal/pkg/client/seqdb/seqproxyapi/v1;seqproxyapi"; - package seqproxyapi.v1; -import "google/protobuf/timestamp.proto"; import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/ozontech/seq-ui/internal/pkg/client/seqdb/seqproxyapi/v1;seqproxyapi"; // seq-db public api. Exposes APIs related to document querying. service SeqProxyApi { @@ -53,9 +53,9 @@ service SeqProxyApi { // Custom error code, returned by seq-db proxy. enum ErrorCode { - ERROR_CODE_UNSPECIFIED = 0; // Unknown/undefined code. - ERROR_CODE_NO = 1; // No error code. Returned when there were no problems during the request handling. - ERROR_CODE_PARTIAL_RESPONSE = 2; // Partial response code. Returned when some of the seq-stores returned an error. + ERROR_CODE_UNSPECIFIED = 0; // Unknown/undefined code. + ERROR_CODE_NO = 1; // No error code. Returned when there were no problems during the request handling. + ERROR_CODE_PARTIAL_RESPONSE = 2; // Partial response code. Returned when some of the seq-stores returned an error. ERROR_CODE_TOO_MANY_FRACTIONS_HIT = 3; // Too many fractions hit code. Returned when too many fractions were hit during search exceeded limit. } @@ -67,8 +67,8 @@ message Error { // Document returned by seq-db. message Document { - string id = 1; // seq-id of the document. - bytes data = 2; // content of the document in utf-8 format. + string id = 1; // seq-id of the document. + bytes data = 2; // content of the document in utf-8 format. google.protobuf.Timestamp time = 3; // timestamp from the document. } @@ -77,22 +77,22 @@ message Aggregation { // Key-value pair containing result of single aggregation. message Bucket { reserved 1; - string key = 2; // Field name. - double value = 3; // Calculated aggregation value. - int64 not_exists = 4; // Number of documents without presence of that field. - repeated double quantiles = 5; // Value of quantiles for given request. Returned when quantiles aggregation func used. + string key = 2; // Field name. + double value = 3; // Calculated aggregation value. + int64 not_exists = 4; // Number of documents without presence of that field. + repeated double quantiles = 5; // Value of quantiles for given request. Returned when quantiles aggregation func used. optional google.protobuf.Timestamp ts = 6; // Will be used to determine bin of time series. } repeated Bucket buckets = 1; // List of aggregations for given request. - int64 not_exists = 2; // Number of documents in which such field does not exist + int64 not_exists = 2; // Number of documents in which such field does not exist } // Histogram response. message Histogram { // Key-value pair with time as a key and number of documents in this bucket as a value. message Bucket { - uint64 doc_count = 1; // Number of documents in bucket. + uint64 doc_count = 1; // Number of documents in bucket. google.protobuf.Timestamp ts = 2; // Left border of the bucket. } @@ -101,37 +101,38 @@ message Histogram { // General search query for requesting documents. message SearchQuery { - string query = 1; // Search query. + string query = 1; // Search query. google.protobuf.Timestamp from = 2; // Lower bound for search (inclusive). - google.protobuf.Timestamp to = 3; // Upper bound for search (inclusive). - bool explain = 4; // Should request be explained (tracing will be provided with the result). + google.protobuf.Timestamp to = 3; // Upper bound for search (inclusive). + bool explain = 4; // Should request be explained (tracing will be provided with the result). + uint32 downsample = 5; // If set, returns roughly 1 in N documents on a probabilistic basis } // Aggregation function used in request. enum AggFunc { - AGG_FUNC_COUNT = 0; // Returns how many times `field` was equal to particular value. - AGG_FUNC_SUM = 1; // Performs an addition operation on `field`, among documents with same `group_by` field. - AGG_FUNC_MIN = 2; // Finds minimum value for `field`, among documents with same `group_by` field. - AGG_FUNC_MAX = 3; // Finds maximum value for `field`, among documents with same `group_by` field. - AGG_FUNC_AVG = 4; // Finds average value for `field`, among documents with same `group_by` field. + AGG_FUNC_COUNT = 0; // Returns how many times `field` was equal to particular value. + AGG_FUNC_SUM = 1; // Performs an addition operation on `field`, among documents with same `group_by` field. + AGG_FUNC_MIN = 2; // Finds minimum value for `field`, among documents with same `group_by` field. + AGG_FUNC_MAX = 3; // Finds maximum value for `field`, among documents with same `group_by` field. + AGG_FUNC_AVG = 4; // Finds average value for `field`, among documents with same `group_by` field. AGG_FUNC_QUANTILE = 5; // Finds quantiles for `field`, among documents with same `group_by` field. - AGG_FUNC_UNIQUE = 6; // Finds unique values for `group_by` field. + AGG_FUNC_UNIQUE = 6; // Finds unique values for `group_by` field. } // Order of document sorting. enum Order { ORDER_DESC = 0; // Type for descending order. - ORDER_ASC = 1; // Type for ascending order. + ORDER_ASC = 1; // Type for ascending order. } // Aggregation query. Generally uses `field` and `group_by`, for details, refer to AggFunc definition. message AggQuery { - string field = 1; // Field over which aggregation function is used on. - reserved 2; // - string group_by = 3; // Field over which to create group for further aggregation. - AggFunc func = 4; // Function to apply on aggregated field. + string field = 1; // Field over which aggregation function is used on. + reserved 2; // + string group_by = 3; // Field over which to create group for further aggregation. + AggFunc func = 4; // Function to apply on aggregated field. repeated double quantiles = 5; // Field used only for `AGG_FUNC_QUANTILE`. Represents list of quantiles to calculate. - optional string interval = 6; // Field used only for time series. + optional string interval = 6; // Field used only for time series. } // Histogram query @@ -141,38 +142,38 @@ message HistQuery { message SearchRequest { SearchQuery query = 1; // Search query. - int64 size = 2; // Maximum number of documents to return. - int64 offset = 3; // Search offset. - bool with_total = 4; // Should total number of documents be returned in response. - Order order = 5; // Document order ORDER_DESC/ORDER_ASC. - string offset_id = 6; // ID offset for pagination. + int64 size = 2; // Maximum number of documents to return. + int64 offset = 3; // Search offset. + bool with_total = 4; // Should total number of documents be returned in response. + Order order = 5; // Document order ORDER_DESC/ORDER_ASC. + string offset_id = 6; // ID offset for pagination. } message ComplexSearchRequest { - SearchQuery query = 1; // Search query. - repeated AggQuery aggs = 2; // List of aggregation queries. - optional HistQuery hist = 3; // Histogram query. - int64 size = 4; // Maximum number of documents to return. - int64 offset = 5; // Search offset. - bool with_total = 6; // Should total number of documents be returned in response. - Order order = 7; // Document order ORDER_DESC/ORDER_ASC. - string offset_id = 8; // ID offset for pagination. + SearchQuery query = 1; // Search query. + repeated AggQuery aggs = 2; // List of aggregation queries. + optional HistQuery hist = 3; // Histogram query. + int64 size = 4; // Maximum number of documents to return. + int64 offset = 5; // Search offset. + bool with_total = 6; // Should total number of documents be returned in response. + Order order = 7; // Document order ORDER_DESC/ORDER_ASC. + string offset_id = 8; // ID offset for pagination. } message SearchResponse { bool partial_response = 1 [deprecated = true]; // True if some stores returned an error. Deprecated, use `Error` instead. - int64 total = 2; // Total number of documents satisfying request. Returned if `with_total` field in request is `true`. - repeated Document docs = 3; // Documents, satisfying the request. - Error error = 4; // Error if happened. + int64 total = 2; // Total number of documents satisfying request. Returned if `with_total` field in request is `true`. + repeated Document docs = 3; // Documents, satisfying the request. + Error error = 4; // Error if happened. } message ComplexSearchResponse { bool partial_response = 1 [deprecated = true]; // True if some stores returned an error. Deprecated, use `Error` instead. - int64 total = 2; // Total number of documents satisfying request. Returned if `with_total` field in request is `true`. - repeated Document docs = 3; // Documents, satisfying the request. - repeated Aggregation aggs = 4; // Aggregation results. - optional Histogram hist = 5; // Histogram results. - Error error = 6; // Error if happened. + int64 total = 2; // Total number of documents satisfying request. Returned if `with_total` field in request is `true`. + repeated Document docs = 3; // Documents, satisfying the request. + repeated Aggregation aggs = 4; // Aggregation results. + optional Histogram hist = 5; // Histogram results. + Error error = 6; // Error if happened. } message StartAsyncSearchRequest { @@ -237,11 +238,11 @@ message FetchAsyncSearchResultResponse { Error error = 9; } -message CancelAsyncSearchRequest{ +message CancelAsyncSearchRequest { string search_id = 1; } -message CancelAsyncSearchResponse{} +message CancelAsyncSearchResponse {} message DeleteAsyncSearchRequest { string search_id = 1; @@ -279,27 +280,27 @@ message AsyncSearchesListItem { } message GetAggregationRequest { - SearchQuery query = 1; // Search query. + SearchQuery query = 1; // Search query. repeated AggQuery aggs = 2; // List of aggregation queries. } message GetAggregationResponse { bool partial_response = 1 [deprecated = true]; // True if some stores returned an error. Deprecated, use `Error` instead. - int64 total = 2; // Total number of documents satisfying request. Returned if `with_total` field in request is `true`. - repeated Aggregation aggs = 3; // Aggregation results. - Error error = 4; // Error if happened. + int64 total = 2; // Total number of documents satisfying request. Returned if `with_total` field in request is `true`. + repeated Aggregation aggs = 3; // Aggregation results. + Error error = 4; // Error if happened. } message GetHistogramRequest { SearchQuery query = 1; // Search query. - HistQuery hist = 2; // Histogram query. + HistQuery hist = 2; // Histogram query. } message GetHistogramResponse { bool partial_response = 1 [deprecated = true]; // True if some stores returned an error. Deprecated, use `Error` instead. - int64 total = 2; // Total number of documents satisfying request. Returned if `with_total` field in request is `true`. - Histogram hist = 3; // Histogram results. - Error error = 4; // Error if happened. + int64 total = 2; // Total number of documents satisfying request. Returned if `with_total` field in request is `true`. + Histogram hist = 3; // Histogram results. + Error error = 4; // Error if happened. } message FetchRequest { @@ -315,15 +316,15 @@ message MappingResponse { message StatusRequest {} message StatusResponse { - int32 number_of_stores = 1; // Total number of stores. + int32 number_of_stores = 1; // Total number of stores. optional google.protobuf.Timestamp oldest_storage_time = 2; // Timestamp of the oldest stored document across all stores. - repeated StoreStatus stores = 4; // Detailed information about each store. + repeated StoreStatus stores = 4; // Detailed information about each store. } message StoreStatus { - string host = 1; // Store's IP-address. + string host = 1; // Store's IP-address. optional StoreStatusValues values = 2; // Store's status information. - optional string error = 3; // Error during the request. + optional string error = 3; // Error during the request. } message StoreStatusValues { @@ -332,8 +333,8 @@ message StoreStatusValues { message ExportRequest { SearchQuery query = 1; // Search query. - int64 size = 2; // Maximum number of documents to return. - int64 offset = 3; // Search offset. + int64 size = 2; // Maximum number of documents to return. + int64 offset = 3; // Search offset. } message ExportResponse { diff --git a/internal/pkg/client/seqdb/test_data.go b/internal/pkg/client/seqdb/test_data.go index f358553..09ac214 100644 --- a/internal/pkg/client/seqdb/test_data.go +++ b/internal/pkg/client/seqdb/test_data.go @@ -27,11 +27,12 @@ func initGRPCClient(client *mock.MockSeqProxyApiClient) *GRPCClient { } } -func makeProxySearchQuery(query string, from, to *timestamppb.Timestamp) *seqproxyapi.SearchQuery { +func makeProxySearchQuery(query string, from, to *timestamppb.Timestamp, downsample uint32) *seqproxyapi.SearchQuery { return &seqproxyapi.SearchQuery{ - Query: query, - From: from, - To: to, + Query: query, + From: from, + To: to, + Downsample: downsample, } } @@ -41,7 +42,7 @@ func makeEvent(id string, countData int, t *timestamppb.Timestamp) *seqapi.Event Data: make(map[string]string), Time: t, } - for i := 0; i < countData; i++ { + for i := range countData { e.Data[fmt.Sprintf("field%d", i+1)] = fmt.Sprintf("val%d", i+1) } return e @@ -51,7 +52,7 @@ func makeHistogram(bucketCount int) *seqapi.Histogram { hist := &seqapi.Histogram{ Buckets: make([]*seqapi.Histogram_Bucket, 0, bucketCount), } - for i := 0; i < bucketCount; i++ { + for i := range bucketCount { hist.Buckets = append(hist.Buckets, &seqapi.Histogram_Bucket{ Key: uint64(i * 100), DocCount: uint64(i + 1), @@ -69,7 +70,7 @@ func makeAggregation(bucketCount int, opts *makeAggOpts) *seqapi.Aggregation { agg := &seqapi.Aggregation{ Buckets: make([]*seqapi.Aggregation_Bucket, 0, bucketCount), } - for i := 0; i < bucketCount; i++ { + for i := range bucketCount { v := new(float64) *v = float64(i + 1) b := &seqapi.Aggregation_Bucket{ @@ -89,7 +90,7 @@ func makeAggregation(bucketCount int, opts *makeAggOpts) *seqapi.Aggregation { func makeAggregations(aggCount, bucketCount int, opts *makeAggOpts) []*seqapi.Aggregation { aggs := make([]*seqapi.Aggregation, 0, aggCount) - for i := 0; i < aggCount; i++ { + for range aggCount { aggs = append(aggs, makeAggregation(bucketCount, opts)) } return aggs diff --git a/pkg/massexport/v1/massexport.pb.go b/pkg/massexport/v1/massexport.pb.go index f624bfe..47c9007 100644 --- a/pkg/massexport/v1/massexport.pb.go +++ b/pkg/massexport/v1/massexport.pb.go @@ -638,10 +638,10 @@ var file_massexport_v1_massexport_proto_rawDesc = []byte{ 0x0a, 0x1e, 0x6d, 0x61, 0x73, 0x73, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x73, 0x73, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x6d, 0x61, 0x73, 0x73, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x76, 0x31, 0x1a, + 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xac, 0x01, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, diff --git a/pkg/seqapi/v1/seq_api.pb.go b/pkg/seqapi/v1/seq_api.pb.go index e056c19..8239033 100644 --- a/pkg/seqapi/v1/seq_api.pb.go +++ b/pkg/seqapi/v1/seq_api.pb.go @@ -669,6 +669,7 @@ type SearchRequest struct { Aggregations []*AggregationQuery `protobuf:"bytes,8,rep,name=aggregations,proto3" json:"aggregations,omitempty"` Order Order `protobuf:"varint,9,opt,name=order,proto3,enum=seqapi.v1.Order" json:"order,omitempty"` OffsetId string `protobuf:"bytes,10,opt,name=offset_id,json=offsetId,proto3" json:"offset_id,omitempty"` + Downsample uint32 `protobuf:"varint,11,opt,name=downsample,proto3" json:"downsample,omitempty"` } func (x *SearchRequest) Reset() { @@ -773,6 +774,13 @@ func (x *SearchRequest) GetOffsetId() string { return "" } +func (x *SearchRequest) GetDownsample() uint32 { + if x != nil { + return x.Downsample + } + return 0 +} + type SearchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -961,10 +969,11 @@ type GetHistogramRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` - Interval string `protobuf:"bytes,2,opt,name=interval,proto3" json:"interval,omitempty"` - From *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=from,proto3" json:"from,omitempty"` - To *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=to,proto3" json:"to,omitempty"` + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + Interval string `protobuf:"bytes,2,opt,name=interval,proto3" json:"interval,omitempty"` + From *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=from,proto3" json:"from,omitempty"` + To *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=to,proto3" json:"to,omitempty"` + Downsample uint32 `protobuf:"varint,5,opt,name=downsample,proto3" json:"downsample,omitempty"` } func (x *GetHistogramRequest) Reset() { @@ -1027,6 +1036,13 @@ func (x *GetHistogramRequest) GetTo() *timestamppb.Timestamp { return nil } +func (x *GetHistogramRequest) GetDownsample() uint32 { + if x != nil { + return x.Downsample + } + return 0 +} + type GetHistogramResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1103,6 +1119,7 @@ type GetAggregationRequest struct { // Deprecated: Marked as deprecated in seqapi/v1/seq_api.proto. AggField string `protobuf:"bytes,4,opt,name=agg_field,json=aggField,proto3" json:"agg_field,omitempty"` Aggregations []*AggregationQuery `protobuf:"bytes,5,rep,name=aggregations,proto3" json:"aggregations,omitempty"` + Downsample uint32 `protobuf:"varint,6,opt,name=downsample,proto3" json:"downsample,omitempty"` } func (x *GetAggregationRequest) Reset() { @@ -1173,6 +1190,13 @@ func (x *GetAggregationRequest) GetAggregations() []*AggregationQuery { return nil } +func (x *GetAggregationRequest) GetDownsample() uint32 { + if x != nil { + return x.Downsample + } + return 0 +} + type GetAggregationResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1409,13 +1433,14 @@ type ExportRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` // query for SeqDB in key:value format - From *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` - To *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` - Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` - Offset int32 `protobuf:"varint,5,opt,name=offset,proto3" json:"offset,omitempty"` - Format ExportFormat `protobuf:"varint,6,opt,name=format,proto3,enum=seqapi.v1.ExportFormat" json:"format,omitempty"` - Fields []string `protobuf:"bytes,7,rep,name=fields,proto3" json:"fields,omitempty"` + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` // query for SeqDB in key:value format + From *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` + To *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` + Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` + Offset int32 `protobuf:"varint,5,opt,name=offset,proto3" json:"offset,omitempty"` + Format ExportFormat `protobuf:"varint,6,opt,name=format,proto3,enum=seqapi.v1.ExportFormat" json:"format,omitempty"` + Fields []string `protobuf:"bytes,7,rep,name=fields,proto3" json:"fields,omitempty"` + Downsample uint32 `protobuf:"varint,8,opt,name=downsample,proto3" json:"downsample,omitempty"` } func (x *ExportRequest) Reset() { @@ -1499,6 +1524,13 @@ func (x *ExportRequest) GetFields() []string { return nil } +func (x *ExportRequest) GetDownsample() uint32 { + if x != nil { + return x.Downsample + } + return 0 +} + type GetLimitsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1917,15 +1949,16 @@ type StartAsyncSearchRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Retention *durationpb.Duration `protobuf:"bytes,1,opt,name=retention,proto3" json:"retention,omitempty"` - Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` - From *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=from,proto3" json:"from,omitempty"` - To *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=to,proto3" json:"to,omitempty"` - Aggs []*AggregationQuery `protobuf:"bytes,5,rep,name=aggs,proto3" json:"aggs,omitempty"` - Hist *StartAsyncSearchRequest_HistQuery `protobuf:"bytes,6,opt,name=hist,proto3,oneof" json:"hist,omitempty"` - WithDocs bool `protobuf:"varint,7,opt,name=with_docs,json=withDocs,proto3" json:"with_docs,omitempty"` - Size int32 `protobuf:"varint,8,opt,name=size,proto3" json:"size,omitempty"` - Meta string `protobuf:"bytes,9,opt,name=meta,proto3" json:"meta,omitempty"` + Retention *durationpb.Duration `protobuf:"bytes,1,opt,name=retention,proto3" json:"retention,omitempty"` + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + From *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=from,proto3" json:"from,omitempty"` + To *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=to,proto3" json:"to,omitempty"` + Aggs []*AggregationQuery `protobuf:"bytes,5,rep,name=aggs,proto3" json:"aggs,omitempty"` + Hist *StartAsyncSearchRequest_HistQuery `protobuf:"bytes,6,opt,name=hist,proto3,oneof" json:"hist,omitempty"` + WithDocs bool `protobuf:"varint,7,opt,name=with_docs,json=withDocs,proto3" json:"with_docs,omitempty"` + Size int32 `protobuf:"varint,8,opt,name=size,proto3" json:"size,omitempty"` + Meta string `protobuf:"bytes,9,opt,name=meta,proto3" json:"meta,omitempty"` + Downsample uint32 `protobuf:"varint,10,opt,name=downsample,proto3" json:"downsample,omitempty"` } func (x *StartAsyncSearchRequest) Reset() { @@ -2023,6 +2056,13 @@ func (x *StartAsyncSearchRequest) GetMeta() string { return "" } +func (x *StartAsyncSearchRequest) GetDownsample() uint32 { + if x != nil { + return x.Downsample + } + return 0 +} + type StartAsyncSearchResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3146,7 +3186,7 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x63, 0x6b, 0x65, 0x74, 0x52, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x4a, - 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0xd2, 0x03, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0xf2, 0x03, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, @@ -3172,7 +3212,9 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x73, 0x65, 0x71, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x49, 0x64, 0x1a, 0x27, 0x0a, 0x09, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, + 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x1a, 0x27, 0x0a, 0x09, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x22, 0xb9, 0x02, 0x0a, 0x0e, 0x53, @@ -3201,7 +3243,7 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x65, 0x71, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xa3, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x48, 0x69, 0x73, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xc3, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, @@ -3211,7 +3253,9 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x2a, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x02, 0x74, 0x6f, 0x22, 0xb0, 0x01, 0x0a, 0x14, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x64, + 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x65, 0x71, 0x61, 0x70, 0x69, @@ -3222,8 +3266,8 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x65, 0x71, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xeb, - 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x72, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x8b, + 0x02, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, @@ -3237,7 +3281,9 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x65, 0x71, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x0c, - 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xf8, 0x01, 0x0a, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, + 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x22, 0xf8, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, @@ -3270,7 +3316,7 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x6e, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x65, 0x71, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0c, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, - 0x22, 0xf8, 0x01, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x22, 0x98, 0x02, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, @@ -3285,7 +3331,9 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x73, 0x65, 0x71, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x07, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x12, 0x0a, 0x10, 0x47, + 0x03, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x64, + 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x02, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x65, 0x61, @@ -3340,7 +3388,7 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x12, 0x35, 0x0a, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, - 0x69, 0x66, 0x65, 0x73, 0x70, 0x61, 0x6e, 0x22, 0xb3, 0x03, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, + 0x69, 0x66, 0x65, 0x73, 0x70, 0x61, 0x6e, 0x22, 0xd3, 0x03, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, @@ -3364,7 +3412,9 @@ var file_seqapi_v1_seq_api_proto_rawDesc = []byte{ 0x6f, 0x63, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x69, 0x74, 0x68, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x1a, 0x27, 0x0a, 0x09, 0x48, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x64, + 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x1a, 0x27, 0x0a, 0x09, 0x48, 0x69, 0x73, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x22, 0x37, 0x0a, diff --git a/swagger/swagger.json b/swagger/swagger.json index f679b0a..f80c0b4 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -2588,6 +2588,9 @@ "seqapi.v1.ExportRequest": { "type": "object", "properties": { + "downsample": { + "type": "integer" + }, "fields": { "type": "array", "items": { @@ -2720,6 +2723,9 @@ "$ref": "#/definitions/seqapi.v1.AggregationQuery" } }, + "downsample": { + "type": "integer" + }, "from": { "type": "string", "format": "date-time" @@ -2867,6 +2873,9 @@ "seqapi.v1.GetHistogramRequest": { "type": "object", "properties": { + "downsample": { + "type": "integer" + }, "from": { "type": "string", "format": "date-time" @@ -2974,6 +2983,9 @@ "$ref": "#/definitions/seqapi.v1.AggregationQuery" } }, + "downsample": { + "type": "integer" + }, "from": { "type": "string", "format": "date-time" @@ -3056,6 +3068,9 @@ "$ref": "#/definitions/seqapi.v1.AggregationTsQuery" } }, + "downsample": { + "type": "integer" + }, "from": { "type": "string", "format": "date-time"