89 lines
2.1 KiB
Go
89 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
)
|
|
|
|
func proxyTo(host string) *httputil.ReverseProxy {
|
|
rp := httputil.NewSingleHostReverseProxy(&url.URL{
|
|
Scheme: "http",
|
|
Host: host,
|
|
RawQuery: "",
|
|
})
|
|
rp.ModifyResponse = logTimeElapsed
|
|
return rp
|
|
}
|
|
|
|
// todo: this shouldn't be in this repo
|
|
var remotes = map[string]*httputil.ReverseProxy{
|
|
"api.pluralkit.me": proxyTo("[fdaa:0:ae33:a7b:8dd7:0:a:202]:5000"),
|
|
"dash.pluralkit.me": proxyTo("[fdaa:0:ae33:a7b:8dd7:0:a:202]:8080"),
|
|
"sentry.pluralkit.me": proxyTo("[fdaa:0:ae33:a7b:8dd7:0:a:202]:9000"),
|
|
}
|
|
|
|
type ProxyHandler struct{}
|
|
|
|
func (p ProxyHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
|
if r.Header.Get("User-Agent") == "" {
|
|
// please set a valid user-agent
|
|
rw.WriteHeader(403)
|
|
return
|
|
}
|
|
|
|
remote, ok := remotes[r.Host]
|
|
if !ok {
|
|
// unknown domains redirect to landing page
|
|
http.Redirect(rw, r, "https://pluralkit.me", http.StatusFound)
|
|
return
|
|
}
|
|
|
|
startTime := time.Now()
|
|
r = r.WithContext(context.WithValue(r.Context(), "req-time", startTime))
|
|
|
|
remote.ServeHTTP(rw, r)
|
|
}
|
|
|
|
func logTimeElapsed(resp *http.Response) error {
|
|
r := resp.Request
|
|
|
|
startTime := r.Context().Value("req-time").(time.Time)
|
|
|
|
elapsed := time.Since(startTime)
|
|
metric.With(map[string]string{
|
|
"domain": r.Host,
|
|
"method": r.Method,
|
|
"status": strconv.Itoa(resp.StatusCode),
|
|
"route": r.URL.Path,
|
|
}).Observe(elapsed.Seconds())
|
|
|
|
log.Printf("[%s] \"%s %s%s\" %d - %vms %s\n", r.Header.Get("Fly-Client-IP"), r.Method, r.Host, r.URL.Path, resp.StatusCode, elapsed.Milliseconds(), r.Header.Get("User-Agent"))
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
prometheus.MustRegister(metric)
|
|
|
|
http.Handle("/metrics", promhttp.Handler())
|
|
go http.ListenAndServe(":9091", nil)
|
|
|
|
http.ListenAndServe(":8080", ProxyHandler{})
|
|
}
|
|
|
|
var metric = prometheus.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "pk_http_requests",
|
|
Buckets: []float64{.1, .25, 1, 2.5, 5, 20},
|
|
},
|
|
[]string{"domain", "method", "status", "route"},
|
|
)
|