Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
loki/cmd/querytee/main.go

88 lines
3.5 KiB

package main
import (
"flag"
"os"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/weaveworks/common/logging"
"github.com/weaveworks/common/server"
"github.com/grafana/loki/pkg/loghttp"
util_log "github.com/grafana/loki/pkg/util/log"
"github.com/grafana/loki/tools/querytee"
)
type Config struct {
ServerMetricsPort int
LogLevel logging.Level
ProxyConfig querytee.ProxyConfig
}
func main() {
// Parse CLI flags.
cfg := Config{}
flag.IntVar(&cfg.ServerMetricsPort, "server.metrics-port", 9900, "The port where metrics are exposed.")
cfg.LogLevel.RegisterFlags(flag.CommandLine)
cfg.ProxyConfig.RegisterFlags(flag.CommandLine)
flag.Parse()
util_log.InitLogger(&server.Config{
LogLevel: cfg.LogLevel,
}, prometheus.DefaultRegisterer, true, false)
// Run the instrumentation server.
registry := prometheus.NewRegistry()
registry.MustRegister(collectors.NewGoCollector())
i := querytee.NewInstrumentationServer(cfg.ServerMetricsPort, registry)
if err := i.Start(); err != nil {
level.Error(util_log.Logger).Log("msg", "Unable to start instrumentation server", "err", err.Error())
os.Exit(1)
}
// Run the proxy.
proxy, err := querytee.NewProxy(cfg.ProxyConfig, util_log.Logger, lokiReadRoutes(cfg), lokiWriteRoutes(), registry)
if err != nil {
level.Error(util_log.Logger).Log("msg", "Unable to initialize the proxy", "err", err.Error())
os.Exit(1)
}
if err := proxy.Start(); err != nil {
level.Error(util_log.Logger).Log("msg", "Unable to start the proxy", "err", err.Error())
os.Exit(1)
}
proxy.Await()
}
func lokiReadRoutes(cfg Config) []querytee.Route {
samplesComparator := querytee.NewSamplesComparator(querytee.SampleComparisonOptions{
Tolerance: cfg.ProxyConfig.ValueComparisonTolerance,
UseRelativeError: cfg.ProxyConfig.UseRelativeError,
SkipRecentSamples: cfg.ProxyConfig.SkipRecentSamples,
})
samplesComparator.RegisterSamplesType(loghttp.ResultTypeStream, compareStreams)
return []querytee.Route{
{Path: "/loki/api/v1/query_range", RouteName: "api_v1_query_range", Methods: []string{"GET"}, ResponseComparator: samplesComparator},
{Path: "/loki/api/v1/query", RouteName: "api_v1_query", Methods: []string{"GET"}, ResponseComparator: samplesComparator},
{Path: "/loki/api/v1/label", RouteName: "api_v1_label", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/loki/api/v1/labels", RouteName: "api_v1_labels", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/loki/api/v1/label/{name}/values", RouteName: "api_v1_label_name_values", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/loki/api/v1/series", RouteName: "api_v1_series", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/api/prom/query", RouteName: "api_prom_query", Methods: []string{"GET"}, ResponseComparator: samplesComparator},
{Path: "/api/prom/label", RouteName: "api_prom_label", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/api/prom/label/{name}/values", RouteName: "api_prom_label_name_values", Methods: []string{"GET"}, ResponseComparator: nil},
{Path: "/api/prom/series", RouteName: "api_prom_series", Methods: []string{"GET"}, ResponseComparator: nil},
}
}
func lokiWriteRoutes() []querytee.Route {
return []querytee.Route{
{Path: "/loki/api/v1/push", RouteName: "api_v1_push", Methods: []string{"POST"}, ResponseComparator: nil},
{Path: "/api/prom/push", RouteName: "api_prom_push", Methods: []string{"POST"}, ResponseComparator: nil},
}
}