Skip to content

Commit

Permalink
Configurable http api prefix (#631)
Browse files Browse the repository at this point in the history
* HTTP Prefix

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

* updated docs

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

* Updated querying config docs

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

* changelog

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

* fixed benchmark

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

* Fixed dashboareds

Signed-off-by: Joe Elliott <number101010@gmail.com>
  • Loading branch information
joe-elliott committed Apr 6, 2021
1 parent 154ec0b commit b08c409
Show file tree
Hide file tree
Showing 16 changed files with 109 additions and 104 deletions.
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)
* [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

0 comments on commit b08c409

Please sign in to comment.