mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
tweaking ui
This commit is contained in:
parent
23012deccf
commit
78bc7b393f
|
@ -58,6 +58,20 @@ func (rrc *RoundRobinCounter) Sum() (sum int64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rrc *RoundRobinCounter) ToList() (ret []int64) {
|
||||||
|
index := rrc.LastIndex
|
||||||
|
step := len(rrc.Values)
|
||||||
|
for step > 0 {
|
||||||
|
step--
|
||||||
|
index++
|
||||||
|
if index >= len(rrc.Values) {
|
||||||
|
index = 0
|
||||||
|
}
|
||||||
|
ret = append(ret, rrc.Values[index])
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type DurationCounter struct {
|
type DurationCounter struct {
|
||||||
MinuteCounter *RoundRobinCounter
|
MinuteCounter *RoundRobinCounter
|
||||||
HourCounter *RoundRobinCounter
|
HourCounter *RoundRobinCounter
|
||||||
|
|
|
@ -243,7 +243,8 @@ func (s *Store) Status() []*VolumeInfo {
|
||||||
FileCount: v.nm.FileCount(),
|
FileCount: v.nm.FileCount(),
|
||||||
DeleteCount: v.nm.DeletedCount(),
|
DeleteCount: v.nm.DeletedCount(),
|
||||||
DeletedByteCount: v.nm.DeletedSize(),
|
DeletedByteCount: v.nm.DeletedSize(),
|
||||||
ReadOnly: v.readOnly}
|
ReadOnly: v.readOnly,
|
||||||
|
Ttl: v.Ttl}
|
||||||
stats = append(stats, s)
|
stats = append(stats, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,19 +60,19 @@ func LoadTTLFromUint32(ttl uint32) (t *TTL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// save stored bytes to an output with 2 bytes
|
// save stored bytes to an output with 2 bytes
|
||||||
func (t TTL) ToBytes(output []byte) {
|
func (t *TTL) ToBytes(output []byte) {
|
||||||
output[0] = t.count
|
output[0] = t.count
|
||||||
output[1] = t.unit
|
output[1] = t.unit
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t TTL) ToUint32() (output uint32) {
|
func (t *TTL) ToUint32() (output uint32) {
|
||||||
output = uint32(t.count) << 8
|
output = uint32(t.count) << 8
|
||||||
output += uint32(t.unit)
|
output += uint32(t.unit)
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t TTL) String() string {
|
func (t *TTL) String() string {
|
||||||
if t.count == 0 {
|
if t == nil || t.count == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if t.unit == Empty {
|
if t.unit == Empty {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/chrislusf/weed-fs/go/glog"
|
"github.com/chrislusf/weed-fs/go/glog"
|
||||||
"github.com/chrislusf/weed-fs/go/operation"
|
"github.com/chrislusf/weed-fs/go/operation"
|
||||||
|
@ -19,6 +20,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var serverStats *stats.ServerStats
|
var serverStats *stats.ServerStats
|
||||||
|
var startTime = time.Now()
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
serverStats = stats.NewServerStats()
|
serverStats = stats.NewServerStats()
|
||||||
|
|
|
@ -60,6 +60,7 @@ func NewMasterServer(r *mux.Router, port int, metaFolder string,
|
||||||
|
|
||||||
ms.guard = security.NewGuard(whiteList, secureKey)
|
ms.guard = security.NewGuard(whiteList, secureKey)
|
||||||
|
|
||||||
|
r.HandleFunc("/", ms.uiStatusHandler)
|
||||||
r.HandleFunc("/ui/index.html", ms.uiStatusHandler)
|
r.HandleFunc("/ui/index.html", ms.uiStatusHandler)
|
||||||
r.HandleFunc("/dir/assign", ms.proxyToLeader(ms.guard.WhiteList(ms.dirAssignHandler)))
|
r.HandleFunc("/dir/assign", ms.proxyToLeader(ms.guard.WhiteList(ms.dirAssignHandler)))
|
||||||
r.HandleFunc("/dir/lookup", ms.proxyToLeader(ms.guard.WhiteList(ms.dirLookupHandler)))
|
r.HandleFunc("/dir/lookup", ms.proxyToLeader(ms.guard.WhiteList(ms.dirLookupHandler)))
|
||||||
|
|
|
@ -3,24 +3,26 @@ package weed_server
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/chrislusf/weed-fs/go/stats"
|
||||||
"github.com/chrislusf/weed-fs/go/util"
|
"github.com/chrislusf/weed-fs/go/util"
|
||||||
ui "github.com/chrislusf/weed-fs/go/weed/weed_server/master_ui"
|
ui "github.com/chrislusf/weed-fs/go/weed/weed_server/master_ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ms *MasterServer) uiStatusHandler(w http.ResponseWriter, r *http.Request) {
|
func (ms *MasterServer) uiStatusHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
stats := make(map[string]interface{})
|
infos := make(map[string]interface{})
|
||||||
stats["Version"] = util.VERSION
|
infos["Version"] = util.VERSION
|
||||||
args := struct {
|
args := struct {
|
||||||
Version string
|
Version string
|
||||||
Topology interface{}
|
Topology interface{}
|
||||||
Peers interface{}
|
Peers interface{}
|
||||||
Stats interface{}
|
Stats interface{}
|
||||||
|
Counters *stats.ServerStats
|
||||||
}{
|
}{
|
||||||
util.VERSION,
|
util.VERSION,
|
||||||
ms.Topo.ToMap(),
|
ms.Topo.ToMap(),
|
||||||
ms.Topo.RaftServer.Peers(),
|
ms.Topo.RaftServer.Peers(),
|
||||||
stats,
|
infos,
|
||||||
//serverStats,
|
serverStats,
|
||||||
}
|
}
|
||||||
ui.StatusTpl.Execute(w, args)
|
ui.StatusTpl.Execute(w, args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,10 @@ var StatusTpl = template.Must(template.New("status").Parse(`<!DOCTYPE html>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<h2>System Stats</h2>
|
<h2>System Stats</h2>
|
||||||
<table class="table table-condensed table-striped">
|
<table class="table table-condensed table-striped">
|
||||||
|
<tr>
|
||||||
|
<th>Concurrent Connections</th>
|
||||||
|
<td>{{ .Counters.Connections.WeekCounter.Count }}</td>
|
||||||
|
</tr>
|
||||||
{{ range $key, $val := .Stats }}
|
{{ range $key, $val := .Stats }}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ $key }}</th>
|
<th>{{ $key }}</th>
|
||||||
|
|
|
@ -3,6 +3,7 @@ package weed_server
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/chrislusf/weed-fs/go/stats"
|
"github.com/chrislusf/weed-fs/go/stats"
|
||||||
"github.com/chrislusf/weed-fs/go/util"
|
"github.com/chrislusf/weed-fs/go/util"
|
||||||
|
@ -11,7 +12,7 @@ import (
|
||||||
|
|
||||||
func (vs *VolumeServer) uiStatusHandler(w http.ResponseWriter, r *http.Request) {
|
func (vs *VolumeServer) uiStatusHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
infos := make(map[string]interface{})
|
infos := make(map[string]interface{})
|
||||||
infos["Version"] = util.VERSION
|
infos["Up Time"] = time.Now().Sub(startTime).String()
|
||||||
var ds []*stats.DiskStatus
|
var ds []*stats.DiskStatus
|
||||||
for _, loc := range vs.store.Locations {
|
for _, loc := range vs.store.Locations {
|
||||||
if dir, e := filepath.Abs(loc.Directory); e == nil {
|
if dir, e := filepath.Abs(loc.Directory); e == nil {
|
||||||
|
@ -24,12 +25,14 @@ func (vs *VolumeServer) uiStatusHandler(w http.ResponseWriter, r *http.Request)
|
||||||
Volumes interface{}
|
Volumes interface{}
|
||||||
DiskStatuses interface{}
|
DiskStatuses interface{}
|
||||||
Stats interface{}
|
Stats interface{}
|
||||||
|
Counters *stats.ServerStats
|
||||||
}{
|
}{
|
||||||
util.VERSION,
|
util.VERSION,
|
||||||
vs.masterNode,
|
vs.masterNode,
|
||||||
vs.store.Status(),
|
vs.store.Status(),
|
||||||
ds,
|
ds,
|
||||||
infos,
|
infos,
|
||||||
|
serverStats,
|
||||||
}
|
}
|
||||||
ui.StatusTpl.Execute(w, args)
|
ui.StatusTpl.Execute(w, args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,48 @@ package master_ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var StatusTpl = template.Must(template.New("status").Parse(`<!DOCTYPE html>
|
func join(data []int64) string {
|
||||||
|
var ret []string
|
||||||
|
for _, d := range data {
|
||||||
|
ret = append(ret, strconv.Itoa(int(d)))
|
||||||
|
}
|
||||||
|
return strings.Join(ret, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
var funcMap = template.FuncMap{
|
||||||
|
"join": join,
|
||||||
|
}
|
||||||
|
|
||||||
|
var StatusTpl = template.Must(template.New("status").Funcs(funcMap).Parse(`<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Seaweed File System {{ .Version }}</title>
|
<title>Seaweed File System {{ .Version }}</title>
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
|
||||||
|
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
|
||||||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function() {
|
||||||
|
var periods = ['second', 'minute', 'hour', 'day'];
|
||||||
|
for (i = 0; i < periods.length; i++) {
|
||||||
|
var period = periods[i];
|
||||||
|
$('.inlinesparkline-'+period).sparkline('html', {
|
||||||
|
type: 'line',
|
||||||
|
barColor: 'red',
|
||||||
|
tooltipSuffix:' request per '+period,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
#jqstooltip{
|
||||||
|
height: 28px !important;
|
||||||
|
width: 150px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -23,7 +58,7 @@ var StatusTpl = template.Must(template.New("status").Parse(`<!DOCTYPE html>
|
||||||
{{ range .DiskStatuses }}
|
{{ range .DiskStatuses }}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ .Dir }}</th>
|
<th>{{ .Dir }}</th>
|
||||||
<td>{{ .Free }}</td>
|
<td>{{ .Free }} Bytes Free</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</table>
|
</table>
|
||||||
|
@ -36,6 +71,22 @@ var StatusTpl = template.Must(template.New("status").Parse(`<!DOCTYPE html>
|
||||||
<th>Master</th>
|
<th>Master</th>
|
||||||
<td><a href="http://{{.Master}}/ui/index.html">{{.Master}}</a></td>
|
<td><a href="http://{{.Master}}/ui/index.html">{{.Master}}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Weekly # ReadRequests</th>
|
||||||
|
<td><span class="inlinesparkline-day">{{ .Counters.ReadRequests.WeekCounter.ToList | join }}</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Daily # ReadRequests</th>
|
||||||
|
<td><span class="inlinesparkline-hour">{{ .Counters.ReadRequests.DayCounter.ToList | join }}</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Hourly # ReadRequests</th>
|
||||||
|
<td><span class="inlinesparkline-minute">{{ .Counters.ReadRequests.HourCounter.ToList | join }}</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Last Minute # ReadRequests</th>
|
||||||
|
<td><span class="inlinesparkline-second">{{ .Counters.ReadRequests.MinuteCounter.ToList | join }}</span></td>
|
||||||
|
</tr>
|
||||||
{{ range $key, $val := .Stats }}
|
{{ range $key, $val := .Stats }}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ $key }}</th>
|
<th>{{ $key }}</th>
|
||||||
|
@ -52,6 +103,7 @@ var StatusTpl = template.Must(template.New("status").Parse(`<!DOCTYPE html>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Id</th>
|
<th>Id</th>
|
||||||
|
<th>Collection</th>
|
||||||
<th>Size</th>
|
<th>Size</th>
|
||||||
<th>Files</th>
|
<th>Files</th>
|
||||||
<th>Trash</th>
|
<th>Trash</th>
|
||||||
|
@ -62,7 +114,8 @@ var StatusTpl = template.Must(template.New("status").Parse(`<!DOCTYPE html>
|
||||||
{{ range .Volumes }}
|
{{ range .Volumes }}
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>{{ .Id }}</code></td>
|
<td><code>{{ .Id }}</code></td>
|
||||||
<td>{{ .Size }}</td>
|
<td>{{ .Collection }}</td>
|
||||||
|
<td>{{ .Size }} Bytes</td>
|
||||||
<td>{{ .FileCount }}</td>
|
<td>{{ .FileCount }}</td>
|
||||||
<td>{{ .DeleteCount }} / {{.DeletedByteCount}} Bytes</td>
|
<td>{{ .DeleteCount }} / {{.DeletedByteCount}} Bytes</td>
|
||||||
<td>{{ .Ttl }}</td>
|
<td>{{ .Ttl }}</td>
|
||||||
|
|
Loading…
Reference in a new issue