Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search v0.1.0 (ingester only) #806

Merged
merged 118 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
4fadaea
super rough draft of searching data in wal
mdisibio Jun 23, 2021
9f7ef36
Search live traces, and all completing blocks, not just head block
mdisibio Jun 24, 2021
8fa8038
Oops, delete tempo binary accidentally added
mdisibio Jun 25, 2021
0dbcd60
Search all root span attributes
mdisibio Jun 25, 2021
195dbe8
tempo-query: implement FindTraces and FindTraceIDs
yvrhdn Jun 28, 2021
b5d8c34
tempo-query: also filter on rootAttrName and rootAttrValue
yvrhdn Jun 28, 2021
c461f05
Change flatbuffer search data to be keyvalue pairs only, capture and …
mdisibio Jun 28, 2021
22283f2
Create lookup api for service.name and span.name. Ingester keeps uniq…
mdisibio Jun 28, 2021
25553d2
Collect tags for all spans
mdisibio Jun 28, 2021
04bc72a
tempo-query: implement lookup of services and operations
yvrhdn Jun 28, 2021
b2933ce
tempo-query: update search API, implement Tags
yvrhdn Jun 28, 2021
3077d95
Refactor lookup API to /api/search/tags and /api/search/<name>/values
yvrhdn Jun 29, 2021
161dfe1
tempo-query: fix search url
yvrhdn Jun 29, 2021
716570b
Add tempo-search example
yvrhdn Jun 29, 2021
c2d2bf8
Fix config synthetic-load-generator
yvrhdn Jun 29, 2021
4582fa6
Capture and search on trace duration
mdisibio Jun 29, 2021
c892393
Add search endpoints to query-frontend
yvrhdn Jun 29, 2021
87f4597
tempo-query: add support for Jaeger's Min and Max Duration
yvrhdn Jun 29, 2021
72226ea
tempo-query: search using query-frontend, some refactoring
yvrhdn Jun 29, 2021
ddb7924
Expand search response: add rootServiceName, rootTraceName, startTime…
yvrhdn Jun 29, 2021
58970f3
Expand search response: actually fill in the data
yvrhdn Jun 29, 2021
bc87764
Delete search data files when parent wal file is deleted
mdisibio Jun 29, 2021
e2838a2
Used flatbuffer shared strings for space savings
mdisibio Jun 29, 2021
c851e6f
Read and write paged search data for local complete blocks
mdisibio Jun 30, 2021
4d3762a
Update for new search results. Properly stop searching when enough re…
mdisibio Jun 30, 2021
b579b95
Add limit to Search API
yvrhdn Jun 30, 2021
22d319f
Drop obsolete SearchRequest parameters
yvrhdn Jun 30, 2021
ac7e68e
Move flatbuffer generated up a folder to simplify imports
mdisibio Jun 30, 2021
2527ef8
Set up context propagation in tempo-query
yvrhdn Jul 1, 2021
4f7f14b
Enfore search limit in querier as well
yvrhdn Jul 1, 2021
1cda372
Search: return traceID as a string
yvrhdn Jul 1, 2021
b063e41
tempo-query: handle 404 traces; always request protobuf
yvrhdn Jul 1, 2021
53ec723
Include more tags in lookups for autocomplete. Save numeric tags too …
mdisibio Jul 1, 2021
c291fae
Autocomplete any tag up to first 50 unique values
mdisibio Jul 1, 2021
3251b2b
Code organization and naming
mdisibio Jul 1, 2021
f9340ec
Performance improvements to tag matching: zero allocs and use binary …
mdisibio Jul 2, 2021
ceb659a
TraceIDToHexString should not remove trailing zeros
yvrhdn Jul 2, 2021
318d849
Fix to sort flatbuffer keys/values correctly. Fix broken code from fu…
mdisibio Jul 2, 2021
aa02b09
Make backend search benchmark more stable and print out stats more cl…
mdisibio Jul 2, 2021
c365f92
Merge Tripperware for traces and search requests
yvrhdn Jul 2, 2021
6475f6d
Performance improvements to reduce number of flatbuffer lookups
mdisibio Jul 2, 2021
7f23078
tempo-query: user jsonpb unmarshaller
yvrhdn Jul 2, 2021
7f2f4d0
tempo-query: search all services and operations, not just for root spans
yvrhdn Jul 2, 2021
de1f29e
Reuse buffers in backend search block
mdisibio Jul 6, 2021
e2dbe0d
Add SearchEnabled config flag and move search API behind feature flag
yvrhdn Jul 7, 2021
af77431
Refactor to mutable form of SearchData
mdisibio Jul 7, 2021
f67f2c2
Code cleanup/comments
mdisibio Jul 8, 2021
be0d150
Fix failing tests and make search controlled by flag
mdisibio Jul 8, 2021
9abfec5
Fix distributor test
mdisibio Jul 8, 2021
3a7cfa1
make vendor-check
annanay25 Jul 9, 2021
20dad4c
Add TestInstanceSearch
annanay25 Jul 14, 2021
e9896e5
Merge branch 'main' into search
annanay25 Jul 14, 2021
0ec742c
Incorporate changes from recent backend refactor
annanay25 Jul 14, 2021
2092d6a
Use local backend in test in place of backend writer
annanay25 Jul 14, 2021
a89b6b6
Dedupe search results at instance level
annanay25 Jul 14, 2021
9a6989f
Merge branch 'main' into search
yvrhdn Jul 14, 2021
4e9f34f
make fmt and fixed some linting issues
yvrhdn Jul 14, 2021
ffff312
Move wal search files to different directory, delete and don't replay…
mdisibio Jul 19, 2021
ca9400b
Ingester search all blocks concurrently
mdisibio Jul 20, 2021
b786cf1
Split extractSearchData into new file and start adding tests
annanay25 Jul 21, 2021
b07fc20
Move ingester/instance search to separate files
mdisibio Jul 21, 2021
66c182e
Add MaxSearchBytesPerTrace limit
annanay25 Jul 21, 2021
6e166f5
Finish moving search to channels and simplify with SearchResults stru…
mdisibio Jul 21, 2021
8852c12
Fix searches to check exit status occasionally. Comments
mdisibio Jul 21, 2021
28997a9
Fix default tempo port in docker-compose
annanay25 Jul 22, 2021
feaf7e1
Fix panic in channel handling
annanay25 Jul 22, 2021
b3902a3
Address possible panic where search results channel could be closed b…
mdisibio Jul 22, 2021
64f3f79
Protect searchblock maps, add race test
annanay25 Jul 23, 2021
00c4cbf
Add locking to fix map panic in appender. Add locking to handle when …
mdisibio Jul 23, 2021
e263655
Experiment with search head block
annanay25 Jul 26, 2021
c4694ad
Add benchmark for wal search, small perf improvement, fix error handl…
mdisibio Jul 27, 2021
901ce87
Test tripperware selection in query frontend
annanay25 Jul 27, 2021
26409dc
Use contains when checking op from path
yvrhdn Jul 27, 2021
cd0aa01
Improve how we check paths in frontendRoundTripper
yvrhdn Jul 27, 2021
89f3a89
Search queries only support json for now, don't bother converting to …
yvrhdn Jul 27, 2021
d6da4fb
Remove commented out code
yvrhdn Jul 27, 2021
14c945c
Refactor: newGetRequest can be private
yvrhdn Jul 27, 2021
80c4903
Dockerize make gen-flat
yvrhdn Jul 27, 2021
a3a3dd5
Minor additions, fix linting
annanay25 Jul 28, 2021
f621d2b
Merge branch 'main' into search
annanay25 Jul 28, 2021
de3d333
make vendor-check, check for userID in search handlers at querier
annanay25 Jul 28, 2021
8764f29
Refactor forGivenIngesters and use it everywhere
annanay25 Jul 28, 2021
800bea4
Remove unused struct
yvrhdn Jul 28, 2021
9ba3ff2
Add test for instance search response metrics
mdisibio Jul 28, 2021
6849b72
Test service name tag extraction, move tags into search module
annanay25 Jul 29, 2021
f0caa57
Make instance search tag cache not store items indefinitely
mdisibio Jul 29, 2021
ad7f17e
Add locks in tag cache
mdisibio Jul 29, 2021
e060b1d
Dedupe search results from ingesters in querier
mdisibio Jul 29, 2021
2d484d0
Move duration filters before tag filters because they are faster to e…
mdisibio Jul 29, 2021
13c3369
Merge branch 'main' into search
mdisibio Jul 30, 2021
efcb101
lint
mdisibio Jul 30, 2021
86080ab
Merge branch 'main' into search
yvrhdn Aug 4, 2021
9187a77
Move RecordSearchLookupValues to outside the tracesMtx
annanay25 Aug 9, 2021
15fd058
Add search tests for backend/streaming blocks. Make it easier to expe…
mdisibio Aug 10, 2021
16d7d78
Check SearchResponse.Metrics is not nil
yvrhdn Aug 11, 2021
b9c41f6
Redo backend search blocks to have their own meta and index, use the …
mdisibio Aug 17, 2021
7ced5d3
Update search blocks to use standard data encodings, which will make …
mdisibio Aug 18, 2021
cc9c726
Merge branch 'main' into search
mdisibio Aug 19, 2021
bf6be84
Combine results from all segments for a live trace. Use a map to dedu…
mdisibio Aug 19, 2021
bbbbf78
lint
mdisibio Aug 19, 2021
aa4457a
Fix failing test
mdisibio Aug 19, 2021
8dd892e
Add page headers and skip whole page if no matches
mdisibio Aug 20, 2021
ec5df19
BackendSearchBlock configurable page size
mdisibio Aug 23, 2021
4960cc2
Simplify batch-level tags instead of storing in a 'fake' trace search…
mdisibio Aug 24, 2021
84f2202
Track number of blocks inspected
mdisibio Aug 25, 2021
60704ae
Cleanup
mdisibio Aug 25, 2021
11668d3
Use consts for search url params
mdisibio Aug 25, 2021
8840f68
Delete unused code
mdisibio Aug 25, 2021
d7632a3
Relocate to /tempodb/search/
mdisibio Aug 30, 2021
2a40702
Default search to snappy encoding
mdisibio Aug 30, 2021
750e349
Add metric ingester_trace_search_bytes_discarded_total for when searc…
mdisibio Aug 30, 2021
ccabaa0
lint: Rename types to remove stutter
mdisibio Aug 30, 2021
6e407e7
Merge branch 'main' into search
mdisibio Aug 30, 2021
a500ba0
Resolve conflicts with main, dataReader.Read error
mdisibio Aug 30, 2021
afae90e
changelog
mdisibio Aug 30, 2021
e00cfed
Update default search block page size to 2MiB based on snappy benchmarks
mdisibio Aug 30, 2021
1bdc697
Rename SearchData -> SearchEntry, BatchSearchData -> SearchPage
mdisibio Aug 31, 2021
0212c95
Pin search blocks to v2 instead of 'latest'
mdisibio Aug 31, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## main / unreleased

