forked from mirror/ledisdb
add detailed men and gc info
This commit is contained in:
parent
bfcec916a1
commit
89c58e45ca
|
@ -53,7 +53,11 @@ func newClientRESP(conn net.Conn, app *App) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *respClient) run() {
|
func (c *respClient) run() {
|
||||||
|
c.app.info.addClients(1)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
c.app.info.addClients(-1)
|
||||||
|
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
buf := make([]byte, 4096)
|
buf := make([]byte, 4096)
|
||||||
n := runtime.Stack(buf, false)
|
n := runtime.Stack(buf, false)
|
||||||
|
|
|
@ -6,9 +6,11 @@ import (
|
||||||
"github.com/siddontang/go/sync2"
|
"github.com/siddontang/go/sync2"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type info struct {
|
type info struct {
|
||||||
|
@ -55,11 +57,11 @@ func (i *info) Close() {
|
||||||
|
|
||||||
func getMemoryHuman(m uint64) string {
|
func getMemoryHuman(m uint64) string {
|
||||||
if m > GB {
|
if m > GB {
|
||||||
return fmt.Sprintf("%dG", m/GB)
|
return fmt.Sprintf("%0.3fG", float64(m)/float64(GB))
|
||||||
} else if m > MB {
|
} else if m > MB {
|
||||||
return fmt.Sprintf("%dM", m/MB)
|
return fmt.Sprintf("%0.3fM", float64(m)/float64(MB))
|
||||||
} else if m > KB {
|
} else if m > KB {
|
||||||
return fmt.Sprintf("%dK", m/KB)
|
return fmt.Sprintf("%0.3fK", float64(m)/float64(KB))
|
||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("%d", m)
|
return fmt.Sprintf("%d", m)
|
||||||
}
|
}
|
||||||
|
@ -72,10 +74,10 @@ func (i *info) Dump(section string) []byte {
|
||||||
i.dumpAll(buf)
|
i.dumpAll(buf)
|
||||||
case "server":
|
case "server":
|
||||||
i.dumpServer(buf)
|
i.dumpServer(buf)
|
||||||
case "client":
|
|
||||||
i.dumpClients(buf)
|
|
||||||
case "mem":
|
case "mem":
|
||||||
i.dumpMem(buf)
|
i.dumpMem(buf)
|
||||||
|
case "gc":
|
||||||
|
i.dumpGC(buf)
|
||||||
case "store":
|
case "store":
|
||||||
i.dumpStore(buf)
|
i.dumpStore(buf)
|
||||||
case "replication":
|
case "replication":
|
||||||
|
@ -97,10 +99,10 @@ func (i *info) dumpAll(buf *bytes.Buffer) {
|
||||||
buf.Write(Delims)
|
buf.Write(Delims)
|
||||||
i.dumpStore(buf)
|
i.dumpStore(buf)
|
||||||
buf.Write(Delims)
|
buf.Write(Delims)
|
||||||
i.dumpClients(buf)
|
|
||||||
buf.Write(Delims)
|
|
||||||
i.dumpMem(buf)
|
i.dumpMem(buf)
|
||||||
buf.Write(Delims)
|
buf.Write(Delims)
|
||||||
|
i.dumpGC(buf)
|
||||||
|
buf.Write(Delims)
|
||||||
i.dumpReplication(buf)
|
i.dumpReplication(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,23 +115,55 @@ func (i *info) dumpServer(buf *bytes.Buffer) {
|
||||||
infoPair{"http_addr", i.app.cfg.HttpAddr},
|
infoPair{"http_addr", i.app.cfg.HttpAddr},
|
||||||
infoPair{"readonly", i.app.cfg.Readonly},
|
infoPair{"readonly", i.app.cfg.Readonly},
|
||||||
infoPair{"goroutine_num", runtime.NumGoroutine()},
|
infoPair{"goroutine_num", runtime.NumGoroutine()},
|
||||||
|
infoPair{"cgo_call_num", runtime.NumCgoCall()},
|
||||||
|
infoPair{"client_num", i.Clients.ConnectedClients},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *info) dumpClients(buf *bytes.Buffer) {
|
|
||||||
buf.WriteString("# Client\r\n")
|
|
||||||
|
|
||||||
i.dumpPairs(buf, infoPair{"client_num", i.Clients.ConnectedClients})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *info) dumpMem(buf *bytes.Buffer) {
|
func (i *info) dumpMem(buf *bytes.Buffer) {
|
||||||
buf.WriteString("# Mem\r\n")
|
buf.WriteString("# Mem\r\n")
|
||||||
|
|
||||||
var mem runtime.MemStats
|
var mem runtime.MemStats
|
||||||
runtime.ReadMemStats(&mem)
|
runtime.ReadMemStats(&mem)
|
||||||
|
|
||||||
i.dumpPairs(buf, infoPair{"mem_alloc", mem.Alloc},
|
i.dumpPairs(buf, infoPair{"mem_alloc", getMemoryHuman(mem.Alloc)},
|
||||||
infoPair{"mem_alloc_human", getMemoryHuman(mem.Alloc)})
|
infoPair{"mem_sys", getMemoryHuman(mem.Sys)},
|
||||||
|
infoPair{"mem_looksups", getMemoryHuman(mem.Lookups)},
|
||||||
|
infoPair{"mem_mallocs", getMemoryHuman(mem.Mallocs)},
|
||||||
|
infoPair{"mem_frees", getMemoryHuman(mem.Frees)},
|
||||||
|
infoPair{"mem_total", getMemoryHuman(mem.TotalAlloc)},
|
||||||
|
infoPair{"mem_heap_alloc", getMemoryHuman(mem.HeapAlloc)},
|
||||||
|
infoPair{"mem_heap_sys", getMemoryHuman(mem.HeapSys)},
|
||||||
|
infoPair{"mem_head_idle", getMemoryHuman(mem.HeapIdle)},
|
||||||
|
infoPair{"mem_head_inuse", getMemoryHuman(mem.HeapInuse)},
|
||||||
|
infoPair{"mem_head_released", getMemoryHuman(mem.HeapReleased)},
|
||||||
|
infoPair{"mem_head_objects", mem.HeapObjects},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
gcTimeFormat = "2006/01/02 15:04:05.000"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *info) dumpGC(buf *bytes.Buffer) {
|
||||||
|
count := 5
|
||||||
|
|
||||||
|
var st debug.GCStats
|
||||||
|
st.Pause = make([]time.Duration, count)
|
||||||
|
// st.PauseQuantiles = make([]time.Duration, count)
|
||||||
|
debug.ReadGCStats(&st)
|
||||||
|
|
||||||
|
h := make([]string, 0, count)
|
||||||
|
|
||||||
|
for i := 0; i < count && i < len(st.Pause); i++ {
|
||||||
|
h = append(h, st.Pause[i].String())
|
||||||
|
}
|
||||||
|
|
||||||
|
i.dumpPairs(buf, infoPair{"gc_last_time", st.LastGC.Format(gcTimeFormat)},
|
||||||
|
infoPair{"gc_num", st.NumGC},
|
||||||
|
infoPair{"gc_pause_total", st.PauseTotal.String()},
|
||||||
|
infoPair{"gc_pause_history", strings.Join(h, ",")},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *info) dumpStore(buf *bytes.Buffer) {
|
func (i *info) dumpStore(buf *bytes.Buffer) {
|
||||||
|
|
Loading…
Reference in New Issue