Skip to content
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 @@ -23,6 +23,7 @@
* `cortex_prometheus_notifications_queue_capacity`
* `cortex_prometheus_notifications_alertmanagers_discovered`
* [ENHANCEMENT] Added `-ingester.flush-on-shutdown-with-wal-enabled` option to enable chunks flushing even when WAL is enabled. #2780
* [ENHANCEMENT] Query-tee: Support for custom API prefix by using `-server.path-prefix` option. #2814
* [BUGFIX] Fixed a bug in the index intersect code causing storage to return more chunks/series than required. #2796
* [BUGFIX] Fixed the number of reported keys in the background cache queue. #2764
* [BUGFIX] Fix race in processing of headers in sharded queries. #2762
Expand Down
27 changes: 17 additions & 10 deletions cmd/query-tee/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ type Config struct {
ServerMetricsPort int
LogLevel logging.Level
ProxyConfig querytee.ProxyConfig
PathPrefix string
}

func main() {
// Parse CLI flags.
cfg := Config{}
flag.IntVar(&cfg.ServerMetricsPort, "server.metrics-port", 9900, "The port where metrics are exposed.")
flag.StringVar(&cfg.PathPrefix, "server.path-prefix", "", "Prefix for API paths (query-tee will accept Prometheus API calls at <prefix>/api/v1/...)")
cfg.LogLevel.RegisterFlags(flag.CommandLine)
cfg.ProxyConfig.RegisterFlags(flag.CommandLine)
flag.Parse()
Expand All @@ -42,7 +44,7 @@ func main() {
}

// Run the proxy.
proxy, err := querytee.NewProxy(cfg.ProxyConfig, util.Logger, cortexReadRoutes(), registry)
proxy, err := querytee.NewProxy(cfg.ProxyConfig, util.Logger, cortexReadRoutes(cfg.PathPrefix), registry)
if err != nil {
level.Error(util.Logger).Log("msg", "Unable to initialize the proxy", "err", err.Error())
os.Exit(1)
Expand All @@ -56,16 +58,21 @@ func main() {
proxy.Await()
}

func cortexReadRoutes() []querytee.Route {
func cortexReadRoutes(prefix string) []querytee.Route {
// Strip trailing slashes.
for len(prefix) > 0 && prefix[len(prefix)-1] == '/' {
prefix = prefix[:len(prefix)-1]
}

samplesComparator := querytee.NewSamplesComparator()
return []querytee.Route{
{Path: "/api/v1/query", RouteName: "api_v1_query", Methods: []string{"GET"}, ResponseComparator: samplesComparator},
{Path: "/api/v1/query_range", RouteName: "api_v1_query_range", Methods: []string{"GET"}, ResponseComparator: samplesComparator},
{Path: "/api/v1/labels", RouteName: "api_v1_labels", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/api/v1/label/{name}/values", RouteName: "api_v1_label_name_values", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/api/v1/series", RouteName: "api_v1_series", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/api/v1/metadata", RouteName: "api_v1_metadata", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/api/v1/rules", RouteName: "api_v1_rules", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/api/v1/alerts", RouteName: "api_v1_alerts", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: prefix + "/api/v1/query", RouteName: "api_v1_query", Methods: []string{"GET"}, ResponseComparator: samplesComparator},
{Path: prefix + "/api/v1/query_range", RouteName: "api_v1_query_range", Methods: []string{"GET"}, ResponseComparator: samplesComparator},
{Path: prefix + "/api/v1/labels", RouteName: "api_v1_labels", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: prefix + "/api/v1/label/{name}/values", RouteName: "api_v1_label_name_values", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: prefix + "/api/v1/series", RouteName: "api_v1_series", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: prefix + "/api/v1/metadata", RouteName: "api_v1_metadata", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: prefix + "/api/v1/rules", RouteName: "api_v1_rules", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: prefix + "/api/v1/alerts", RouteName: "api_v1_alerts", Methods: []string{"GET"}, ResponseComparator: nil},
}
}
20 changes: 20 additions & 0 deletions cmd/query-tee/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

func TestCortexReadRoutes(t *testing.T) {
routes := cortexReadRoutes("")
for _, r := range routes {
assert.True(t, strings.HasPrefix(r.Path, "/api/v1/"))
}

routes = cortexReadRoutes("/some/random/prefix///")
for _, r := range routes {
assert.True(t, strings.HasPrefix(r.Path, "/some/random/prefix/api/v1/"))
}
}