This repository has been archived by the owner on Mar 22, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
542 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package web | ||
|
||
import ( | ||
"time" | ||
"runtime" | ||
"fmt" | ||
|
||
"github.com/labstack/echo" | ||
|
||
"github.com/hb-go/echo-web/util/conv" | ||
) | ||
|
||
func DashboardHandler(c echo.Context) error { | ||
updateSystemStatus() | ||
|
||
c.Set("tmpl", "web/dashboard") | ||
c.Set("data", map[string]interface{}{ | ||
"title": "Dashboard", | ||
"SysStatus": sysStatus, | ||
}) | ||
|
||
return nil | ||
} | ||
|
||
var ( | ||
startTime = time.Now() | ||
) | ||
|
||
var sysStatus struct { | ||
Uptime string | ||
NumGoroutine int | ||
|
||
// General statistics. | ||
MemAllocated string // bytes allocated and still in use | ||
MemTotal string // bytes allocated (even if freed) | ||
MemSys string // bytes obtained from system (sum of XxxSys below) | ||
Lookups uint64 // number of pointer lookups | ||
MemMallocs uint64 // number of mallocs | ||
MemFrees uint64 // number of frees | ||
|
||
// Main allocation heap statistics. | ||
HeapAlloc string // bytes allocated and still in use | ||
HeapSys string // bytes obtained from system | ||
HeapIdle string // bytes in idle spans | ||
HeapInuse string // bytes in non-idle span | ||
HeapReleased string // bytes released to the OS | ||
HeapObjects uint64 // total number of allocated objects | ||
|
||
// Low-level fixed-size structure allocator statistics. | ||
// Inuse is bytes used now. | ||
// Sys is bytes obtained from system. | ||
StackInuse string // bootstrap stacks | ||
StackSys string | ||
MSpanInuse string // mspan structures | ||
MSpanSys string | ||
MCacheInuse string // mcache structures | ||
MCacheSys string | ||
BuckHashSys string // profiling bucket hash table | ||
GCSys string // GC metadata | ||
OtherSys string // other system allocations | ||
|
||
// Garbage collector statistics. | ||
NextGC string // next run in HeapAlloc time (bytes) | ||
LastGC string // last run in absolute time (ns) | ||
PauseTotalNs string | ||
PauseNs string // circular buffer of recent GC pause times, most recent at [(NumGC+255)%256] | ||
NumGC uint32 | ||
} | ||
|
||
func updateSystemStatus() { | ||
sysStatus.Uptime = conv.TimeSincePro(startTime) | ||
|
||
m := new(runtime.MemStats) | ||
runtime.ReadMemStats(m) | ||
sysStatus.NumGoroutine = runtime.NumGoroutine() | ||
|
||
sysStatus.MemAllocated = conv.FileSize(int64(m.Alloc)) | ||
sysStatus.MemTotal = conv.FileSize(int64(m.TotalAlloc)) | ||
sysStatus.MemSys = conv.FileSize(int64(m.Sys)) | ||
sysStatus.Lookups = m.Lookups | ||
sysStatus.MemMallocs = m.Mallocs | ||
sysStatus.MemFrees = m.Frees | ||
|
||
sysStatus.HeapAlloc = conv.FileSize(int64(m.HeapAlloc)) | ||
sysStatus.HeapSys = conv.FileSize(int64(m.HeapSys)) | ||
sysStatus.HeapIdle = conv.FileSize(int64(m.HeapIdle)) | ||
sysStatus.HeapInuse = conv.FileSize(int64(m.HeapInuse)) | ||
sysStatus.HeapReleased = conv.FileSize(int64(m.HeapReleased)) | ||
sysStatus.HeapObjects = m.HeapObjects | ||
|
||
sysStatus.StackInuse = conv.FileSize(int64(m.StackInuse)) | ||
sysStatus.StackSys = conv.FileSize(int64(m.StackSys)) | ||
sysStatus.MSpanInuse = conv.FileSize(int64(m.MSpanInuse)) | ||
sysStatus.MSpanSys = conv.FileSize(int64(m.MSpanSys)) | ||
sysStatus.MCacheInuse = conv.FileSize(int64(m.MCacheInuse)) | ||
sysStatus.MCacheSys = conv.FileSize(int64(m.MCacheSys)) | ||
sysStatus.BuckHashSys = conv.FileSize(int64(m.BuckHashSys)) | ||
sysStatus.GCSys = conv.FileSize(int64(m.GCSys)) | ||
sysStatus.OtherSys = conv.FileSize(int64(m.OtherSys)) | ||
|
||
sysStatus.NextGC = conv.FileSize(int64(m.NextGC)) | ||
sysStatus.LastGC = fmt.Sprintf("%.1fs", float64(time.Now().UnixNano()-int64(m.LastGC))/1000/1000/1000) | ||
sysStatus.PauseTotalNs = fmt.Sprintf("%.1fs", float64(m.PauseTotalNs)/1000/1000/1000) | ||
sysStatus.PauseNs = fmt.Sprintf("%.3fs", float64(m.PauseNs[(m.NumGC+255)%256])/1000/1000/1000) | ||
sysStatus.NumGC = m.NumGC | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
{% extends "../base.html" %} | ||
|
||
{% block head_title %} | ||
{{title}} | ||
{% endblock %} | ||
|
||
|
||
{% block head_scripts %} | ||
<script type="text/javascript"> | ||
requirejs(['bootstrap']); | ||
</script> | ||
{% endblock %} | ||
|
||
{% block content %} | ||
<div class="container" style="padding:0px 10px; width:900px;"> | ||
<table class="table table-striped"> | ||
<tr> | ||
<td>服务运行时间</td> | ||
<td>{{SysStatus.Uptime}}</td> | ||
</tr> | ||
<tr> | ||
<td>当前 Goroutines 数量</td> | ||
<td>{{SysStatus.NumGoroutine}}</td> | ||
</tr> | ||
<tr> | ||
<td>当前内存使用量</td> | ||
<td>{{SysStatus.MemAllocated}}</td> | ||
</tr> | ||
<tr> | ||
<td>所有被分配的内存</td> | ||
<td>{{SysStatus.MemTotal}}</td> | ||
</tr> | ||
<tr> | ||
<td>内存占用量</td> | ||
<td>{{SysStatus.MemSys}}</td> | ||
</tr> | ||
<tr> | ||
<td>指针查找次数</td> | ||
<td>{{SysStatus.Lookups}}</td> | ||
</tr> | ||
<tr> | ||
<td>内存分配次数</td> | ||
<td>{{SysStatus.MemMallocs}}</td> | ||
</tr> | ||
<tr> | ||
<td>内存释放次数</td> | ||
<td>{{SysStatus.MemFrees}}</td> | ||
</tr> | ||
<tr> | ||
<td>当前 Heap 内存使用量</td> | ||
<td>{{SysStatus.HeapAlloc}}</td> | ||
</tr> | ||
<tr> | ||
<td>Heap 内存占用量</td> | ||
<td>{{SysStatus.HeapSys}}</td> | ||
</tr> | ||
<tr> | ||
<td>Heap 内存空闲量</td> | ||
<td>{{SysStatus.HeapIdle}}</td> | ||
</tr> | ||
<tr> | ||
<td>正在使用的 Heap 内存</td> | ||
<td>{{SysStatus.HeapInuse}}</td> | ||
</tr> | ||
<tr> | ||
<td>被释放的 Heap 内存</td> | ||
<td>{{SysStatus.HeapReleased}}</td> | ||
</tr> | ||
<tr> | ||
<td>Heap 对象数量</td> | ||
<td>{{SysStatus.HeapObjects}}</td> | ||
</tr> | ||
<tr> | ||
<td>启动 Stack 使用量</td> | ||
<td>{{SysStatus.StackInuse}}</td> | ||
</tr> | ||
<tr> | ||
<td>被分配的 Stack 内存</td> | ||
<td>{{SysStatus.StackSys}}</td> | ||
</tr> | ||
<tr> | ||
<td>MSpan 结构内存使用量</td> | ||
<td>{{SysStatus.MSpanInuse}}</td> | ||
</tr> | ||
<tr> | ||
<td>被分配的 MSpan 结构内存</td> | ||
<td>{{SysStatus.HeapSys}}</td> | ||
</tr> | ||
<tr> | ||
<td>MCache 结构内存使用量</td> | ||
<td>{{SysStatus.MCacheInuse}}</td> | ||
</tr> | ||
<tr> | ||
<td>被分配的 MCache 结构内存</td> | ||
<td>{{SysStatus.MCacheSys}}</td> | ||
</tr> | ||
<tr> | ||
<td>被分配的剖析哈希表内存</td> | ||
<td>{{SysStatus.BuckHashSys}}</td> | ||
</tr> | ||
<tr> | ||
<td>被分配的 GC 元数据内存</td> | ||
<td>{{SysStatus.GCSys}}</td> | ||
</tr> | ||
<tr> | ||
<td>其它被分配的系统内存</td> | ||
<td>{{SysStatus.OtherSys}}</td> | ||
</tr> | ||
<tr> | ||
<td>下次 GC 内存回收量</td> | ||
<td>{{SysStatus.NextGC}}</td> | ||
</tr> | ||
<tr> | ||
<td>距离上次 GC 时间</td> | ||
<td>{{SysStatus.LastGC}}</td> | ||
</tr> | ||
<tr> | ||
<td>GC 执行时间总量</td> | ||
<td>{{SysStatus.PauseTotalNs}}</td> | ||
</tr> | ||
<tr> | ||
<td>GC 暂停时间总量</td> | ||
<td>{{SysStatus.PauseNs}}</td> | ||
</tr> | ||
<tr> | ||
<td>上次 GC 暂停时间</td> | ||
<td>{{SysStatus.NumGC}}</td> | ||
</tr> | ||
</table> | ||
</div> | ||
{% endblock %} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2017 The Gogs Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package conv | ||
|
||
import ( | ||
"fmt" | ||
"math" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
// IsTextFile returns true if file content format is plain text or empty. | ||
func IsTextFile(data []byte) bool { | ||
if len(data) == 0 { | ||
return true | ||
} | ||
return strings.Contains(http.DetectContentType(data), "text/") | ||
} | ||
|
||
func IsImageFile(data []byte) bool { | ||
return strings.Contains(http.DetectContentType(data), "image/") | ||
} | ||
|
||
func IsPDFFile(data []byte) bool { | ||
return strings.Contains(http.DetectContentType(data), "application/pdf") | ||
} | ||
|
||
func IsVideoFile(data []byte) bool { | ||
return strings.Contains(http.DetectContentType(data), "video/") | ||
} | ||
|
||
const ( | ||
Byte = 1 | ||
KByte = Byte * 1024 | ||
MByte = KByte * 1024 | ||
GByte = MByte * 1024 | ||
TByte = GByte * 1024 | ||
PByte = TByte * 1024 | ||
EByte = PByte * 1024 | ||
) | ||
|
||
var bytesSizeTable = map[string]uint64{ | ||
"b": Byte, | ||
"kb": KByte, | ||
"mb": MByte, | ||
"gb": GByte, | ||
"tb": TByte, | ||
"pb": PByte, | ||
"eb": EByte, | ||
} | ||
|
||
func logn(n, b float64) float64 { | ||
return math.Log(n) / math.Log(b) | ||
} | ||
|
||
func humanateBytes(s uint64, base float64, sizes []string) string { | ||
if s < 10 { | ||
return fmt.Sprintf("%d B", s) | ||
} | ||
e := math.Floor(logn(float64(s), base)) | ||
suffix := sizes[int(e)] | ||
val := float64(s) / math.Pow(base, math.Floor(e)) | ||
f := "%.0f" | ||
if val < 10 { | ||
f = "%.1f" | ||
} | ||
|
||
return fmt.Sprintf(f+" %s", val, suffix) | ||
} | ||
|
||
// FileSize calculates the file size and generate user-friendly string. | ||
func FileSize(s int64) string { | ||
sizes := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"} | ||
return humanateBytes(uint64(s), 1024, sizes) | ||
} |
Oops, something went wrong.