* [FEATURE] Add ability to search ingesters for traces [#806](https://github.com/grafana/tempo/pull/806) (@mdisibio)
* [BUGFIX] Update port spec for GCS docker-compose example [#869](https://github.com/grafana/tempo/pull/869) (@zalegrala)
* [BUGFIX] Cortex upgrade to fix an issue where unhealthy compactors can't be forgotten [#878](https://github.com/grafana/tempo/pull/878) (@joe-elliott)
* [ENHANCEMENT] Added "query blocks" cli option. [#876](https://github.com/grafana/tempo/pull/876) (@joe-elliott)
Expand Down
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,18 @@ gen-proto:

rm -rf $(PROTO_INTERMEDIATE_DIR)

.PHONY: gen-flat
gen-flat:
# -o /pkg generates into same folder as tempo.fbs for simpler imports.
docker run -v${PWD}:/opt/src neomantra/flatbuffers flatc --go -o /opt/src/pkg /opt/src/pkg/tempofb/tempo.fbs

### Check vendored files and generated proto
.PHONY: vendor-check
vendor-check: gen-proto
vendor-check: gen-proto gen-flat
go mod vendor
go mod tidy -e
git diff --exit-code -- go.sum go.mod vendor/ pkg/tempopb/
git diff --exit-code -- go.sum go.mod vendor/ pkg/tempopb/ pkg/tempofb/


### Release (intended to be used in the .github/workflows/images.yml)
$(GORELEASER):
Expand Down
2 changes: 1 addition & 1 deletion cmd/tempo-cli/cmd-gen-index.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func VerifyIndex(indexReader common.IndexReader, dataReader common.DataReader) e
}

// read data file at record position
_, _, err = dataReader.Read(context.TODO(), []common.Record{*record}, nil)
_, _, err = dataReader.Read(context.TODO(), []common.Record{*record}, nil, nil)
if err != nil {
fmt.Println("index/data is corrupt, record/data mismatch")
return err
Expand Down
17 changes: 13 additions & 4 deletions cmd/tempo-query/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ import (
"io"
"strings"

"github.com/spf13/viper"

"github.com/grafana/tempo/cmd/tempo-query/tempo"
"github.com/hashicorp/go-hclog"
hcplugin "github.com/hashicorp/go-plugin"
"github.com/jaegertracing/jaeger/plugin/storage/grpc"
"github.com/jaegertracing/jaeger/plugin/storage/grpc/shared"
"github.com/jaegertracing/jaeger/storage/dependencystore"
"github.com/jaegertracing/jaeger/storage/spanstore"
otgrpc "github.com/opentracing-contrib/go-grpc"
"github.com/opentracing/opentracing-go"
"github.com/spf13/viper"
jaeger_config "github.com/uber/jaeger-client-go/config"
google_grpc "google.golang.org/grpc"

"github.com/grafana/tempo/cmd/tempo-query/tempo"
)

func main() {
Expand Down Expand Up @@ -51,8 +55,13 @@ func main() {

backend := tempo.New(cfg)
plugin := &plugin{backend: backend}
grpc.Serve(&shared.PluginServices{
grpc.ServeWithGRPCServer(&shared.PluginServices{
Store: plugin,
}, func(options []google_grpc.ServerOption) *google_grpc.Server {
return hcplugin.DefaultGRPCServer([]google_grpc.ServerOption{
google_grpc.UnaryInterceptor(otgrpc.OpenTracingServerInterceptor(opentracing.GlobalTracer())),
google_grpc.StreamInterceptor(otgrpc.OpenTracingStreamServerInterceptor(opentracing.GlobalTracer())),
})
})
}

Expand Down
214 changes: 190 additions & 24 deletions cmd/tempo-query/tempo/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"strconv"
"time"

"github.com/gogo/protobuf/jsonpb"
"github.com/grafana/tempo/pkg/tempopb"
"github.com/opentracing/opentracing-go"
ot_log "github.com/opentracing/opentracing-go/log"
"github.com/weaveworks/common/user"
Expand All @@ -25,48 +29,45 @@ const (
ProtobufTypeHeaderValue = "application/protobuf"
)

const (
serviceSearchTag = "service.name"
operationSearchTag = "name"
minDurationSearchTag = "minDuration"
maxDurationSearchTag = "maxDuration"
numTracesSearchTag = "limit"
)

type Backend struct {
tempoEndpoint string
tempoBackend string
}

func New(cfg *Config) *Backend {
return &Backend{
tempoEndpoint: "http://" + cfg.Backend + "/api/traces/",
tempoBackend: cfg.Backend,
}
}

func (b *Backend) GetDependencies(ctx context.Context, endTs time.Time, lookback time.Duration) ([]jaeger.DependencyLink, error) {
return nil, nil
}

func (b *Backend) GetTrace(ctx context.Context, traceID jaeger.TraceID) (*jaeger.Trace, error) {
hexID := fmt.Sprintf("%016x%016x", traceID.High, traceID.Low)
url := fmt.Sprintf("http://%s/api/traces/%s", b.tempoBackend, traceID)

span, _ := opentracing.StartSpanFromContext(ctx, "GetTrace")
span, ctx := opentracing.StartSpanFromContext(ctx, "tempo-query.GetTrace")
defer span.Finish()

req, err := http.NewRequestWithContext(ctx, "GET", b.tempoEndpoint+hexID, nil)
req, err := b.newGetRequest(ctx, url, span)
if err != nil {
return nil, err
}

if tracer := opentracing.GlobalTracer(); tracer != nil {
// this is not really loggable or anything we can react to. just ignoring this error
_ = tracer.Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header))
}

// currently Jaeger Query will only propagate bearer token to the grpc backend and no other headers
// so we are going to extract the tenant id from the header, if it exists and use it
tenantID, found := extractBearerToken(ctx)
if found {
req.Header.Set(user.OrgIDHeaderName, tenantID)
}

// Set content type to grpc
// Set content type to GRPC
req.Header.Set(AcceptHeaderKey, ProtobufTypeHeaderValue)

resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("failed get to tempo %w", err)
return nil, fmt.Errorf("failed GET to tempo %w", err)
}
defer resp.Body.Close()

Expand All @@ -91,7 +92,7 @@ func (b *Backend) GetTrace(ctx context.Context, traceID jaeger.TraceID) (*jaeger

jaegerBatches, err := ot_jaeger.InternalTracesToJaegerProto(otTrace)
if err != nil {
return nil, fmt.Errorf("error translating to jaegerBatches %v: %w", hexID, err)
return nil, fmt.Errorf("error translating to jaegerBatches %v: %w", traceID, err)
}

jaegerTrace := &jaeger.Trace{
Expand All @@ -117,21 +118,186 @@ func (b *Backend) GetTrace(ctx context.Context, traceID jaeger.TraceID) (*jaeger
}

func (b *Backend) GetServices(ctx context.Context) ([]string, error) {
return nil, nil
span, ctx := opentracing.StartSpanFromContext(ctx, "tempo-query.GetOperations")
defer span.Finish()

return b.lookupTagValues(ctx, span, serviceSearchTag)
}

func (b *Backend) GetOperations(ctx context.Context, query jaeger_spanstore.OperationQueryParameters) ([]jaeger_spanstore.Operation, error) {
return nil, nil
span, ctx := opentracing.StartSpanFromContext(ctx, "tempo-query.GetOperations")
defer span.Finish()

tagValues, err := b.lookupTagValues(ctx, span, operationSearchTag)
if err != nil {
return nil, err
}

var operations []jaeger_spanstore.Operation
for _, value := range tagValues {
operations = append(operations, jaeger_spanstore.Operation{
Name: value,
SpanKind: "",
})
}

return operations, nil

}

func (b *Backend) FindTraces(ctx context.Context, query *jaeger_spanstore.TraceQueryParameters) ([]*jaeger.Trace, error) {
return nil, nil
span, ctx := opentracing.StartSpanFromContext(ctx, "tempo-query.FindTraces")
defer span.Finish()

traceIDs, err := b.FindTraceIDs(ctx, query)
if err != nil {
return nil, err
}

span.LogFields(ot_log.String("msg", fmt.Sprintf("Found %d trace IDs", len(traceIDs))))

// for every traceID, get the full trace
var jaegerTraces []*jaeger.Trace
for _, traceID := range traceIDs {
trace, err := b.GetTrace(ctx, traceID)
if err != nil {
// TODO this seems to be an internal inconsistency error, ignore so we can still show the rest
span.LogFields(ot_log.Error(fmt.Errorf("could not get trace for traceID %v: %w", traceID, err)))
continue
}

jaegerTraces = append(jaegerTraces, trace)
}

span.LogFields(ot_log.String("msg", fmt.Sprintf("Returning %d traces", len(jaegerTraces))))

return jaegerTraces, nil
}

func (b *Backend) FindTraceIDs(ctx context.Context, query *jaeger_spanstore.TraceQueryParameters) ([]jaeger.TraceID, error) {
return nil, nil
span, ctx := opentracing.StartSpanFromContext(ctx, "tempo-query.FindTraceIDs")
defer span.Finish()

url := url.URL{
Scheme: "http",
Host: b.tempoBackend,
Path: "api/search",
}
urlQuery := url.Query()
urlQuery.Set(serviceSearchTag, query.ServiceName)
urlQuery.Set(operationSearchTag, query.OperationName)
urlQuery.Set(minDurationSearchTag, query.DurationMin.String())
urlQuery.Set(maxDurationSearchTag, query.DurationMax.String())
urlQuery.Set(numTracesSearchTag, strconv.Itoa(query.NumTraces))
for k, v := range query.Tags {
urlQuery.Set(k, v)
}
url.RawQuery = urlQuery.Encode()

req, err := b.newGetRequest(ctx, url.String(), span)
if err != nil {
return nil, err
}

resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("failed GET to tempo %w", err)
}
defer resp.Body.Close()

// if search endpoint returns 404, search is most likely not enabled
if resp.StatusCode == http.StatusNotFound {
return nil, nil
}

if resp.StatusCode != http.StatusOK {
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response from Tempo: got %s", resp.Status)
}
return nil, fmt.Errorf("%s", body)
}

var searchResponse tempopb.SearchResponse
err = jsonpb.Unmarshal(resp.Body, &searchResponse)
if err != nil {
return nil, fmt.Errorf("error unmarshaling Tempo response: %w", err)
}

jaegerTraceIDs := make([]jaeger.TraceID, len(searchResponse.Traces))

for i, traceMetadata := range searchResponse.Traces {
jaegerTraceID, err := jaeger.TraceIDFromString(traceMetadata.TraceID)
if err != nil {
return nil, fmt.Errorf("could not convert traceID into Jaeger's traceID %w", err)
}
jaegerTraceIDs[i] = jaegerTraceID
}

return jaegerTraceIDs, nil
}

func (b *Backend) lookupTagValues(ctx context.Context, span opentracing.Span, tagName string) ([]string, error) {
url := fmt.Sprintf("http://%s/api/search/tag/%s/values", b.tempoBackend, tagName)

req, err := b.newGetRequest(ctx, url, span)
if err != nil {
return nil, err
}

resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("failed GET to tempo %w", err)
}
defer resp.Body.Close()

// if search endpoint returns 404, search is most likely not enabled
if resp.StatusCode == http.StatusNotFound {
return nil, nil
}

if resp.StatusCode != http.StatusOK {
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response from Tempo: got %s", resp.Status)
}
return nil, fmt.Errorf("%s", body)
}

var searchLookupResponse tempopb.SearchTagValuesResponse
err = jsonpb.Unmarshal(resp.Body, &searchLookupResponse)
if err != nil {
return nil, fmt.Errorf("error unmarshaling Tempo response: %w", err)
}

return searchLookupResponse.TagValues, nil
}

func (b *Backend) WriteSpan(ctx context.Context, span *jaeger.Span) error {
return nil
}

func (b *Backend) newGetRequest(ctx context.Context, url string, span opentracing.Span) (*http.Request, error) {
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return nil, err
}

if tracer := opentracing.GlobalTracer(); tracer != nil {
// this is not really loggable or anything we can react to. just ignoring this error
_ = tracer.Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header))
}

