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:
Michael Berlin 2016-08-22 00:55:33 -07:00
Родитель 7904a0a1e8
Коммит 71fc83fb3f
6 изменённых файлов: 55 добавлений и 44 удалений

Просмотреть файл

@ -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)