зеркало из https://github.com/github/vitess-gh.git
tabletserver: Move infrastructure for /<table>z pages into an extra package go/vt/logz.
This way, other packages can reuse the code without depending on go/vt/tabletserver. I'll use the new package in go/vt/throttler shortly.
This commit is contained in:
Родитель
7904a0a1e8
Коммит
71fc83fb3f
|
@ -2,16 +2,21 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package tabletserver
|
||||
// Package logz provides an infrastructure to expose a list of entries as
|
||||
// a sortable table on a webpage.
|
||||
//
|
||||
// It is used by many internal vttablet pages e.g. /queryz, /querylogz, /schemaz
|
||||
// /streamqueryz or /txlogz.
|
||||
//
|
||||
// See tabletserver/querylogz.go for an example how to use it.
|
||||
package logz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func startHTMLTable(w http.ResponseWriter) {
|
||||
func StartHTMLTable(w http.ResponseWriter) {
|
||||
w.Write([]byte(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
@ -69,7 +74,7 @@ func startHTMLTable(w http.ResponseWriter) {
|
|||
`))
|
||||
}
|
||||
|
||||
func endHTMLTable(w http.ResponseWriter) {
|
||||
func EndHTMLTable(w http.ResponseWriter) {
|
||||
defer w.Write([]byte(`
|
||||
</table>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
|
||||
|
@ -117,9 +122,9 @@ $(function() {
|
|||
</html>`))
|
||||
}
|
||||
|
||||
// wrappable inserts zero-width whitespaces to make
|
||||
// Wrappable inserts zero-width whitespaces to make
|
||||
// the string wrappable.
|
||||
func wrappable(in string) string {
|
||||
func Wrappable(in string) string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
for _, ch := range in {
|
||||
buf.WriteRune(ch)
|
||||
|
@ -130,28 +135,3 @@ func wrappable(in string) string {
|
|||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func adjustValue(val int, lower int, upper int) int {
|
||||
if val < lower {
|
||||
return lower
|
||||
} else if val > upper {
|
||||
return upper
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func parseTimeoutLimitParams(req *http.Request) (time.Duration, int) {
|
||||
timeout := 10
|
||||
limit := 300
|
||||
if ts, ok := req.URL.Query()["timeout"]; ok {
|
||||
if t, err := strconv.Atoi(ts[0]); err == nil {
|
||||
timeout = adjustValue(t, 0, 60)
|
||||
}
|
||||
}
|
||||
if l, ok := req.URL.Query()["limit"]; ok {
|
||||
if lim, err := strconv.Atoi(l[0]); err == nil {
|
||||
limit = adjustValue(lim, 1, 200000)
|
||||
}
|
||||
}
|
||||
return time.Duration(timeout) * time.Second, limit
|
||||
}
|
|
@ -8,12 +8,14 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
log "github.com/golang/glog"
|
||||
"github.com/youtube/vitess/go/acl"
|
||||
"github.com/youtube/vitess/go/vt/logz"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -42,7 +44,7 @@ var (
|
|||
`)
|
||||
querylogzFuncMap = template.FuncMap{
|
||||
"stampMicro": func(t time.Time) string { return t.Format(time.StampMicro) },
|
||||
"cssWrappable": wrappable,
|
||||
"cssWrappable": logz.Wrappable,
|
||||
"unquote": func(s string) string { return strings.Trim(s, "\"") },
|
||||
}
|
||||
querylogzTmpl = template.Must(template.New("example").Funcs(querylogzFuncMap).Parse(`
|
||||
|
@ -84,8 +86,8 @@ func querylogzHandler(ch chan interface{}, w http.ResponseWriter, r *http.Reques
|
|||
return
|
||||
}
|
||||
timeout, limit := parseTimeoutLimitParams(r)
|
||||
startHTMLTable(w)
|
||||
defer endHTMLTable(w)
|
||||
logz.StartHTMLTable(w)
|
||||
defer logz.EndHTMLTable(w)
|
||||
w.Write(querylogzHeader)
|
||||
|
||||
tmr := time.NewTimer(timeout)
|
||||
|
@ -127,3 +129,28 @@ func querylogzHandler(ch chan interface{}, w http.ResponseWriter, r *http.Reques
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseTimeoutLimitParams(req *http.Request) (time.Duration, int) {
|
||||
timeout := 10
|
||||
limit := 300
|
||||
if ts, ok := req.URL.Query()["timeout"]; ok {
|
||||
if t, err := strconv.Atoi(ts[0]); err == nil {
|
||||
timeout = adjustValue(t, 0, 60)
|
||||
}
|
||||
}
|
||||
if l, ok := req.URL.Query()["limit"]; ok {
|
||||
if lim, err := strconv.Atoi(l[0]); err == nil {
|
||||
limit = adjustValue(lim, 1, 200000)
|
||||
}
|
||||
}
|
||||
return time.Duration(timeout) * time.Second, limit
|
||||
}
|
||||
|
||||
func adjustValue(val int, lower int, upper int) int {
|
||||
if val < lower {
|
||||
return lower
|
||||
} else if val > upper {
|
||||
return upper
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
log "github.com/golang/glog"
|
||||
"github.com/youtube/vitess/go/acl"
|
||||
"github.com/youtube/vitess/go/vt/logz"
|
||||
"github.com/youtube/vitess/go/vt/tabletserver/planbuilder"
|
||||
)
|
||||
|
||||
|
@ -119,8 +120,8 @@ func queryzHandler(si *SchemaInfo, w http.ResponseWriter, r *http.Request) {
|
|||
acl.SendError(w, err)
|
||||
return
|
||||
}
|
||||
startHTMLTable(w)
|
||||
defer endHTMLTable(w)
|
||||
logz.StartHTMLTable(w)
|
||||
defer logz.EndHTMLTable(w)
|
||||
w.Write(queryzHeader)
|
||||
|
||||
keys := si.queries.Keys()
|
||||
|
@ -136,7 +137,7 @@ func queryzHandler(si *SchemaInfo, w http.ResponseWriter, r *http.Request) {
|
|||
continue
|
||||
}
|
||||
Value := &queryzRow{
|
||||
Query: wrappable(v),
|
||||
Query: logz.Wrappable(v),
|
||||
Table: plan.TableName,
|
||||
Plan: plan.PlanID,
|
||||
Reason: plan.Reason,
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
log "github.com/golang/glog"
|
||||
"github.com/youtube/vitess/go/acl"
|
||||
"github.com/youtube/vitess/go/vt/logz"
|
||||
"github.com/youtube/vitess/go/vt/schema"
|
||||
)
|
||||
|
||||
|
@ -65,8 +66,8 @@ func schemazHandler(tables []*schema.Table, w http.ResponseWriter, r *http.Reque
|
|||
acl.SendError(w, err)
|
||||
return
|
||||
}
|
||||
startHTMLTable(w)
|
||||
defer endHTMLTable(w)
|
||||
logz.StartHTMLTable(w)
|
||||
defer logz.EndHTMLTable(w)
|
||||
w.Write(schemazHeader)
|
||||
|
||||
sorter := schemazSorter{
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
log "github.com/golang/glog"
|
||||
"github.com/youtube/vitess/go/acl"
|
||||
"github.com/youtube/vitess/go/vt/logz"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -60,8 +61,8 @@ func streamQueryzHandler(queryList *QueryList, w http.ResponseWriter, r *http.Re
|
|||
w.Write(js)
|
||||
return
|
||||
}
|
||||
startHTMLTable(w)
|
||||
defer endHTMLTable(w)
|
||||
logz.StartHTMLTable(w)
|
||||
defer logz.EndHTMLTable(w)
|
||||
w.Write(streamqueryzHeader)
|
||||
for i := range rows {
|
||||
if err := streamqueryzTmpl.Execute(w, rows[i]); err != nil {
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
log "github.com/golang/glog"
|
||||
"github.com/youtube/vitess/go/acl"
|
||||
"github.com/youtube/vitess/go/vt/callerid"
|
||||
"github.com/youtube/vitess/go/vt/logz"
|
||||
|
||||
querypb "github.com/youtube/vitess/go/vt/proto/query"
|
||||
vtrpcpb "github.com/youtube/vitess/go/vt/proto/vtrpc"
|
||||
|
@ -74,8 +75,8 @@ func txlogzHandler(w http.ResponseWriter, req *http.Request) {
|
|||
timeout, limit := parseTimeoutLimitParams(req)
|
||||
ch := TxLogger.Subscribe("txlogz")
|
||||
defer TxLogger.Unsubscribe(ch)
|
||||
startHTMLTable(w)
|
||||
defer endHTMLTable(w)
|
||||
logz.StartHTMLTable(w)
|
||||
defer logz.EndHTMLTable(w)
|
||||
w.Write(txlogzHeader)
|
||||
|
||||
tmr := time.NewTimer(timeout)
|
||||
|
|
Загрузка…
Ссылка в новой задаче