Skip to content

Commit 63baf71

Browse files
committed
Allow the query-frontend code to proxy queries to 'vanilla' Prometheus.
Signed-off-by: Tom Wilkie <[email protected]>
1 parent 900ca62 commit 63baf71

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

pkg/querier/frontend/frontend.go

+30-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"io/ioutil"
99
"math/rand"
1010
"net/http"
11+
"net/url"
12+
"path"
1113
"sync"
1214
"time"
1315

@@ -57,6 +59,7 @@ type Config struct {
5759
CacheResults bool `yaml:"cache_results"`
5860
CompressResponses bool `yaml:"compress_responses"`
5961
queryrange.ResultsCacheConfig `yaml:"results_cache"`
62+
DownstreamURL string `yaml:"downstream"`
6063
}
6164

6265
// RegisterFlags adds the flags required to config this to the given FlagSet.
@@ -68,6 +71,7 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
6871
f.BoolVar(&cfg.CacheResults, "querier.cache-results", false, "Cache query results.")
6972
f.BoolVar(&cfg.CompressResponses, "querier.compress-http-responses", false, "Compress HTTP responses.")
7073
cfg.ResultsCacheConfig.RegisterFlags(f)
74+
f.StringVar(&cfg.DownstreamURL, "querier.downstream-url", "", "URL of downstream Prometheus.")
7175
}
7276

7377
// Frontend queues HTTP requests, dispatches them to backends, and handles retries
@@ -99,6 +103,7 @@ func New(cfg Config, log log.Logger, limits *validation.Overrides) (*Frontend, e
99103
log: log,
100104
queues: map[string]chan *request{},
101105
}
106+
f.cond = sync.NewCond(&f.mtx)
102107

103108
// Stack up the pipeline of various query range middlewares.
104109
var queryRangeMiddleware []queryrange.Middleware
@@ -119,8 +124,24 @@ func New(cfg Config, log log.Logger, limits *validation.Overrides) (*Frontend, e
119124
queryRangeMiddleware = append(queryRangeMiddleware, queryrange.InstrumentMiddleware("retry", queryRangeDuration), queryrange.NewRetryMiddleware(log, cfg.MaxRetries))
120125
}
121126

122-
// Finally, if the user selected any query range middleware, stitch it in.
127+
// If the user has specified a downstream Prometheus, then we should
128+
// forward requests to that. Otherwise we will wait for queries to
129+
// contact us.
123130
var roundTripper http.RoundTripper = f
131+
if cfg.DownstreamURL != "" {
132+
u, err := url.Parse(cfg.DownstreamURL)
133+
if err != nil {
134+
return nil, err
135+
}
136+
137+
roundTripper = RoundTripFunc(func(r *http.Request) (*http.Response, error) {
138+
r.URL.Host = u.Host
139+
r.URL.Path = path.Join(u.Path, r.URL.Path)
140+
return http.DefaultTransport.RoundTrip(r)
141+
})
142+
}
143+
144+
// Finally, if the user selected any query range middleware, stitch it in.
124145
if len(queryRangeMiddleware) > 0 {
125146
roundTripper = queryrange.NewRoundTripper(
126147
f,
@@ -129,10 +150,17 @@ func New(cfg Config, log log.Logger, limits *validation.Overrides) (*Frontend, e
129150
)
130151
}
131152
f.roundTripper = roundTripper
132-
f.cond = sync.NewCond(&f.mtx)
133153
return f, nil
134154
}
135155

156+
// RoundTripFunc is to http.RoundTripper what http.HandlerFunc is to http.Handler.
157+
type RoundTripFunc func(*http.Request) (*http.Response, error)
158+
159+
// RoundTrip implements http.RoundTripper.
160+
func (f RoundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) {
161+
return f(r)
162+
}
163+
136164
// Close stops new requests and errors out any pending requests.
137165
func (f *Frontend) Close() {
138166
f.mtx.Lock()

0 commit comments

Comments
 (0)