@@ -2,27 +2,16 @@ package api
22
33import (
44 "context"
5- "errors"
65 "flag"
76 "net/http"
8- "regexp"
97 "strings"
108 "time"
119
12- "github.com/opentracing-contrib/go-stdlib/nethttp"
13- "github.com/opentracing/opentracing-go"
14- "github.com/prometheus/client_golang/prometheus"
15- dto "github.com/prometheus/client_model/go"
16-
1710 "github.com/felixge/fgprof"
1811 "github.com/go-kit/kit/log"
1912 "github.com/go-kit/kit/log/level"
20- "github.com/gorilla/mux"
21- "github.com/prometheus/common/route"
22- "github.com/prometheus/prometheus/config"
23- "github.com/prometheus/prometheus/promql"
13+ "github.com/prometheus/client_golang/prometheus"
2414 "github.com/prometheus/prometheus/storage"
25- v1 "github.com/prometheus/prometheus/web/api/v1"
2615 "github.com/weaveworks/common/middleware"
2716 "github.com/weaveworks/common/server"
2817
@@ -104,23 +93,17 @@ func New(cfg Config, serverCfg server.Config, s *server.Server, logger log.Logge
10493// RegisterRoute registers a single route enforcing HTTP methods. A single
10594// route is expected to be specific about which HTTP methods are supported.
10695func (a * API ) RegisterRoute (path string , handler http.Handler , auth bool , method string , methods ... string ) {
107- a .registerRouteWithRouter (a .server .HTTP , path , handler , auth , method , methods ... )
108- }
109-
110- // RegisterRoute registers a single route to a router, enforcing HTTP methods. A single
111- // route is expected to be specific about which HTTP methods are supported.
112- func (a * API ) registerRouteWithRouter (router * mux.Router , path string , handler http.Handler , auth bool , method string , methods ... string ) {
11396 methods = append ([]string {method }, methods ... )
11497
11598 level .Debug (a .logger ).Log ("msg" , "api: registering route" , "methods" , strings .Join (methods , "," ), "path" , path , "auth" , auth )
11699 if auth {
117100 handler = a .authMiddleware .Wrap (handler )
118101 }
119102 if len (methods ) == 0 {
120- router .Path (path ).Handler (handler )
103+ a . server . HTTP .Path (path ).Handler (handler )
121104 return
122105 }
123- router .Path (path ).Methods (methods ... ).Handler (handler )
106+ a . server . HTTP .Path (path ).Methods (methods ... ).Handler (handler )
124107}
125108
126109func (a * API ) RegisterRoutesWithPrefix (prefix string , handler http.Handler , auth bool , methods ... string ) {
@@ -135,20 +118,6 @@ func (a *API) RegisterRoutesWithPrefix(prefix string, handler http.Handler, auth
135118 a .server .HTTP .PathPrefix (prefix ).Methods (methods ... ).Handler (handler )
136119}
137120
138- // Latest Prometheus requires r.RemoteAddr to be set to addr:port, otherwise it reject the request.
139- // Requests to Querier sometimes doesn't have that (if they are fetched from Query-Frontend).
140- // Prometheus uses this when logging queries to QueryLogger, but Cortex doesn't call engine.SetQueryLogger to set one.
141- //
142- // Can be removed when (if) https://github.com/prometheus/prometheus/pull/6840 is merged.
143- func fakeRemoteAddr (handler http.Handler ) http.Handler {
144- return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
145- if r .RemoteAddr == "" {
146- r .RemoteAddr = "127.0.0.1:8888"
147- }
148- handler .ServeHTTP (w , r )
149- })
150- }
151-
152121// RegisterAlertmanager registers endpoints associated with the alertmanager. It will only
153122// serve endpoints using the legacy http-prefix if it is not run as a single binary.
154123func (a * API ) RegisterAlertmanager (am * alertmanager.MultitenantAlertmanager , target , apiEnabled bool ) {
@@ -302,114 +271,22 @@ func (a *API) RegisterCompactor(c *compactor.Compactor) {
302271 a .RegisterRoute ("/compactor/ring" , http .HandlerFunc (c .RingHandler ), false , "GET" , "POST" )
303272}
304273
305- // RegisterQuerier registers the Prometheus routes supported by the
306- // Cortex querier service. Currently this can not be registered simultaneously
307- // with the QueryFrontend.
308- func (a * API ) RegisterQuerier (
274+ // RegisterQueryable registers the the default routes associated with the querier
275+ // module.
276+ func (a * API ) RegisterQueryable (
309277 queryable storage.SampleAndChunkQueryable ,
310- engine * promql.Engine ,
311278 distributor * distributor.Distributor ,
312- registerRoutesExternally bool ,
313- tombstonesLoader * purger.TombstonesLoader ,
314- querierRequestDuration * prometheus.HistogramVec ,
315- receivedMessageSize * prometheus.HistogramVec ,
316- sentMessageSize * prometheus.HistogramVec ,
317- inflightRequests * prometheus.GaugeVec ,
318- ) http.Handler {
319- api := v1 .NewAPI (
320- engine ,
321- errorTranslateQueryable {queryable }, // Translate errors to errors expected by API.
322- func (context.Context ) v1.TargetRetriever { return & querier.DummyTargetRetriever {} },
323- func (context.Context ) v1.AlertmanagerRetriever { return & querier.DummyAlertmanagerRetriever {} },
324- func () config.Config { return config.Config {} },
325- map [string ]string {}, // TODO: include configuration flags
326- v1.GlobalURLOptions {},
327- func (f http.HandlerFunc ) http.HandlerFunc { return f },
328- nil , // Only needed for admin APIs.
329- "" , // This is for snapshots, which is disabled when admin APIs are disabled. Hence empty.
330- false , // Disable admin APIs.
331- a .logger ,
332- func (context.Context ) v1.RulesRetriever { return & querier.DummyRulesRetriever {} },
333- 0 , 0 , 0 , // Remote read samples and concurrency limit.
334- regexp .MustCompile (".*" ),
335- func () (v1.RuntimeInfo , error ) { return v1.RuntimeInfo {}, errors .New ("not implemented" ) },
336- & v1.PrometheusVersion {},
337- // This is used for the stats API which we should not support. Or find other ways to.
338- prometheus .GathererFunc (func () ([]* dto.MetricFamily , error ) { return nil , nil }),
339- )
340-
279+ ) {
341280 // these routes are always registered to the default server
342281 a .RegisterRoute ("/api/v1/user_stats" , http .HandlerFunc (distributor .UserStatsHandler ), true , "GET" )
343282 a .RegisterRoute ("/api/v1/chunks" , querier .ChunksHandler (queryable ), true , "GET" )
344283
345284 a .RegisterRoute (a .cfg .LegacyHTTPPrefix + "/user_stats" , http .HandlerFunc (distributor .UserStatsHandler ), true , "GET" )
346285 a .RegisterRoute (a .cfg .LegacyHTTPPrefix + "/chunks" , querier .ChunksHandler (queryable ), true , "GET" )
347-
348- // these routes are either registered the default server OR to an internal mux. The internal mux is
349- // for use in a single binary mode when both the query frontend and the querier would attempt to claim these routes
350- // TODO: Add support to expose querier paths with a configurable prefix in single binary mode.
351- router := mux .NewRouter ()
352- if registerRoutesExternally {
353- router = a .server .HTTP
354- }
355-
356- // Use a separate metric for the querier in order to differentiate requests from the query-frontend when
357- // running Cortex as a single binary.
358- inst := middleware.Instrument {
359- RouteMatcher : router ,
360- Duration : querierRequestDuration ,
361- RequestBodySize : receivedMessageSize ,
362- ResponseBodySize : sentMessageSize ,
363- InflightRequests : inflightRequests ,
364- }
365-
366- promRouter := route .New ().WithPrefix (a .cfg .ServerPrefix + a .cfg .PrometheusHTTPPrefix + "/api/v1" )
367- api .Register (promRouter )
368- cacheGenHeaderMiddleware := getHTTPCacheGenNumberHeaderSetterMiddleware (tombstonesLoader )
369- promHandler := fakeRemoteAddr (inst .Wrap (cacheGenHeaderMiddleware .Wrap (promRouter )))
370-
371- a .registerRouteWithRouter (router , a .cfg .PrometheusHTTPPrefix + "/api/v1/read" , querier .RemoteReadHandler (queryable ), true , "POST" )
372- a .registerRouteWithRouter (router , a .cfg .PrometheusHTTPPrefix + "/api/v1/query" , promHandler , true , "GET" , "POST" )
373- a .registerRouteWithRouter (router , a .cfg .PrometheusHTTPPrefix + "/api/v1/query_range" , promHandler , true , "GET" , "POST" )
374- a .registerRouteWithRouter (router , a .cfg .PrometheusHTTPPrefix + "/api/v1/labels" , promHandler , true , "GET" , "POST" )
375- a .registerRouteWithRouter (router , a .cfg .PrometheusHTTPPrefix + "/api/v1/label/{name}/values" , promHandler , true , "GET" )
376- a .registerRouteWithRouter (router , a .cfg .PrometheusHTTPPrefix + "/api/v1/series" , promHandler , true , "GET" , "POST" , "DELETE" )
377- //TODO(gotjosh): This custom handler is temporary until we're able to vendor the changes in:
378- // https://github.com/prometheus/prometheus/pull/7125/files
379- a .registerRouteWithRouter (router , a .cfg .PrometheusHTTPPrefix + "/api/v1/metadata" , querier .MetadataHandler (distributor ), true , "GET" )
380-
381- legacyPromRouter := route .New ().WithPrefix (a .cfg .ServerPrefix + a .cfg .LegacyHTTPPrefix + "/api/v1" )
382- api .Register (legacyPromRouter )
383- legacyPromHandler := fakeRemoteAddr (inst .Wrap (cacheGenHeaderMiddleware .Wrap (legacyPromRouter )))
384-
385- a .registerRouteWithRouter (router , a .cfg .LegacyHTTPPrefix + "/api/v1/read" , querier .RemoteReadHandler (queryable ), true , "POST" )
386- a .registerRouteWithRouter (router , a .cfg .LegacyHTTPPrefix + "/api/v1/query" , legacyPromHandler , true , "GET" , "POST" )
387- a .registerRouteWithRouter (router , a .cfg .LegacyHTTPPrefix + "/api/v1/query_range" , legacyPromHandler , true , "GET" , "POST" )
388- a .registerRouteWithRouter (router , a .cfg .LegacyHTTPPrefix + "/api/v1/labels" , legacyPromHandler , true , "GET" , "POST" )
389- a .registerRouteWithRouter (router , a .cfg .LegacyHTTPPrefix + "/api/v1/label/{name}/values" , legacyPromHandler , true , "GET" )
390- a .registerRouteWithRouter (router , a .cfg .LegacyHTTPPrefix + "/api/v1/series" , legacyPromHandler , true , "GET" , "POST" , "DELETE" )
391- //TODO(gotjosh): This custom handler is temporary until we're able to vendor the changes in:
392- // https://github.com/prometheus/prometheus/pull/7125/files
393- a .registerRouteWithRouter (router , a .cfg .LegacyHTTPPrefix + "/api/v1/metadata" , querier .MetadataHandler (distributor ), true , "GET" )
394-
395- // if we have externally registered routes then we need to return the server handler
396- // so that we continue to use all standard middleware
397- if registerRoutesExternally {
398- return a .server .HTTPServer .Handler
399- }
400-
401- // Since we have a new router and the request will not go trough the default server
402- // HTTP middleware stack, we need to add a middleware to extract the trace context
403- // from the HTTP headers and inject it into the Go context.
404- return nethttp .MiddlewareFunc (opentracing .GlobalTracer (), router .ServeHTTP , nethttp .OperationNameFunc (func (r * http.Request ) string {
405- return "internalQuerier"
406- }))
407286}
408287
409- // registerQueryAPI registers the Prometheus routes supported by the
410- // Cortex querier service. Currently this can not be registered simultaneously
411- // with the Querier.
412- func (a * API ) registerQueryAPI (handler http.Handler ) {
288+ // RegisterQueryAPI registers the Prometheus API routes with the provided handler.
289+ func (a * API ) RegisterQueryAPI (handler http.Handler ) {
413290 a .RegisterRoute (a .cfg .PrometheusHTTPPrefix + "/api/v1/read" , handler , true , "POST" )
414291 a .RegisterRoute (a .cfg .PrometheusHTTPPrefix + "/api/v1/query" , handler , true , "GET" , "POST" )
415292 a .RegisterRoute (a .cfg .PrometheusHTTPPrefix + "/api/v1/query_range" , handler , true , "GET" , "POST" )
@@ -433,7 +310,7 @@ func (a *API) registerQueryAPI(handler http.Handler) {
433310// with the Querier.
434311func (a * API ) RegisterQueryFrontend (f * frontend.Frontend ) {
435312 frontend .RegisterFrontendServer (a .server .GRPC , f )
436- a .registerQueryAPI (f .Handler ())
313+ a .RegisterQueryAPI (f .Handler ())
437314}
438315
439316// RegisterServiceMapHandler registers the Cortex structs service handler
0 commit comments