package main import ( "context" "flag" "log" "net/http" "net/http/httputil" "net/url" "os" "os/signal" "syscall" "time" ) var ( addr = flag.String("addr", getenv("ADDR", ":3000"), "TCP `addr` to listen on") karmaBackend = flag.String("karma-url", getenv("KARMA_URL", ""), "`URL` for the Karma backend") prometheusBackend = flag.String("prometheus-url", getenv("PROMETHEUS_URL", ""), "`URL` for the Prometheus backend") rootDir = "/var/www" alertBackendURL *url.URL prometheusBackendURL *url.URL ) func getenv(k, dflt string) string { if s := os.Getenv(k); s != "" { return s } return dflt } func main() { log.SetFlags(0) flag.Parse() var err error alertBackendURL, err = url.Parse(*karmaBackend) if err != nil { log.Fatalf("Error parsing --karma-url: %v", err) } prometheusBackendURL, err = url.Parse(*prometheusBackend) if err != nil { log.Fatalf("Error parsing --prometheus-url: %v", err) } // Proxy some specific URLs to certain backends. If we need // more we'll add them. http.Handle("/alerts.json", httputil.NewSingleHostReverseProxy(alertBackendURL)) http.Handle("/api/v1/", httputil.NewSingleHostReverseProxy(prometheusBackendURL)) // Simple static file server for /var/www. http.Handle("/", http.FileServer(http.Dir(rootDir))) srv := &http.Server{ Addr: *addr, ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 600 * time.Second, } sigCh := make(chan os.Signal, 1) go func() { <-sigCh // Gracefully terminate for 3 seconds max, then shut // down remaining clients. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() err := srv.Shutdown(ctx) if err == context.Canceled { err = srv.Close() } if err != nil { log.Printf("error terminating server: %v", err) } }() signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) log.Printf("starting static server on %s", *addr) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("error: %v", err) } }