in cmd/frontend/main.go [78:229]
func main() {
flag.Parse()
logger := log.NewJSONLogger(log.NewSyncWriter(os.Stderr))
logger = log.With(logger, "ts", log.DefaultTimestampUTC)
logger = log.With(logger, "caller", log.DefaultCaller)
if !fips140.Enabled() {
_ = logger.Log("msg", "FIPS mode not enabled")
os.Exit(1)
}
switch strings.ToLower(*logLevel) {
case "debug":
logger = level.NewFilter(logger, level.AllowDebug())
case "warn":
logger = level.NewFilter(logger, level.AllowWarn())
case "error":
logger = level.NewFilter(logger, level.AllowError())
case "info":
logger = level.NewFilter(logger, level.AllowInfo())
default:
//nolint:errcheck
level.Error(logger).Log("msg",
"--log.level can only be one of 'debug', 'info', 'warn', 'error'")
os.Exit(1)
}
metrics := prometheus.NewRegistry()
metrics.MustRegister(
collectors.NewGoCollector(),
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
)
if *projectID == "" {
//nolint:errcheck
level.Error(logger).Log("msg", "--query.project-id must be set")
os.Exit(1)
}
targetURL, err := url.Parse(strings.ReplaceAll(*targetURLStr, projectIDVar, *projectID))
if err != nil {
//nolint:errcheck
level.Error(logger).Log("msg", "parsing target URL failed", "err", err)
os.Exit(1)
}
externalURL, err := url.Parse(*externalURLStr)
if err != nil {
//nolint:errcheck
level.Error(logger).Log("msg", "parsing external URL failed", "err", err)
os.Exit(1)
}
var ruleEndpointURLs []url.URL
for _, ruleEndpointURLStr := range strings.Split(*ruleEndpointURLStrings, ",") {
ruleEndpointURL, err := url.Parse(strings.TrimSpace(ruleEndpointURLStr))
if err != nil || ruleEndpointURL == nil {
_ = level.Error(logger).Log("msg", "parsing rule endpoint URL failed", "err", err, "url", strings.TrimSpace(ruleEndpointURLStr))
os.Exit(1)
}
ruleEndpointURLs = append(ruleEndpointURLs, *ruleEndpointURL)
}
version, err := export.Version()
if err != nil {
_ = level.Error(logger).Log("msg", "Unable to fetch module version", "err", err)
os.Exit(1)
}
var g run.Group
{
term := make(chan os.Signal, 1)
cancel := make(chan struct{})
signal.Notify(term, os.Interrupt, syscall.SIGTERM)
g.Add(
func() error {
select {
case <-term:
//nolint:errcheck
level.Info(logger).Log("msg", "received SIGTERM, exiting gracefully...")
case <-cancel:
}
return nil
},
func(error) {
close(cancel)
},
)
}
{
opts := []option.ClientOption{
option.WithScopes("https://www.googleapis.com/auth/monitoring.read"),
option.WithCredentialsFile(*credentialsFile),
}
ctx, cancel := context.WithCancel(context.Background())
transport, err := apihttp.NewTransport(ctx, http.DefaultTransport, opts...)
if err != nil {
//nolint:errcheck
level.Error(logger).Log("msg", "create proxy HTTP transport", "err", err)
os.Exit(1)
}
ruleProxy := rule.NewProxy(
log.With(logger, "component", "rule-proxy"),
&http.Client{Timeout: 30 * time.Second},
ruleEndpointURLs,
)
server := &http.Server{Addr: *listenAddress}
buildInfoHandler := http.HandlerFunc(promapi.BuildinfoHandlerFunc(log.With(logger, "component", "buildinfo-handler"), "frontend", version))
http.Handle("/api/v1/status/buildinfo", buildInfoHandler)
http.Handle("/metrics", promhttp.HandlerFor(metrics, promhttp.HandlerOpts{Registry: metrics}))
http.Handle("/api/v1/rules", http.HandlerFunc(ruleProxy.RuleGroups))
http.Handle("/api/v1/rules/", http.NotFoundHandler())
http.Handle("/api/v1/alerts", http.HandlerFunc(ruleProxy.Alerts))
http.Handle("/api/", authenticate(forward(logger, targetURL, transport)))
http.HandleFunc("/-/healthy", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "Prometheus frontend is Healthy.\n")
})
http.HandleFunc("/-/ready", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "Prometheus frontend is Ready.\n")
})
http.Handle("/", authenticate(ui.Handler(externalURL)))
g.Add(func() error {
//nolint:errcheck
level.Info(logger).Log("msg", "Starting web server for metrics", "listen", *listenAddress)
return server.ListenAndServe()
}, func(error) {
//nolint:fatcontext //TODO review this linter error
ctx, cancel = context.WithTimeout(ctx, time.Minute)
if err := server.Shutdown(ctx); err != nil {
//nolint:errcheck
level.Error(logger).Log("msg", "Server failed to shut down gracefully")
}
cancel()
})
}
if err := g.Run(); err != nil {
//nolint:errcheck
level.Error(logger).Log("msg", "running reloader failed", "err", err)
os.Exit(1)
}
}