github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/cmd/query-tee/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"os"
     6  
     7  	"github.com/go-kit/log/level"
     8  	"github.com/prometheus/client_golang/prometheus"
     9  	"github.com/prometheus/client_golang/prometheus/collectors"
    10  	"github.com/weaveworks/common/logging"
    11  	"github.com/weaveworks/common/server"
    12  
    13  	util_log "github.com/cortexproject/cortex/pkg/util/log"
    14  	"github.com/cortexproject/cortex/tools/querytee"
    15  )
    16  
    17  type Config struct {
    18  	ServerMetricsPort int
    19  	LogLevel          logging.Level
    20  	ProxyConfig       querytee.ProxyConfig
    21  	PathPrefix        string
    22  }
    23  
    24  func main() {
    25  	// Parse CLI flags.
    26  	cfg := Config{}
    27  	flag.IntVar(&cfg.ServerMetricsPort, "server.metrics-port", 9900, "The port where metrics are exposed.")
    28  	flag.StringVar(&cfg.PathPrefix, "server.path-prefix", "", "Prefix for API paths (query-tee will accept Prometheus API calls at <prefix>/api/v1/...)")
    29  	cfg.LogLevel.RegisterFlags(flag.CommandLine)
    30  	cfg.ProxyConfig.RegisterFlags(flag.CommandLine)
    31  	flag.Parse()
    32  
    33  	util_log.InitLogger(&server.Config{
    34  		LogLevel: cfg.LogLevel,
    35  	})
    36  
    37  	// Run the instrumentation server.
    38  	registry := prometheus.NewRegistry()
    39  	registry.MustRegister(collectors.NewGoCollector())
    40  
    41  	i := querytee.NewInstrumentationServer(cfg.ServerMetricsPort, registry)
    42  	if err := i.Start(); err != nil {
    43  		level.Error(util_log.Logger).Log("msg", "Unable to start instrumentation server", "err", err.Error())
    44  		os.Exit(1)
    45  	}
    46  
    47  	// Run the proxy.
    48  	proxy, err := querytee.NewProxy(cfg.ProxyConfig, util_log.Logger, cortexReadRoutes(cfg), registry)
    49  	if err != nil {
    50  		level.Error(util_log.Logger).Log("msg", "Unable to initialize the proxy", "err", err.Error())
    51  		os.Exit(1)
    52  	}
    53  
    54  	if err := proxy.Start(); err != nil {
    55  		level.Error(util_log.Logger).Log("msg", "Unable to start the proxy", "err", err.Error())
    56  		os.Exit(1)
    57  	}
    58  
    59  	proxy.Await()
    60  }
    61  
    62  func cortexReadRoutes(cfg Config) []querytee.Route {
    63  	prefix := cfg.PathPrefix
    64  
    65  	// Strip trailing slashes.
    66  	for len(prefix) > 0 && prefix[len(prefix)-1] == '/' {
    67  		prefix = prefix[:len(prefix)-1]
    68  	}
    69  
    70  	samplesComparator := querytee.NewSamplesComparator(cfg.ProxyConfig.ValueComparisonTolerance)
    71  	return []querytee.Route{
    72  		{Path: prefix + "/api/v1/query", RouteName: "api_v1_query", Methods: []string{"GET"}, ResponseComparator: samplesComparator},
    73  		{Path: prefix + "/api/v1/query_range", RouteName: "api_v1_query_range", Methods: []string{"GET"}, ResponseComparator: samplesComparator},
    74  		{Path: prefix + "/api/v1/labels", RouteName: "api_v1_labels", Methods: []string{"GET"}, ResponseComparator: nil},
    75  		{Path: prefix + "/api/v1/label/{name}/values", RouteName: "api_v1_label_name_values", Methods: []string{"GET"}, ResponseComparator: nil},
    76  		{Path: prefix + "/api/v1/series", RouteName: "api_v1_series", Methods: []string{"GET"}, ResponseComparator: nil},
    77  		{Path: prefix + "/api/v1/metadata", RouteName: "api_v1_metadata", Methods: []string{"GET"}, ResponseComparator: nil},
    78  		{Path: prefix + "/api/v1/rules", RouteName: "api_v1_rules", Methods: []string{"GET"}, ResponseComparator: nil},
    79  		{Path: prefix + "/api/v1/alerts", RouteName: "api_v1_alerts", Methods: []string{"GET"}, ResponseComparator: nil},
    80  	}
    81  }