0
0
mirror of https://github.com/rls-moe/nyx synced 2024-09-28 16:03:47 +02:00
nyx/http/admin/status.go

88 lines
2.4 KiB
Go
Raw Normal View History

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