diff --git a/cmd/query/app/query_parser.go b/cmd/query/app/query_parser.go index 7d835d04c2f..931c4d918cc 100644 --- a/cmd/query/app/query_parser.go +++ b/cmd/query/app/query_parser.go @@ -30,12 +30,14 @@ import ( const ( defaultQueryLimit = 100 + defaultSpansLimit = 10000 operationParam = "operation" tagParam = "tag" tagsParam = "tags" startTimeParam = "start" limitParam = "limit" + limitSpansParam = "limitSpans" minDurationParam = "minDuration" maxDurationParam = "maxDuration" serviceParam = "service" @@ -105,6 +107,16 @@ func (p *queryParser) parse(r *http.Request) (*traceQueryParameters, error) { limit = int(limitParsed) } + limitSpansParam := r.FormValue(limitSpansParam) + limitSpans := defaultSpansLimit + if limitSpansParam != "" { + limitParsed, err := strconv.ParseInt(limitSpansParam, 10, 32) + if err != nil { + return nil, err + } + limitSpans = int(limitParsed) + } + minDuration, err := p.parseDuration(minDurationParam, r) if err != nil { return nil, err @@ -137,6 +149,7 @@ func (p *queryParser) parse(r *http.Request) (*traceQueryParameters, error) { StartTimeMax: endTime, Tags: tags, NumTraces: limit, + NumSpans: limitSpans, DurationMin: minDuration, DurationMax: maxDuration, }, diff --git a/cmd/query/app/query_parser_test.go b/cmd/query/app/query_parser_test.go index 09448851f8f..cd8e550aeb5 100644 --- a/cmd/query/app/query_parser_test.go +++ b/cmd/query/app/query_parser_test.go @@ -53,6 +53,7 @@ func TestParseTraceQuery(t *testing.T) { StartTimeMin: time.Unix(0, 0), StartTimeMax: time.Unix(0, 0), NumTraces: 200, + NumSpans: 10000, Tags: map[string]string{"k": "v", "x": "y"}, }, }, @@ -68,6 +69,7 @@ func TestParseTraceQuery(t *testing.T) { StartTimeMin: time.Unix(0, 0), StartTimeMax: time.Unix(0, 0), NumTraces: 200, + NumSpans: 10000, Tags: map[string]string{"k": "v", "x": "y"}, }, }, @@ -81,6 +83,7 @@ func TestParseTraceQuery(t *testing.T) { StartTimeMin: time.Unix(0, 0), StartTimeMax: time.Unix(0, 0), NumTraces: 200, + NumSpans: 10000, Tags: map[string]string{"k": "v", "x": "y"}, }, }, @@ -93,6 +96,7 @@ func TestParseTraceQuery(t *testing.T) { StartTimeMin: time.Unix(0, 0), StartTimeMax: time.Unix(0, 0), NumTraces: 200, + NumSpans: 10000, DurationMin: 10 * time.Second, DurationMax: 20 * time.Second, Tags: make(map[string]string), @@ -107,6 +111,7 @@ func TestParseTraceQuery(t *testing.T) { StartTimeMin: time.Unix(0, 0), StartTimeMax: time.Unix(0, 0), NumTraces: 200, + NumSpans: 10000, DurationMin: 10 * time.Second, Tags: make(map[string]string), }, @@ -117,6 +122,7 @@ func TestParseTraceQuery(t *testing.T) { &traceQueryParameters{ TraceQueryParameters: spanstore.TraceQueryParameters{ NumTraces: 100, + NumSpans: 10000, StartTimeMin: timeNow, StartTimeMax: timeNow, Tags: make(map[string]string), @@ -133,6 +139,7 @@ func TestParseTraceQuery(t *testing.T) { StartTimeMin: time.Unix(0, 0), StartTimeMax: time.Unix(0, 0), NumTraces: 100, + NumSpans: 10000, Tags: make(map[string]string), }, traceIDs: []model.TraceID{ diff --git a/plugin/storage/es/spanstore/reader.go b/plugin/storage/es/spanstore/reader.go index 722e61c3ac6..ecfaec181ea 100644 --- a/plugin/storage/es/spanstore/reader.go +++ b/plugin/storage/es/spanstore/reader.go @@ -54,6 +54,7 @@ const ( defaultDocCount = 10000 // the default elasticsearch allowed limit defaultNumTraces = 100 + defaultNumSpans = 10000 ) var ( @@ -136,7 +137,7 @@ func (s *SpanReader) GetTrace(ctx context.Context, traceID model.TraceID) (*mode span, ctx := opentracing.StartSpanFromContext(ctx, "GetTrace") defer span.Finish() currentTime := time.Now() - traces, err := s.multiRead(ctx, []string{traceID.String()}, currentTime.Add(-s.maxSpanAge), currentTime) + traces, err := s.multiRead(ctx, []string{traceID.String()}, currentTime.Add(-s.maxSpanAge), currentTime, defaultNumSpans) if err != nil { return nil, err } @@ -231,15 +232,14 @@ func (s *SpanReader) FindTraces(ctx context.Context, traceQuery *spanstore.Trace if err != nil { return nil, err } - return s.multiRead(ctx, uniqueTraceIDs, traceQuery.StartTimeMin, traceQuery.StartTimeMax) + return s.multiRead(ctx, uniqueTraceIDs, traceQuery.StartTimeMin, traceQuery.StartTimeMax, traceQuery.NumSpans) } func (s *SpanReader) FindTraceIDs(ctx context.Context, traceQuery *spanstore.TraceQueryParameters) ([]model.TraceID, error) { return nil, errors.New("not implemented") // TODO: Implement } -func (s *SpanReader) multiRead(ctx context.Context, traceIDs []string, startTime, endTime time.Time) ([]*model.Trace, error) { - +func (s *SpanReader) multiRead(ctx context.Context, traceIDs []string, startTime, endTime time.Time, numSpans int) ([]*model.Trace, error) { childSpan, _ := opentracing.StartSpanFromContext(ctx, "multiRead") childSpan.LogFields(otlog.Object("trace_ids", traceIDs)) defer childSpan.Finish() @@ -269,7 +269,7 @@ func (s *SpanReader) multiRead(ctx context.Context, traceIDs []string, startTime if val, ok := searchAfterTime[traceID]; ok { nextTime = val } - searchRequests[i] = elastic.NewSearchRequest().IgnoreUnavailable(true).Type(spanType).Source(elastic.NewSearchSource().Query(query).Size(defaultDocCount).Sort("startTime", true).SearchAfter(nextTime)) + searchRequests[i] = elastic.NewSearchRequest().IgnoreUnavailable(true).Type(spanType).Source(elastic.NewSearchSource().Query(query).Size(defaultDocCount).TerminateAfter(numSpans).Sort("startTime", true).SearchAfter(nextTime)) } // set traceIDs to empty traceIDs = nil diff --git a/storage/spanstore/interface.go b/storage/spanstore/interface.go index df642efece2..79dae80dfc9 100644 --- a/storage/spanstore/interface.go +++ b/storage/spanstore/interface.go @@ -51,4 +51,5 @@ type TraceQueryParameters struct { DurationMin time.Duration DurationMax time.Duration NumTraces int + NumSpans int }