mirror of
https://github.com/rls-moe/nyx
synced 2024-11-14 22:12:24 +00:00
88 lines
2.4 KiB
Go
88 lines
2.4 KiB
Go
|
package admin
|
|||
|
|
|||
|
import (
|
|||
|
"bytes"
|
|||
|
"fmt"
|
|||
|
"github.com/dustin/go-humanize"
|
|||
|
"go.rls.moe/nyx/http/errw"
|
|||
|
"go.rls.moe/nyx/http/middle"
|
|||
|
"net/http"
|
|||
|
"runtime"
|
|||
|
"sync"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
var memStat = map[string]interface{}{}
|
|||
|
var memStatLock = new(sync.RWMutex)
|
|||
|
|
|||
|
var startTime = time.Now().UTC()
|
|||
|
|
|||
|
func init() {
|
|||
|
go func() {
|
|||
|
update()
|
|||
|
ticker := time.Tick(time.Second * 10)
|
|||
|
for _ = range ticker {
|
|||
|
update()
|
|||
|
}
|
|||
|
}()
|
|||
|
}
|
|||
|
|
|||
|
func update() {
|
|||
|
memStatLock.Lock()
|
|||
|
defer memStatLock.Unlock()
|
|||
|
memStat["Uptime"] = uptime()
|
|||
|
memStat["GC"] = gcStat()
|
|||
|
}
|
|||
|
func uptime() map[string]interface{} {
|
|||
|
return map[string]interface{}{
|
|||
|
"human": humanize.Time(startTime),
|
|||
|
"hours": time.Now().Sub(startTime).Hours(),
|
|||
|
"seconds": time.Now().Sub(startTime).Seconds(),
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func gcStat() map[string]interface{} {
|
|||
|
m := &runtime.MemStats{}
|
|||
|
runtime.ReadMemStats(m)
|
|||
|
|
|||
|
mem := map[string]interface{}{}
|
|||
|
mem["alloc"] = fmt.Sprintf("%.5f GiB", float64(m.Alloc)/1024/1024/1024)
|
|||
|
mem["calloc"] = fmt.Sprintf("%.5f GiB", float64(m.TotalAlloc)/1024/1024/1024)
|
|||
|
mem["sysmem"] = fmt.Sprintf("%.5f MiB", float64(m.Sys)/1024/1024)
|
|||
|
mem["lookups"] = fmt.Sprintf("× %d", m.Lookups)
|
|||
|
mem["mallocs"] = fmt.Sprintf("× %d", m.Mallocs)
|
|||
|
mem["frees"] = fmt.Sprintf("× %d", m.Frees)
|
|||
|
mem["liveobj"] = fmt.Sprintf("× %d", m.Mallocs-m.Frees)
|
|||
|
mem["heapalloc"] = fmt.Sprintf("%.5f MiB", float64(m.HeapSys)/1024/1024)
|
|||
|
mem["heaprelease"] = fmt.Sprintf("%.5f MiB", float64(m.HeapReleased)/1024/1024)
|
|||
|
mem["gcmeta"] = fmt.Sprintf("%.5f MiB", float64(m.GCSys)/1024/1024)
|
|||
|
mem["pause"] = fmt.Sprintf("%.5f min", float64(m.PauseTotalNs)/1000/1000/1000/60)
|
|||
|
mem["gctimes"] = fmt.Sprintf("× %d", m.NumGC)
|
|||
|
mem["fgctimes"] = fmt.Sprintf("× %d", m.NumForcedGC)
|
|||
|
mem["cpufrac"] = fmt.Sprintf("%.5f %%", m.GCCPUFraction*100)
|
|||
|
return map[string]interface{}{
|
|||
|
"numcpu": runtime.NumCPU(),
|
|||
|
"numgor": runtime.NumGoroutine(),
|
|||
|
"version": runtime.Version(),
|
|||
|
"arch": runtime.GOARCH,
|
|||
|
"os": runtime.GOOS,
|
|||
|
"compiler": runtime.Compiler,
|
|||
|
"memory": mem,
|
|||
|
}
|
|||
|
}
|
|||
|
func serveStatus(w http.ResponseWriter, r *http.Request) {
|
|||
|
memStatLock.RLock()
|
|||
|
defer memStatLock.RUnlock()
|
|||
|
ctx := middle.GetBaseCtx(r)
|
|||
|
ctx["Uptime"] = memStat["Uptime"]
|
|||
|
ctx["GC"] = memStat["GC"]
|
|||
|
dat := bytes.NewBuffer([]byte{})
|
|||
|
err := statusTmpl.Execute(dat, ctx)
|
|||
|
if err != nil {
|
|||
|
errw.ErrorWriter(err, w, r)
|
|||
|
return
|
|||
|
}
|
|||
|
http.ServeContent(w, r, "panel.html", time.Now(),
|
|||
|
bytes.NewReader(dat.Bytes()))
|
|||
|
}
|