// currently Jaeger Query will only propagate bearer token to the grpc backend and no other headers
// so we are going to extract the tenant id from the header, if it exists and use it
tenantID, found := extractBearerToken(ctx)
if found {
req.Header.Set(user.OrgIDHeaderName, tenantID)
}

return req, nil
}

func extractBearerToken(ctx context.Context) (string, bool) {
if md, ok := metadata.FromIncomingContext(ctx); ok {
values := md.Get(spanstore.BearerTokenKey)
Expand Down
2 changes: 2 additions & 0 deletions cmd/tempo/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type Config struct {
Target string `yaml:"target,omitempty"`
AuthEnabled bool `yaml:"auth_enabled,omitempty"`
MultitenancyEnabled bool `yaml:"multitenancy_enabled,omitempty"`
SearchEnabled bool `yaml:"search_enabled,omitempty"`
HTTPAPIPrefix string `yaml:"http_api_prefix"`
UseOTelTracer bool `yaml:"use_otel_tracer,omitempty"`

Expand All @@ -68,6 +69,7 @@ func (c *Config) RegisterFlagsAndApplyDefaults(prefix string, f *flag.FlagSet) {
f.StringVar(&c.Target, "target", All, "target module")
f.BoolVar(&c.AuthEnabled, "auth.enabled", false, "Set to true to enable auth (deprecated: use multitenancy.enabled)")
f.BoolVar(&c.MultitenancyEnabled, "multitenancy.enabled", false, "Set to true to enable multitenancy.")
f.BoolVar(&c.SearchEnabled, "search.enabled", false, "Set to true to enable search (unstable).")
joe-elliott marked this conversation as resolved.
Show resolved Hide resolved
f.StringVar(&c.HTTPAPIPrefix, "http-api-prefix", "", "String prefix for all http api endpoints.")
f.BoolVar(&c.UseOTelTracer, "use-otel-tracer", false, "Set to true to replace the OpenTracing tracer with the OpenTelemetry tracer")

Expand Down
Loading