2015-03-20 01:39:22 +08:00
|
|
|
package master_ui
|
|
|
|
|
|
|
|
import (
|
2020-02-24 04:33:47 +08:00
|
|
|
"fmt"
|
2015-03-20 01:39:22 +08:00
|
|
|
"html/template"
|
2015-03-23 03:50:04 +08:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2015-03-20 01:39:22 +08:00
|
|
|
)
|
|
|
|
|
2020-02-24 04:33:47 +08:00
|
|
|
func bytesToHumanReadble(b uint64) string {
|
|
|
|
const unit = 1024
|
|
|
|
if b < unit {
|
|
|
|
return fmt.Sprintf("%d B", b)
|
|
|
|
}
|
|
|
|
div, exp := uint64(unit), 0
|
|
|
|
for n := b / unit; n >= unit; n /= unit {
|
|
|
|
div *= unit
|
|
|
|
exp++
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("%.2f %ciB", float64(b)/float64(div), "KMGTPE"[exp])
|
|
|
|
}
|
|
|
|
|
|
|
|
func percentFrom(total uint64, part_of uint64) string {
|
|
|
|
return fmt.Sprintf("%.2f", (float64(part_of)/float64(total))*100)
|
|
|
|
}
|
|
|
|
|
2015-03-23 03:50:04 +08:00
|
|
|
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{
|
2020-02-24 04:33:47 +08:00
|
|
|
"join": join,
|
|
|
|
"bytesToHumanReadble": bytesToHumanReadble,
|
|
|
|
"percentFrom": percentFrom,
|
2015-03-23 03:50:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
var StatusTpl = template.Must(template.New("status").Funcs(funcMap).Parse(`<!DOCTYPE html>
|
2015-03-20 01:39:22 +08:00
|
|
|
<html>
|
|
|
|
<head>
|
2015-04-17 05:11:25 +08:00
|
|
|
<title>SeaweedFS {{ .Version }}</title>
|
2018-10-08 12:42:57 +08:00
|
|
|
<link rel="stylesheet" href="/seaweedfsstatic/bootstrap/3.3.1/css/bootstrap.min.css">
|
|
|
|
<script type="text/javascript" src="/seaweedfsstatic/javascript/jquery-2.1.3.min.js"></script>
|
|
|
|
<script type="text/javascript" src="/seaweedfsstatic/javascript/jquery-sparklines/2.1.2/jquery.sparkline.min.js"></script>
|
2015-03-23 03:50:04 +08:00
|
|
|
<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>
|
2015-03-20 01:39:22 +08:00
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div class="container">
|
|
|
|
<div class="page-header">
|
2015-04-18 02:26:27 +08:00
|
|
|
<h1>
|
2018-12-28 06:43:36 +08:00
|
|
|
<a href="https://github.com/chrislusf/seaweedfs"><img src="/seaweedfsstatic/seaweed50x50.png"></img></a>
|
2015-04-18 02:26:27 +08:00
|
|
|
SeaweedFS <small>{{ .Version }}</small>
|
|
|
|
</h1>
|
2015-03-20 01:39:22 +08:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-sm-6">
|
|
|
|
<h2>Disk Stats</h2>
|
2020-02-24 04:33:47 +08:00
|
|
|
<table class="table table-striped">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Path</th>
|
|
|
|
<th>Total</th>
|
|
|
|
<th>Free</th>
|
|
|
|
<th>% Usage</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
2015-03-20 01:39:22 +08:00
|
|
|
{{ range .DiskStatuses }}
|
|
|
|
<tr>
|
2020-02-24 04:33:47 +08:00
|
|
|
<td>{{ .Dir }}</td>
|
|
|
|
<td>{{ bytesToHumanReadble .All }}</td>
|
|
|
|
<td>{{ bytesToHumanReadble .Used }}</td>
|
|
|
|
<td>{{ percentFrom .All .Used}}</td>
|
2015-03-20 01:39:22 +08:00
|
|
|
</tr>
|
|
|
|
{{ end }}
|
2020-02-24 04:33:47 +08:00
|
|
|
</tbody>
|
2015-03-20 01:39:22 +08:00
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="col-sm-6">
|
|
|
|
<h2>System Stats</h2>
|
|
|
|
<table class="table table-condensed table-striped">
|
|
|
|
<tr>
|
2018-06-01 15:39:39 +08:00
|
|
|
<th>Masters</th>
|
|
|
|
<td>{{.Masters}}</td>
|
2015-03-20 01:39:22 +08:00
|
|
|
</tr>
|
2015-03-23 03:50:04 +08:00
|
|
|
<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>
|
2015-03-20 01:39:22 +08:00
|
|
|
{{ range $key, $val := .Stats }}
|
|
|
|
<tr>
|
|
|
|
<th>{{ $key }}</th>
|
|
|
|
<td>{{ $val }}</td>
|
|
|
|
</tr>
|
|
|
|
{{ end }}
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="row">
|
|
|
|
<h2>Volumes</h2>
|
|
|
|
<table class="table table-striped">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Id</th>
|
2015-03-23 03:50:04 +08:00
|
|
|
<th>Collection</th>
|
2019-12-25 06:55:26 +08:00
|
|
|
<th>Data Size</th>
|
2015-03-20 01:39:22 +08:00
|
|
|
<th>Files</th>
|
|
|
|
<th>Trash</th>
|
|
|
|
<th>TTL</th>
|
2019-12-25 06:55:26 +08:00
|
|
|
<th>ReadOnly</th>
|
2015-03-20 01:39:22 +08:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{{ range .Volumes }}
|
|
|
|
<tr>
|
|
|
|
<td><code>{{ .Id }}</code></td>
|
2015-03-23 03:50:04 +08:00
|
|
|
<td>{{ .Collection }}</td>
|
|
|
|
<td>{{ .Size }} Bytes</td>
|
2015-03-20 01:39:22 +08:00
|
|
|
<td>{{ .FileCount }}</td>
|
|
|
|
<td>{{ .DeleteCount }} / {{.DeletedByteCount}} Bytes</td>
|
|
|
|
<td>{{ .Ttl }}</td>
|
2019-12-25 06:55:26 +08:00
|
|
|
<td>{{ .ReadOnly }}</td>
|
2015-03-20 01:39:22 +08:00
|
|
|
</tr>
|
|
|
|
{{ end }}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
|
2019-12-03 15:23:54 +08:00
|
|
|
<div class="row">
|
|
|
|
<h2>Remote Volumes</h2>
|
|
|
|
<table class="table table-striped">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Id</th>
|
|
|
|
<th>Collection</th>
|
|
|
|
<th>Size</th>
|
|
|
|
<th>Files</th>
|
|
|
|
<th>Trash</th>
|
|
|
|
<th>Remote</th>
|
|
|
|
<th>Key</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{{ range .RemoteVolumes }}
|
|
|
|
<tr>
|
|
|
|
<td><code>{{ .Id }}</code></td>
|
|
|
|
<td>{{ .Collection }}</td>
|
|
|
|
<td>{{ .Size }} Bytes</td>
|
|
|
|
<td>{{ .FileCount }}</td>
|
|
|
|
<td>{{ .DeleteCount }} / {{.DeletedByteCount}} Bytes</td>
|
|
|
|
<td>{{ .RemoteStorageName }}</td>
|
|
|
|
<td>{{ .RemoteStorageKey }}</td>
|
|
|
|
</tr>
|
|
|
|
{{ end }}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
|
2019-06-05 12:52:37 +08:00
|
|
|
<div class="row">
|
|
|
|
<h2>Erasure Coding Shards</h2>
|
|
|
|
<table class="table table-striped">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Id</th>
|
|
|
|
<th>Collection</th>
|
|
|
|
<th>Shard Size</th>
|
|
|
|
<th>Shards</th>
|
|
|
|
<th>CreatedAt</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{{ range .EcVolumes }}
|
|
|
|
<tr>
|
|
|
|
<td><code>{{ .VolumeId }}</code></td>
|
|
|
|
<td>{{ .Collection }}</td>
|
|
|
|
<td>{{ .ShardSize }} Bytes</td>
|
|
|
|
<td>{{ .ShardIdList }}</td>
|
|
|
|
<td>{{ .CreatedAt.Format "02 Jan 06 15:04 -0700" }}</td>
|
|
|
|
</tr>
|
|
|
|
{{ end }}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
|
2015-03-20 01:39:22 +08:00
|
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
`))
|