Skip to content

Commit e3221b2

Browse files
authored
Separate HTTP Instrumentation for Querier (#2708)
* separate instrumentation for the querier Signed-off-by: Jacob Lisi <[email protected]> * check for prefix in integration tests Signed-off-by: Jacob Lisi <[email protected]> * fix linting issues Signed-off-by: Jacob Lisi <[email protected]> * refactor per PR comments Signed-off-by: Jacob Lisi <[email protected]> * fix liniting errors Signed-off-by: Jacob Lisi <[email protected]> * update the changelog Signed-off-by: Jacob Lisi <[email protected]> * make registerQueryAPI private Signed-off-by: Jacob Lisi <[email protected]>
1 parent 34b45d1 commit e3221b2

File tree

4 files changed

+54
-27
lines changed

4 files changed

+54
-27
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
* [FEATURE] TLS config options added for GRPC clients in Querier (Query-frontend client & Ingester client), Ruler, Store Gateway, as well as HTTP client in Config store client. #2502
5454
* [FEATURE] The flag `-frontend.max-cache-freshness` is now supported within the limits overrides, to specify per-tenant max cache freshness values. The corresponding YAML config parameter has been changed from `results_cache.max_freshness` to `limits_config.max_cache_freshness`. The legacy YAML config parameter (`results_cache.max_freshness`) will continue to be supported till Cortex release `v1.4.0`. #2609
5555
* [FEATURE] Experimental gRPC Store: Added support to 3rd parties index and chunk stores using gRPC client/server plugin mechanism. #2220
56+
* [ENHANCEMENT] Querier: Added metric `cortex_querier_request_duration_seconds` for all requests to the querier. #2708
5657
* [ENHANCEMENT] Experimental TSDB: added the following metrics to the ingester: #2580 #2583 #2589 #2654
5758
* `cortex_ingester_tsdb_appender_add_duration_seconds`
5859
* `cortex_ingester_tsdb_appender_commit_duration_seconds`

integration/asserts.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var (
3030
serviceMetricsPrefixes = map[ServiceType][]string{
3131
Distributor: {},
3232
Ingester: {"!cortex_ingester_client", "cortex_ingester"}, // The metrics prefix cortex_ingester_client may be used by other components so we ignore it.
33-
Querier: {},
33+
Querier: {"cortex_querier"},
3434
QueryFrontend: {"cortex_frontend", "cortex_query_frontend"},
3535
TableManager: {},
3636
AlertManager: {"cortex_alertmanager"},

pkg/api/api.go

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
"github.com/go-kit/kit/log"
1616
"github.com/go-kit/kit/log/level"
17+
"github.com/gorilla/mux"
1718
"github.com/prometheus/common/route"
1819
"github.com/prometheus/prometheus/config"
1920
"github.com/prometheus/prometheus/promql"
@@ -22,8 +23,6 @@ import (
2223
"github.com/weaveworks/common/middleware"
2324
"github.com/weaveworks/common/server"
2425

25-
"github.com/gorilla/mux"
26-
2726
"github.com/cortexproject/cortex/pkg/alertmanager"
2827
"github.com/cortexproject/cortex/pkg/chunk/purger"
2928
"github.com/cortexproject/cortex/pkg/compactor"
@@ -252,7 +251,14 @@ func (a *API) RegisterCompactor(c *compactor.Compactor) {
252251
// RegisterQuerier registers the Prometheus routes supported by the
253252
// Cortex querier service. Currently this can not be registered simultaneously
254253
// with the QueryFrontend.
255-
func (a *API) RegisterQuerier(queryable storage.Queryable, engine *promql.Engine, distributor *distributor.Distributor, registerRoutesExternally bool, tombstonesLoader *purger.TombstonesLoader) http.Handler {
254+
func (a *API) RegisterQuerier(
255+
queryable storage.Queryable,
256+
engine *promql.Engine,
257+
distributor *distributor.Distributor,
258+
registerRoutesExternally bool,
259+
tombstonesLoader *purger.TombstonesLoader,
260+
querierRequestDuration *prometheus.HistogramVec,
261+
) http.Handler {
256262
api := v1.NewAPI(
257263
engine,
258264
queryable,
@@ -288,10 +294,17 @@ func (a *API) RegisterQuerier(queryable storage.Queryable, engine *promql.Engine
288294
router = a.server.HTTP
289295
}
290296

297+
// Use a separate metric for the querier in order to differentiate requests from the query-frontend when
298+
// running Cortex as a single binary.
299+
inst := middleware.Instrument{
300+
Duration: querierRequestDuration,
301+
RouteMatcher: router,
302+
}
303+
291304
promRouter := route.New().WithPrefix(a.cfg.ServerPrefix + a.cfg.PrometheusHTTPPrefix + "/api/v1")
292305
api.Register(promRouter)
293306
cacheGenHeaderMiddleware := getHTTPCacheGenNumberHeaderSetterMiddleware(tombstonesLoader)
294-
promHandler := fakeRemoteAddr(cacheGenHeaderMiddleware.Wrap(promRouter))
307+
promHandler := fakeRemoteAddr(inst.Wrap(cacheGenHeaderMiddleware.Wrap(promRouter)))
295308

296309
a.registerRouteWithRouter(router, a.cfg.PrometheusHTTPPrefix+"/api/v1/read", querier.RemoteReadHandler(queryable), true, "POST")
297310
a.registerRouteWithRouter(router, a.cfg.PrometheusHTTPPrefix+"/api/v1/query", promHandler, true, "GET", "POST")
@@ -305,7 +318,7 @@ func (a *API) RegisterQuerier(queryable storage.Queryable, engine *promql.Engine
305318

306319
legacyPromRouter := route.New().WithPrefix(a.cfg.ServerPrefix + a.cfg.LegacyHTTPPrefix + "/api/v1")
307320
api.Register(legacyPromRouter)
308-
legacyPromHandler := fakeRemoteAddr(cacheGenHeaderMiddleware.Wrap(legacyPromRouter))
321+
legacyPromHandler := fakeRemoteAddr(inst.Wrap(cacheGenHeaderMiddleware.Wrap(legacyPromRouter)))
309322

310323
a.registerRouteWithRouter(router, a.cfg.LegacyHTTPPrefix+"/api/v1/read", querier.RemoteReadHandler(queryable), true, "POST")
311324
a.registerRouteWithRouter(router, a.cfg.LegacyHTTPPrefix+"/api/v1/query", legacyPromHandler, true, "GET", "POST")
@@ -331,31 +344,34 @@ func (a *API) RegisterQuerier(queryable storage.Queryable, engine *promql.Engine
331344
}))
332345
}
333346

347+
// registerQueryAPI registers the Prometheus routes supported by the
348+
// Cortex querier service. Currently this can not be registered simultaneously
349+
// with the Querier.
350+
func (a *API) registerQueryAPI(handler http.Handler) {
351+
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/read", handler, true, "POST")
352+
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/query", handler, true, "GET", "POST")
353+
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/query_range", handler, true, "GET", "POST")
354+
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/labels", handler, true, "GET", "POST")
355+
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/label/{name}/values", handler, true, "GET")
356+
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/series", handler, true, "GET", "POST", "DELETE")
357+
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/metadata", handler, true, "GET")
358+
359+
// Register Legacy Routers
360+
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/read", handler, true, "POST")
361+
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/query", handler, true, "GET", "POST")
362+
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/query_range", handler, true, "GET", "POST")
363+
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/labels", handler, true, "GET", "POST")
364+
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/label/{name}/values", handler, true, "GET")
365+
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/series", handler, true, "GET", "POST", "DELETE")
366+
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/metadata", handler, true, "GET")
367+
}
368+
334369
// RegisterQueryFrontend registers the Prometheus routes supported by the
335370
// Cortex querier service. Currently this can not be registered simultaneously
336371
// with the Querier.
337372
func (a *API) RegisterQueryFrontend(f *frontend.Frontend) {
338373
frontend.RegisterFrontendServer(a.server.GRPC, f)
339-
340-
// Previously the frontend handled all calls to the provided prefix. Instead explicit
341-
// routing is used since it will be required to enable the frontend to be run as part
342-
// of a single binary in the future.
343-
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/read", f.Handler(), true, "POST")
344-
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/query", f.Handler(), true, "GET", "POST")
345-
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/query_range", f.Handler(), true, "GET", "POST")
346-
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/labels", f.Handler(), true, "GET", "POST")
347-
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/label/{name}/values", f.Handler(), true, "GET")
348-
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/series", f.Handler(), true, "GET", "POST", "DELETE")
349-
a.RegisterRoute(a.cfg.PrometheusHTTPPrefix+"/api/v1/metadata", f.Handler(), true, "GET")
350-
351-
// Register Legacy Routers
352-
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/read", f.Handler(), true, "POST")
353-
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/query", f.Handler(), true, "GET", "POST")
354-
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/query_range", f.Handler(), true, "GET", "POST")
355-
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/labels", f.Handler(), true, "GET", "POST")
356-
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/label/{name}/values", f.Handler(), true, "GET")
357-
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/series", f.Handler(), true, "GET", "POST", "DELETE")
358-
a.RegisterRoute(a.cfg.LegacyHTTPPrefix+"/api/v1/metadata", f.Handler(), true, "GET")
374+
a.registerQueryAPI(f.Handler())
359375
}
360376

361377
// RegisterServiceMapHandler registers the Cortex structs service handler

pkg/cortex/modules.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import (
66

77
"github.com/go-kit/kit/log/level"
88
"github.com/prometheus/client_golang/prometheus"
9+
"github.com/prometheus/client_golang/prometheus/promauto"
910
"github.com/prometheus/prometheus/promql"
1011
httpgrpc_server "github.com/weaveworks/common/httpgrpc/server"
12+
"github.com/weaveworks/common/instrument"
1113
"github.com/weaveworks/common/server"
1214

1315
"github.com/cortexproject/cortex/pkg/alertmanager"
@@ -162,9 +164,17 @@ func (t *Cortex) initDistributor() (serv services.Service, err error) {
162164
func (t *Cortex) initQuerier() (serv services.Service, err error) {
163165
queryable, engine := querier.New(t.Cfg.Querier, t.Distributor, t.StoreQueryable, t.TombstonesLoader, prometheus.DefaultRegisterer)
164166

167+
// Prometheus histograms for requests to the querier.
168+
querierRequestDuration := promauto.With(prometheus.DefaultRegisterer).NewHistogramVec(prometheus.HistogramOpts{
169+
Namespace: "cortex",
170+
Name: "querier_request_duration_seconds",
171+
Help: "Time (in seconds) spent serving HTTP requests to the querier.",
172+
Buckets: instrument.DefBuckets,
173+
}, []string{"method", "route", "status_code", "ws"})
174+
165175
// if we are not configured for single binary mode then the querier needs to register its paths externally
166176
registerExternally := t.Cfg.Target != All
167-
handler := t.API.RegisterQuerier(queryable, engine, t.Distributor, registerExternally, t.TombstonesLoader)
177+
handler := t.API.RegisterQuerier(queryable, engine, t.Distributor, registerExternally, t.TombstonesLoader, querierRequestDuration)
168178

169179
// single binary mode requires a properly configured worker. if the operator did not attempt to configure the
170180
// worker we will attempt an automatic configuration here

0 commit comments

Comments
 (0)