mirror of
https://github.com/tailscale/tailscale.git
synced 2025-03-29 12:32:24 +00:00
cmd/microproxy: adjust to export node stats and a Go expvar server's stats.
This is a temporary specialization to what tailscale prod needs right now, it'll go back to something more generic later.
This commit is contained in:
parent
8ca796d144
commit
48d7ee1c6a
@ -9,8 +9,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -29,7 +31,8 @@ var (
|
|||||||
certdir = flag.String("certdir", "", "directory to borrow LetsEncrypt certificates from")
|
certdir = flag.String("certdir", "", "directory to borrow LetsEncrypt certificates from")
|
||||||
hostname = flag.String("hostname", "", "hostname to serve")
|
hostname = flag.String("hostname", "", "hostname to serve")
|
||||||
logCollection = flag.String("logcollection", "", "If non-empty, logtail collection to log to")
|
logCollection = flag.String("logcollection", "", "If non-empty, logtail collection to log to")
|
||||||
target = flag.String("target", "", "URL to proxy to (usually http://localhost:...")
|
nodeExporter = flag.String("node-exporter", "http://localhost:9100", "URL of the local prometheus node exporter")
|
||||||
|
goVarsURL = flag.String("go-vars-url", "http://localhost:8383/debug/vars", "URL of a local Go server's /debug/vars endpoint")
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -39,14 +42,20 @@ func main() {
|
|||||||
logpolicy.New(*logCollection)
|
logpolicy.New(*logCollection)
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := url.Parse(*target)
|
ne, err := url.Parse(*nodeExporter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Couldn't parse URL %q: %v", *target, err)
|
log.Fatalf("Couldn't parse URL %q: %v", *nodeExporter, err)
|
||||||
}
|
}
|
||||||
proxy := httputil.NewSingleHostReverseProxy(u)
|
proxy := httputil.NewSingleHostReverseProxy(ne)
|
||||||
proxy.FlushInterval = time.Second
|
proxy.FlushInterval = time.Second
|
||||||
|
|
||||||
|
if _, err = url.Parse(*goVarsURL); err != nil {
|
||||||
|
log.Fatalf("Couldn't parse URL %q: %v", *goVarsURL, err)
|
||||||
|
}
|
||||||
|
|
||||||
mux := tsweb.NewMux(http.HandlerFunc(debugHandler))
|
mux := tsweb.NewMux(http.HandlerFunc(debugHandler))
|
||||||
mux.Handle("/", tsweb.Protected(proxy))
|
mux.Handle("/metrics", tsweb.Protected(proxy))
|
||||||
|
mux.Handle("/varz", tsweb.Protected(tsweb.StdHandler(&goVarsHandler{*goVarsURL}, log.Printf)))
|
||||||
|
|
||||||
ch := &certHolder{
|
ch := &certHolder{
|
||||||
hostname: *hostname,
|
hostname: *hostname,
|
||||||
@ -66,6 +75,42 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type goVarsHandler struct {
|
||||||
|
url string
|
||||||
|
}
|
||||||
|
|
||||||
|
func promPrint(w io.Writer, prefix string, obj map[string]interface{}) {
|
||||||
|
for k, i := range obj {
|
||||||
|
if prefix != "" {
|
||||||
|
k = prefix + "_" + k
|
||||||
|
}
|
||||||
|
switch v := i.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
promPrint(w, k, v)
|
||||||
|
case float64:
|
||||||
|
fmt.Fprintf(w, "%s %f\n", k, v)
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(w, "# Skipping key %q, unhandled type %T\n", k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *goVarsHandler) ServeHTTPErr(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
resp, err := http.Get(h.url)
|
||||||
|
if err != nil {
|
||||||
|
return tsweb.Error(http.StatusInternalServerError, "fetch failed", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
var mon map[string]interface{}
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&mon); err != nil {
|
||||||
|
return tsweb.Error(http.StatusInternalServerError, "fetch failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
promPrint(w, "", mon)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// certHolder loads and caches a TLS certificate from disk, reloading
|
// certHolder loads and caches a TLS certificate from disk, reloading
|
||||||
// it every hour.
|
// it every hour.
|
||||||
type certHolder struct {
|
type certHolder struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user