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

Configurable http api prefix #631

Merged
merged 6 commits into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -12,6 +12,7 @@
This is a **breaking change** and will likely result in query errors on rollout as the query signature b/n QueryFrontend & Querier has changed. [#557](https://github.com/grafana/tempo/pull/557)
* [ENHANCEMENT] Add list compaction-summary command to tempo-cli [#588](https://github.com/grafana/tempo/pull/588)
* [ENHANCEMENT] Add list and view index commands to tempo-cli [#611](https://github.com/grafana/tempo/pull/611)
* [ENHANCEMENT] Add a configurable prefix for HTTP endpoints. [#631](https://github.com/grafana/tempo/pull/631)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this count as a breaking change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure. It technically unbreaks the hardcoded /tempo breaking change :). So 0.6.0 => 0.7.0 will not be a breaking change. While this exact commit is a breaking change from the previous one.

I think for this reason we leave it out.

* [BUGFIX] Fixes permissions errors on startup in GCS. [#554](https://github.com/grafana/tempo/pull/554)
* [BUGFIX] Fixes error where Dell ECS cannot list objects. [#561](https://github.com/grafana/tempo/pull/561)
* [BUGFIX] Fixes listing blocks in S3 when the list is truncated. [#567](https://github.com/grafana/tempo/pull/567)
Expand Down
2 changes: 1 addition & 1 deletion cmd/tempo-query/tempo/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type Backend struct {

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

Expand Down
7 changes: 4 additions & 3 deletions cmd/tempo/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ const metricsNamespace = "tempo"

// Config is the root config for App.
type Config struct {
Target string `yaml:"target,omitempty"`
AuthEnabled bool `yaml:"auth_enabled,omitempty"`
HTTPPrefix string `yaml:"http_prefix"`
Target string `yaml:"target,omitempty"`
AuthEnabled bool `yaml:"auth_enabled,omitempty"`
HTTPAPIPrefix string `yaml:"http_api_prefix"`

Server server.Config `yaml:"server,omitempty"`
Distributor distributor.Config `yaml:"distributor,omitempty"`
Expand All @@ -63,6 +63,7 @@ func (c *Config) RegisterFlagsAndApplyDefaults(prefix string, f *flag.FlagSet) {
// global settings
f.StringVar(&c.Target, "target", All, "target module")
f.BoolVar(&c.AuthEnabled, "auth.enabled", true, "Set to false to disable auth.")
f.StringVar(&c.HTTPAPIPrefix, "http-api-prefix", "", "String prefix for all http api endpoints.")

// Server settings
flagext.DefaultValues(&c.Server)
Expand Down
12 changes: 6 additions & 6 deletions cmd/tempo/app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ const (
All string = "all"
)

const (
queryEndpoint = "/tempo/api/traces/{traceID}"
)

func (t *App) initServer() (services.Service, error) {
t.cfg.Server.MetricsNamespace = metricsNamespace
t.cfg.Server.ExcludeRequestInLog = true
Expand Down Expand Up @@ -155,7 +151,7 @@ func (t *App) initQuerier() (services.Service, error) {
t.httpAuthMiddleware,
).Wrap(http.HandlerFunc(t.querier.TraceByIDHandler))

t.server.HTTP.Handle("/querier"+queryEndpoint, tracesHandler)
t.server.HTTP.Handle("/querier"+queryEndpoint(&t.cfg), tracesHandler)
return t.querier, t.querier.CreateAndRegisterWorker(t.server.HTTPServer.Handler)
}

Expand Down Expand Up @@ -187,7 +183,7 @@ func (t *App) initQueryFrontend() (services.Service, error) {
// register grpc server for queriers to connect to
cortex_frontend_v1pb.RegisterFrontendServer(t.server.GRPC, t.frontend)
// http query endpoint
t.server.HTTP.Handle(queryEndpoint, tracesHandler)
t.server.HTTP.Handle(queryEndpoint(&t.cfg), tracesHandler)

return services.NewIdleService(nil, func(_ error) error {
t.frontend.Close()
Expand Down Expand Up @@ -277,3 +273,7 @@ func (t *App) setupModuleManager() error {

return nil
}

func queryEndpoint(cfg *Config) string {
return cfg.HTTPAPIPrefix + "/api/traces/{traceID}"
}
4 changes: 2 additions & 2 deletions docs/tempo/website/architecture/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Batches traces into blocks, blooms, indexes and flushes to backend. Blocks in t
Responsible for sharding the search space for an incoming query.

Traces are exposed via a simple HTTP endpoint:
`GET /tempo/api/traces/<traceID>`
`GET /api/traces/<traceID>`

Internally, the Query Frontend splits the blockID space into a configurable number of shards and queues these requests.
Queriers connect to the Query Frontend via a streaming gRPC connection to process these sharded queries.
Expand All @@ -45,7 +45,7 @@ Queriers connect to the Query Frontend via a streaming gRPC connection to proces
The querier is responsible for finding the requested trace id in either the ingesters or the backend storage. It begins by querying the ingesters to see if the id is currently stored there, if not it proceeds to use the bloom and indexes to find the trace in the storage backend.

The querier exposes an HTTP endpoint at:
`GET /querier/tempo/api/traces/<traceID>`, but its not expected to be used directly.
`GET /querier/api/traces/<traceID>`, but its not expected to be used directly.

Queries should be sent to the Query Frontend.

Expand Down
Binary file modified docs/tempo/website/configuration/ds75.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion docs/tempo/website/configuration/querying.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ and help you set up your datasources appropriately.
## Grafana 7.5.x (easy mode)

Grafana 7.5.x is able to query Tempo directly. Point the Grafana datasource at your Tempo query frontend (or single
binary) and enter the url: `http://<tempo hostname>:<http port number>/tempo`. For most of [our examples](https://github.com/grafana/tempo/tree/master/example/docker-compose) the following works.
binary) and enter the url: `http://<tempo hostname>:<http port number>`. For most of [our examples](https://github.com/grafana/tempo/tree/master/example/docker-compose) the following works.

<p align="center"><img src="../ds75.png" alt="Grafana 7.5.x datasource"></p>

Note that the port of 3100 is a common port used in our examples. Tempo default for http is 80.


## Grafana 7.4.x

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ datasources:
type: tempo
access: proxy
orgId: 1
url: http://tempo:3100/tempo
url: http://tempo:3100
basicAuth: false
isDefault: false
version: 1
Expand All @@ -29,7 +29,7 @@ datasources:
type: tempo
access: proxy
orgId: 1
url: http://tempo/tempo
url: http://tempo
basicAuth: false
isDefault: false
version: 1
Expand Down
2 changes: 1 addition & 1 deletion integration/bench/smoke_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function readPath() {

console.log(`type=read traceId=${traceId}`);

let res = http.get(`${QUERY_ENDPOINT}/tempo/api/traces/${traceId}`, params);
let res = http.get(`${QUERY_ENDPOINT}/api/traces/${traceId}`, params);
check(res, {
'read status is 200': (r) => r.status === 200,
}, { type: 'read' });
Expand Down
14 changes: 7 additions & 7 deletions integration/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestAllInOne(t *testing.T) {
require.NoError(t, tempo.WaitSumMetrics(cortex_e2e.Equals(1), "tempo_ingester_traces_created_total"))

// query an in-memory trace
queryAndAssertTrace(t, "http://"+tempo.Endpoint(3100)+"/tempo/api/traces/"+hexID, "my operation", 1)
queryAndAssertTrace(t, "http://"+tempo.Endpoint(3100)+"/api/traces/"+hexID, "my operation", 1)

// flush trace to backend
res, err := cortex_e2e.GetRequest("http://" + tempo.Endpoint(3100) + "/flush")
Expand All @@ -78,7 +78,7 @@ func TestAllInOne(t *testing.T) {
require.NoError(t, tempo.WaitSumMetrics(cortex_e2e.Equals(1), "tempo_query_frontend_queries_total"))

// query trace - should fetch from backend
queryAndAssertTrace(t, "http://"+tempo.Endpoint(3100)+"/tempo/api/traces/"+hexID, "my operation", 1)
queryAndAssertTrace(t, "http://"+tempo.Endpoint(3100)+"/api/traces/"+hexID, "my operation", 1)
}

func TestAzuriteAllInOne(t *testing.T) {
Expand Down Expand Up @@ -121,7 +121,7 @@ func TestAzuriteAllInOne(t *testing.T) {
require.NoError(t, tempo.WaitSumMetrics(cortex_e2e.Equals(1), "tempo_ingester_traces_created_total"))

// query an in-memory trace
queryAndAssertTrace(t, "http://"+tempo.Endpoint(3100)+"/tempo/api/traces/"+hexID, "my operation", 1)
queryAndAssertTrace(t, "http://"+tempo.Endpoint(3100)+"/api/traces/"+hexID, "my operation", 1)

// flush trace to backend
res, err := cortex_e2e.GetRequest("http://" + tempo.Endpoint(3100) + "/flush")
Expand All @@ -136,7 +136,7 @@ func TestAzuriteAllInOne(t *testing.T) {
require.NoError(t, tempo.WaitSumMetrics(cortex_e2e.Equals(1), "tempodb_blocklist_length"))

// query trace - should fetch from backend
queryAndAssertTrace(t, "http://"+tempo.Endpoint(3100)+"/tempo/api/traces/"+hexID, "my operation", 1)
queryAndAssertTrace(t, "http://"+tempo.Endpoint(3100)+"/api/traces/"+hexID, "my operation", 1)

}
func TestMicroservices(t *testing.T) {
Expand Down Expand Up @@ -192,7 +192,7 @@ func TestMicroservices(t *testing.T) {
require.NoError(t, tempoIngester3.WaitSumMetrics(cortex_e2e.Equals(1), "tempo_ingester_traces_created_total"))

// query an in-memory trace
queryAndAssertTrace(t, "http://"+tempoQueryFrontend.Endpoint(3100)+"/tempo/api/traces/"+hexID, "my operation", 1)
queryAndAssertTrace(t, "http://"+tempoQueryFrontend.Endpoint(3100)+"/api/traces/"+hexID, "my operation", 1)

// flush trace to backend
res, err := cortex_e2e.GetRequest("http://" + tempoIngester1.Endpoint(3100) + "/flush")
Expand All @@ -214,7 +214,7 @@ func TestMicroservices(t *testing.T) {
require.NoError(t, tempoQueryFrontend.WaitSumMetrics(cortex_e2e.Equals(1), "tempo_query_frontend_queries_total"))

// query trace - should fetch from backend
queryAndAssertTrace(t, "http://"+tempoQueryFrontend.Endpoint(3100)+"/tempo/api/traces/"+hexID, "my operation", 1)
queryAndAssertTrace(t, "http://"+tempoQueryFrontend.Endpoint(3100)+"/api/traces/"+hexID, "my operation", 1)

// stop an ingester and confirm we can still write and query
err = tempoIngester2.Stop()
Expand All @@ -228,7 +228,7 @@ func TestMicroservices(t *testing.T) {
hexID = fmt.Sprintf("%016x%016x", batch.Spans[0].TraceIdHigh, batch.Spans[0].TraceIdLow)

// query an in-memory trace
queryAndAssertTrace(t, "http://"+tempoQueryFrontend.Endpoint(3100)+"/tempo/api/traces/"+hexID, "my operation", 1)
queryAndAssertTrace(t, "http://"+tempoQueryFrontend.Endpoint(3100)+"/api/traces/"+hexID, "my operation", 1)

// stop another ingester and confirm things fail
err = tempoIngester1.Stop()
Expand Down
1 change: 1 addition & 0 deletions operations/tempo-mixin/config.libsonnet
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
_config+:: {
http_api_prefix: '',
jobs: {
gateway: 'cortex-gw',
query_frontend: 'query-frontend',
Expand Down
12 changes: 6 additions & 6 deletions operations/tempo-mixin/dashboards.libsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ dashboard_utils {
g.row('Gateway')
.addPanel(
$.panel('QPS') +
$.qpsPanel('tempo_request_duration_seconds_count{%s, route="tempo_api_traces_traceid"}' % $.jobMatcher($._config.jobs.gateway))
$.qpsPanel('tempo_request_duration_seconds_count{%s, route="%sapi_traces_traceid"}' % [$.jobMatcher($._config.jobs.gateway), $._config.http_api_prefix])
)
.addPanel(
$.panel('Latency') +
$.latencyPanel('tempo_request_duration_seconds', '{%s,route="tempo_api_traces_traceid"}' % $.jobMatcher($._config.jobs.gateway))
$.latencyPanel('tempo_request_duration_seconds', '{%s,route="%sapi_traces_traceid"}' % [$.jobMatcher($._config.jobs.gateway), $._config.http_api_prefix])
)
)
.addRow(
Expand All @@ -34,22 +34,22 @@ dashboard_utils {
g.row('Query Frontend')
.addPanel(
$.panel('QPS') +
$.qpsPanel('tempo_request_duration_seconds_count{%s, route="tempo_api_traces_traceid"}' % $.jobMatcher($._config.jobs.query_frontend))
$.qpsPanel('tempo_request_duration_seconds_count{%s, route="%sapi_traces_traceid"}' % [$.jobMatcher($._config.jobs.query_frontend), $._config.http_api_prefix])
)
.addPanel(
$.panel('Latency') +
$.latencyPanel('tempo_request_duration_seconds', '{%s,route="tempo_api_traces_traceid"}' % $.jobMatcher($._config.jobs.query_frontend))
$.latencyPanel('tempo_request_duration_seconds', '{%s,route="%sapi_traces_traceid"}' % [$.jobMatcher($._config.jobs.query_frontend), $._config.http_api_prefix])
)
)
.addRow(
g.row('Querier')
.addPanel(
$.panel('QPS') +
$.qpsPanel('tempo_request_duration_seconds_count{%s, route="querier_tempo_api_traces_traceid"}' % $.jobMatcher($._config.jobs.querier))
$.qpsPanel('tempo_request_duration_seconds_count{%s, route="querier_%sapi_traces_traceid"}' % [$.jobMatcher($._config.jobs.querier), $._config.http_api_prefix])
)
.addPanel(
$.panel('Latency') +
$.latencyPanel('tempo_request_duration_seconds', '{%s,route="querier_tempo_api_traces_traceid"}' % $.jobMatcher($._config.jobs.querier))
$.latencyPanel('tempo_request_duration_seconds', '{%s,route="querier_%sapi_traces_traceid"}' % [$.jobMatcher($._config.jobs.querier), $._config.http_api_prefix])
)
)
.addRow(
Expand Down
Loading