From 9776bb8a034b61b7eafc3c5a50b2bf90ede76915 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 15 Nov 2013 21:45:51 +0800 Subject: [PATCH] improve the admin module --- admin.go | 2 +- admin/profile.go | 24 ++++++++++++------------ admin/profile_test.go | 14 ++++++++++++++ admin/statistics.go | 6 +++--- admin/statistics_test.go | 14 +++++++------- 5 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 admin/profile_test.go diff --git a/admin.go b/admin.go index bd61be1a..68779395 100644 --- a/admin.go +++ b/admin.go @@ -46,7 +46,7 @@ func ProfIndex(rw http.ResponseWriter, r *http.Request) { r.ParseForm() command := r.Form.Get("command") if command != "" { - admin.ProcessInput(command) + admin.ProcessInput(command, rw) } else { rw.Write([]byte("request url like '/prof?command=lookup goroutine'")) } diff --git a/admin/profile.go b/admin/profile.go index ec90e8e0..6459c7dc 100644 --- a/admin/profile.go +++ b/admin/profile.go @@ -2,6 +2,7 @@ package admin import ( "fmt" + "io" "log" "os" "runtime" @@ -11,7 +12,6 @@ import ( "time" ) -var heapProfileCounter int32 var startTime = time.Now() var pid int @@ -19,20 +19,20 @@ func init() { pid = os.Getpid() } -func ProcessInput(input string) { +func ProcessInput(input string, w io.Writer) { switch input { case "lookup goroutine": p := pprof.Lookup("goroutine") - p.WriteTo(os.Stdout, 2) + p.WriteTo(w, 2) case "lookup heap": p := pprof.Lookup("heap") - p.WriteTo(os.Stdout, 2) + p.WriteTo(w, 2) case "lookup threadcreate": p := pprof.Lookup("threadcreate") - p.WriteTo(os.Stdout, 2) + p.WriteTo(w, 2) case "lookup block": p := pprof.Lookup("block") - p.WriteTo(os.Stdout, 2) + p.WriteTo(w, 2) case "start cpuprof": StartCPUProfile() case "stop cpuprof": @@ -40,7 +40,7 @@ func ProcessInput(input string) { case "get memprof": MemProf() case "gc summary": - PrintGCSummary() + PrintGCSummary(w) } } @@ -66,16 +66,16 @@ func StopCPUProfile() { pprof.StopCPUProfile() } -func PrintGCSummary() { +func PrintGCSummary(w io.Writer) { memStats := &runtime.MemStats{} runtime.ReadMemStats(memStats) gcstats := &debug.GCStats{PauseQuantiles: make([]time.Duration, 100)} debug.ReadGCStats(gcstats) - printGC(memStats, gcstats) + printGC(memStats, gcstats, w) } -func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats) { +func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats, w io.Writer) { if gcstats.NumGC > 0 { lastPause := gcstats.Pause[0] @@ -83,7 +83,7 @@ func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats) { overhead := float64(gcstats.PauseTotal) / float64(elapsed) * 100 allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds() - fmt.Printf("NumGC:%d Pause:%s Pause(Avg):%s Overhead:%3.2f%% Alloc:%s Sys:%s Alloc(Rate):%s/s Histogram:%s %s %s \n", + fmt.Fprintf(w, "NumGC:%d Pause:%s Pause(Avg):%s Overhead:%3.2f%% Alloc:%s Sys:%s Alloc(Rate):%s/s Histogram:%s %s %s \n", gcstats.NumGC, toS(lastPause), toS(avg(gcstats.Pause)), @@ -99,7 +99,7 @@ func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats) { elapsed := time.Now().Sub(startTime) allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds() - fmt.Printf("Alloc:%s Sys:%s Alloc(Rate):%s/s\n", + fmt.Fprintf(w, "Alloc:%s Sys:%s Alloc(Rate):%s/s\n", toH(memStats.Alloc), toH(memStats.Sys), toH(uint64(allocatedRate))) diff --git a/admin/profile_test.go b/admin/profile_test.go new file mode 100644 index 00000000..4e3373cf --- /dev/null +++ b/admin/profile_test.go @@ -0,0 +1,14 @@ +package admin + +import ( + "os" + "testing" +) + +func TestProcessInput(t *testing.T) { + ProcessInput("lookup goroutine", os.Stdout) + ProcessInput("lookup heap", os.Stdout) + ProcessInput("lookup threadcreate", os.Stdout) + ProcessInput("lookup block", os.Stdout) + ProcessInput("gc summary", os.Stdout) +} diff --git a/admin/statistics.go b/admin/statistics.go index 9a69e1c0..6991803e 100644 --- a/admin/statistics.go +++ b/admin/statistics.go @@ -64,11 +64,11 @@ func (m *UrlMap) AddStatistics(requestMethod, requestUrl, requestController stri func (m *UrlMap) GetMap(rw io.Writer) { m.lock.RLock() defer m.lock.RUnlock() - fmt.Fprintf(rw, "| % -30s| % -10s | % -16s | % -16s | % -16s | % -16s | % -16s |\n", "requestUrl", "method", "times", "used (s)", "avg used (μs)", "max used (μs)", "min used (μs)") + fmt.Fprintf(rw, "| % -50s| % -10s | % -16s | % -16s | % -16s | % -16s | % -16s |\n", "requestUrl", "method", "times", "used", "max used", "min used", "avg used") for k, v := range m.urlmap { for kk, vv := range v { - fmt.Fprintf(rw, "| % -30s| % -10s | % -16d | % -16f | % -16f | % -16f | % -16f |\n", k, - kk, vv.RequestNum, vv.TotalTime, vv.MaxTime, vv.MinTime, int64(vv.TotalTime)/vv.RequestNum, + fmt.Fprintf(rw, "| % -50s| % -10s | % -16d | % -16s | % -16s | % -16s | % -16s |\n", k, + kk, vv.RequestNum, toS(vv.TotalTime), toS(vv.MaxTime), toS(vv.MinTime), toS(time.Duration(int64(vv.TotalTime)/vv.RequestNum)), ) } } diff --git a/admin/statistics_test.go b/admin/statistics_test.go index e5eb6e11..3d7f68a3 100644 --- a/admin/statistics_test.go +++ b/admin/statistics_test.go @@ -7,12 +7,12 @@ import ( ) func TestStatics(t *testing.T) { - StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(1000000)) - StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(1200000)) - StatisticsMap.AddStatistics("GET", "/api/user", "&admin.user", time.Duration(1300000)) - StatisticsMap.AddStatistics("POST", "/api/admin", "&admin.user", time.Duration(1400000)) - StatisticsMap.AddStatistics("POST", "/api/user/astaxie", "&admin.user", time.Duration(1200000)) - StatisticsMap.AddStatistics("POST", "/api/user/xiemengjun", "&admin.user", time.Duration(1300000)) - StatisticsMap.AddStatistics("DELETE", "/api/user", "&admin.user", time.Duration(1400000)) + StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(2000)) + StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(120000)) + StatisticsMap.AddStatistics("GET", "/api/user", "&admin.user", time.Duration(13000)) + StatisticsMap.AddStatistics("POST", "/api/admin", "&admin.user", time.Duration(14000)) + StatisticsMap.AddStatistics("POST", "/api/user/astaxie", "&admin.user", time.Duration(12000)) + StatisticsMap.AddStatistics("POST", "/api/user/xiemengjun", "&admin.user", time.Duration(13000)) + StatisticsMap.AddStatistics("DELETE", "/api/user", "&admin.user", time.Duration(1400)) StatisticsMap.GetMap(os.Stdout) }