blob: 2ddd5ea1a42965fce117e7657fbf3553d165c566 [file] [log] [blame]
// Copyright 2017 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package rpc
import (
"context"
"html/template"
"net/http"
"sort"
"time"
"go.chromium.org/goma/server/log"
)
func init() {
http.HandleFunc("/debug/backends", func(w http.ResponseWriter, req *http.Request) {
// TODO: auth request as net/trace
w.Header().Set("Content-Type", "text/html; charset=utf=8")
Render(w, req)
})
}
// Render renders backend information.
// It is handled on /debug/backends on default http mux.
func Render(w http.ResponseWriter, req *http.Request) {
type backendInfo struct {
Addr string
Conn bool
NReq int64
NErr int64
Load int
Err error
}
type clientInfo struct {
Target string
Timestamp time.Time
Backends []backendInfo
}
data := struct {
Clients []clientInfo
}{}
clientsMu.Lock()
for _, client := range clients {
client.mu.RLock()
ci := clientInfo{
Target: client.target,
Timestamp: client.timestamp,
}
var addrs []string
for addr := range client.backends {
addrs = append(addrs, addr)
}
sort.Strings(addrs)
for _, addr := range addrs {
b := client.backends[addr]
b.mu.Lock()
bi := backendInfo{
Addr: b.addr,
Conn: b.cc != nil,
NReq: b.nreq,
NErr: b.nerr,
Load: b.load,
Err: b.err,
}
ci.Backends = append(ci.Backends, bi)
b.mu.Unlock()
}
client.mu.RUnlock()
data.Clients = append(data.Clients, ci)
}
clientsMu.Unlock()
err := pageTmpl.ExecuteTemplate(w, "Page", data)
if err != nil {
logger := log.FromContext(context.Background())
logger.Errorf("rpc: Failed executing template: %v", err)
}
}
var pageTmpl = template.Must(template.New("Page").Parse(pageHTML))
const pageHTML = `
{{template "Prolog" .}}
{{template "StatusTable" .}}
{{template "Epilog" .}}
{{define "Prolog"}}
<html>
<head>
<title>/debug/backends</title>
</head>
<body>
<h1>/debug/backends</h1>
{{end}}
{{define "StatusTable"}}
<table border="1">
<tr>
<th>target
<td>timestamp
<td>backends
<td>conn
<td># of reqs
<td># of err
<td>load
<td>err
{{range $c := .Clients}}
<tr>
<td>{{$c.Target}}
<td>{{$c.Timestamp}}
{{range $b := $c.Backends}}
<tr>
<td colspan="2">
<td>{{$b.Addr}}
<td>{{$b.Conn}}
<td>{{$b.NReq}}
<td>{{$b.NErr}}
<td>{{$b.Load}}
<td>{{$b.Err}}
{{end}}
{{end}}
</table>
{{end}}
{{define "Epilog"}}
</body>
</html>
{{end}}
`