Skip to content
Snippets Groups Projects
server.go 2.03 KiB
Newer Older
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")
ale's avatar
ale committed
	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)
	}
}