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()))
|
||
}
|