github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/cmd/querytee/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 "github.com/grafana/loki/pkg/loghttp" 14 util_log "github.com/grafana/loki/pkg/util/log" 15 "github.com/grafana/loki/tools/querytee" 16 ) 17 18 type Config struct { 19 ServerMetricsPort int 20 LogLevel logging.Level 21 ProxyConfig querytee.ProxyConfig 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 cfg.LogLevel.RegisterFlags(flag.CommandLine) 29 cfg.ProxyConfig.RegisterFlags(flag.CommandLine) 30 flag.Parse() 31 32 util_log.InitLogger(&server.Config{ 33 LogLevel: cfg.LogLevel, 34 }, prometheus.DefaultRegisterer) 35 36 // Run the instrumentation server. 37 registry := prometheus.NewRegistry() 38 registry.MustRegister(collectors.NewGoCollector()) 39 40 i := querytee.NewInstrumentationServer(cfg.ServerMetricsPort, registry) 41 if err := i.Start(); err != nil { 42 level.Error(util_log.Logger).Log("msg", "Unable to start instrumentation server", "err", err.Error()) 43 os.Exit(1) 44 } 45 46 // Run the proxy. 47 proxy, err := querytee.NewProxy(cfg.ProxyConfig, util_log.Logger, lokiReadRoutes(cfg), lokiWriteRoutes(), registry) 48 if err != nil { 49 level.Error(util_log.Logger).Log("msg", "Unable to initialize the proxy", "err", err.Error()) 50 os.Exit(1) 51 } 52 53 if err := proxy.Start(); err != nil { 54 level.Error(util_log.Logger).Log("msg", "Unable to start the proxy", "err", err.Error()) 55 os.Exit(1) 56 } 57 58 proxy.Await() 59 } 60 61 func lokiReadRoutes(cfg Config) []querytee.Route { 62 samplesComparator := querytee.NewSamplesComparator(querytee.SampleComparisonOptions{ 63 Tolerance: cfg.ProxyConfig.ValueComparisonTolerance, 64 UseRelativeError: cfg.ProxyConfig.UseRelativeError, 65 SkipRecentSamples: cfg.ProxyConfig.SkipRecentSamples, 66 }) 67 samplesComparator.RegisterSamplesType(loghttp.ResultTypeStream, compareStreams) 68 69 return []querytee.Route{ 70 {Path: "/loki/api/v1/query_range", RouteName: "api_v1_query_range", Methods: []string{"GET"}, ResponseComparator: samplesComparator}, 71 {Path: "/loki/api/v1/query", RouteName: "api_v1_query", Methods: []string{"GET"}, ResponseComparator: samplesComparator}, 72 {Path: "/loki/api/v1/label", RouteName: "api_v1_label", Methods: []string{"GET"}, ResponseComparator: nil}, 73 {Path: "/loki/api/v1/labels", RouteName: "api_v1_labels", Methods: []string{"GET"}, ResponseComparator: nil}, 74 {Path: "/loki/api/v1/label/{name}/values", RouteName: "api_v1_label_name_values", Methods: []string{"GET"}, ResponseComparator: nil}, 75 {Path: "/loki/api/v1/series", RouteName: "api_v1_series", Methods: []string{"GET"}, ResponseComparator: nil}, 76 {Path: "/api/prom/query", RouteName: "api_prom_query", Methods: []string{"GET"}, ResponseComparator: samplesComparator}, 77 {Path: "/api/prom/label", RouteName: "api_prom_label", Methods: []string{"GET"}, ResponseComparator: nil}, 78 {Path: "/api/prom/label/{name}/values", RouteName: "api_prom_label_name_values", Methods: []string{"GET"}, ResponseComparator: nil}, 79 {Path: "/api/prom/series", RouteName: "api_prom_series", Methods: []string{"GET"}, ResponseComparator: nil}, 80 } 81 } 82 83 func lokiWriteRoutes() []querytee.Route { 84 return []querytee.Route{ 85 {Path: "/loki/api/v1/push", RouteName: "api_v1_push", Methods: []string{"POST"}, ResponseComparator: nil}, 86 {Path: "/api/prom/push", RouteName: "api_prom_push", Methods: []string{"POST"}, ResponseComparator: nil}, 87 } 88 }