Files
traces/modules/querier/querier_query_range.go
T
Joe ElliottandZach Kelling 3ae918ff89 [Tempo 3.0] Remove compactor and v2 block encoding code (#6273)
* o7 compactor

Signed-off-by: Joe Elliott <number101010@gmail.com>

* wip: o7 v2

Signed-off-by: Joe Elliott <number101010@gmail.com>

* test cleanup

Signed-off-by: Joe Elliott <number101010@gmail.com>

* remove compactor from jsonnet

Signed-off-by: Joe Elliott <number101010@gmail.com>

* changelog

Signed-off-by: Joe Elliott <number101010@gmail.com>

* gen manifest

Signed-off-by: Joe Elliott <number101010@gmail.com>

* config cleanup

Signed-off-by: Joe Elliott <number101010@gmail.com>

* docs

Signed-off-by: Joe Elliott <number101010@gmail.com>

* jsonnet

Signed-off-by: Joe Elliott <number101010@gmail.com>

* remove encoding

Signed-off-by: Joe Elliott <number101010@gmail.com>

* remove data encoding

Signed-off-by: Joe Elliott <number101010@gmail.com>

* lint and cleanup

Signed-off-by: Joe Elliott <number101010@gmail.com>

* unflake TestWorker\?

Signed-off-by: Joe Elliott <number101010@gmail.com>

---------

Signed-off-by: Joe Elliott <number101010@gmail.com>
2026-02-22 00:55:18 -08:00

140 lines
3.8 KiB
Go

package querier
import (
"context"
"fmt"
"time"
"github.com/go-kit/log/level"
"github.com/grafana/tempo/pkg/tempopb"
"github.com/grafana/tempo/pkg/traceql"
"github.com/grafana/tempo/pkg/util/log"
"github.com/grafana/tempo/pkg/validation"
"github.com/grafana/tempo/tempodb/backend"
"github.com/grafana/tempo/tempodb/encoding/common"
)
func (q *Querier) QueryRange(ctx context.Context, req *tempopb.QueryRangeRequest) (*tempopb.QueryRangeResponse, error) {
if req.QueryMode == QueryModeRecent {
return q.queryRangeRecent(ctx, req)
}
return q.queryBlock(ctx, req)
}
func (q *Querier) queryRangeRecent(ctx context.Context, req *tempopb.QueryRangeRequest) (*tempopb.QueryRangeResponse, error) {
// correct max series limit logic should've been set by the query-frontend sharder
c, err := traceql.QueryRangeCombinerFor(req, traceql.AggregateModeSum, int(req.MaxSeries))
if err != nil {
return nil, err
}
results, err := q.forGivenGenerators(ctx, func(ctx context.Context, client tempopb.MetricsGeneratorClient) (any, error) {
return client.QueryRange(ctx, req)
})
if err != nil {
_ = level.Error(log.Logger).Log("msg", "error querying generators in Querier.queryRangeRecent", "err", err)
return nil, fmt.Errorf("error querying generators in Querier.queryRangeRecent: %w", err)
}
for _, result := range results {
resp := result.(*tempopb.QueryRangeResponse)
c.Combine(resp)
if c.MaxSeriesReached() {
break
}
}
return c.Response(), nil
}
func (q *Querier) queryBlock(ctx context.Context, req *tempopb.QueryRangeRequest) (*tempopb.QueryRangeResponse, error) {
tenantID, err := validation.ExtractValidTenantID(ctx)
if err != nil {
return nil, fmt.Errorf("error extracting org id in Querier.queryBlock: %w", err)
}
blockID, err := backend.ParseUUID(req.BlockID)
if err != nil {
return nil, err
}
dc, err := backend.DedicatedColumnsFromTempopb(req.DedicatedColumns)
if err != nil {
return nil, err
}
meta := &backend.BlockMeta{
Version: req.Version,
TenantID: tenantID,
StartTime: time.Unix(0, int64(req.Start)),
EndTime: time.Unix(0, int64(req.End)),
// IndexPageSize: req.IndexPageSize,
// TotalRecords: req.TotalRecords,
BlockID: blockID,
Size_: req.Size_,
FooterSize: req.FooterSize,
DedicatedColumns: dc,
}
opts := common.DefaultSearchOptions()
opts.StartPage = int(req.StartPage)
opts.TotalPages = int(req.PagesToSearch)
unsafe := q.limits.UnsafeQueryHints(tenantID)
expr, err := traceql.Parse(req.Query)
if err != nil {
return nil, err
}
timeOverlapCutoff := q.cfg.Metrics.TimeOverlapCutoff
if v, ok := expr.Hints.GetFloat(traceql.HintTimeOverlapCutoff, unsafe); ok && v >= 0 && v <= 1.0 {
timeOverlapCutoff = v
}
eval, err := traceql.NewEngine().CompileMetricsQueryRange(req, int(req.Exemplars), timeOverlapCutoff, unsafe)
if err != nil {
return nil, err
}
f := traceql.NewSpansetFetcherWrapper(func(ctx context.Context, req traceql.FetchSpansRequest) (traceql.FetchSpansResponse, error) {
return q.store.Fetch(ctx, meta, req, opts)
})
err = eval.Do(ctx, f, uint64(meta.StartTime.UnixNano()), uint64(meta.EndTime.UnixNano()), int(req.MaxSeries))
if err != nil {
return nil, err
}
res := eval.Results()
inspectedBytes, spansTotal, _ := eval.Metrics()
if req.MaxSeries > 0 && len(res) > int(req.MaxSeries) {
limitedRes := make(traceql.SeriesSet)
count := 0
for k, v := range res {
if count >= int(req.MaxSeries) {
break
}
limitedRes[k] = v
count++
}
res = limitedRes
}
response := &tempopb.QueryRangeResponse{
Series: res.ToProto(req),
Metrics: &tempopb.SearchMetrics{
InspectedBytes: inspectedBytes,
InspectedSpans: spansTotal,
},
}
if req.MaxSeries > 0 && len(res) > int(req.MaxSeries) {
response.Status = tempopb.PartialStatus_PARTIAL
}
return response, nil
}