Skip to content
Snippets Groups Projects
Commit 2b0e1fd1 authored by ale's avatar ale
Browse files

add debug page for lbv2

parent 292e4e71
Branches
Tags
No related merge requests found
...@@ -316,10 +316,12 @@ func (h *HttpRedirector) createHandler() http.Handler { ...@@ -316,10 +316,12 @@ func (h *HttpRedirector) createHandler() http.Handler {
nil)) nil))
// Pass /debug/ to the default ServeMux, all the default debug // Pass /debug/ to the default ServeMux, all the default debug
// handlers are installed there. // handlers are installed there. Add a debug handler for the
mux.Handle( // LoadBalancer data. Gzip the responses.
"/debug/", debugMux := http.NewServeMux()
handlers.GZIPHandler(http.DefaultServeMux, nil)) debugMux.Handle("/debug/lbv2", h.lb)
debugMux.Handle("/", http.DefaultServeMux)
mux.Handle("/debug/", handlers.GZIPHandler(debugMux, nil))
// Optionally enable a reverse proxy to the local Icecast for // Optionally enable a reverse proxy to the local Icecast for
// the direct stream URLs (below IcecastMountPrefix). // the direct stream URLs (below IcecastMountPrefix).
......
...@@ -2,10 +2,10 @@ package fe ...@@ -2,10 +2,10 @@ package fe
import ( import (
"fmt" "fmt"
"html/template"
"net/http" "net/http"
"sort" "sort"
"sync" "sync"
"text/template"
"time" "time"
) )
......
...@@ -103,6 +103,16 @@ func TestHttpRedirector_Static(t *testing.T) { ...@@ -103,6 +103,16 @@ func TestHttpRedirector_Static(t *testing.T) {
} }
} }
func TestHttpRedirector_LBDebugPage(t *testing.T) {
_, srv := createTestHttpServer(t)
defer srv.Close()
data := doHttpRequest(t, "GET", srv.URL+"/debug/lbv2", 200)
if !strings.Contains(data, "node1") {
t.Errorf("Bad response:\n%s", data)
}
}
type httpTestContext struct { type httpTestContext struct {
srv *httptest.Server srv *httptest.Server
targetSrv *httptest.Server targetSrv *httptest.Server
......
package lbv2
import (
"fmt"
"html/template"
"net/http"
)
const debugText = `<html>
<body>
<title>Load Balancer</title>
<h3>Query costs</h3>
<table>
<tr><th>Node</th><th>Requests</th><th>Utilization/Cost</th></tr>
{{$dimensions := .Dimensions}}
{{range .Nodes}}
<tr>
<td>{{.Name}}</td>
<td>{{.Requests}}</td>
{{range $d := $dimensions}}
{{$data := index .Data $d}}
<td>
{{$data.PredictedUtilization}}/{{$data.ReportedUtilization}}/{{$data.Cost}}
</td>
{{end}}
</tr>
{{end}}
</table>
</body>
</html>`
var debugTmpl = template.Must(template.New("lbv2 debug").Parse(debugText))
type nodeDebugData struct {
Name string
Requests int
Data map[int]costAndUtil
}
type costAndUtil struct {
ReportedUtilization float64
PredictedUtilization float64
Cost float64
}
func (l *LoadBalancer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Build a view of the cost/utilization data.
l.lock.Lock()
var nodes []nodeDebugData
for _, n := range l.nodes {
ndata := nodeDebugData{Name: n.Name(), Data: make(map[int]costAndUtil)}
for dim, pred := range l.predictors {
util := n.Utilization(dim)
ndata.Requests = util.Requests
ndata.Data[dim] = costAndUtil{
ReportedUtilization: util.Utilization,
PredictedUtilization: pred.Utilization(n),
Cost: float64(pred.cost[n.Name()]),
}
}
nodes = append(nodes, ndata)
}
var dimensions []int
for dim := range l.predictors {
dimensions = append(dimensions, dim)
}
l.lock.Unlock()
ctx := struct {
Nodes []nodeDebugData
Dimensions []int
NumDimensions int
}{nodes, dimensions, len(dimensions)}
err := debugTmpl.Execute(w, ctx)
if err != nil {
fmt.Fprintln(w, "debug: error executing template: ", err.Error())
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment