9776bb8a by astaxie

improve the admin module

1 parent 969464f8
...@@ -46,7 +46,7 @@ func ProfIndex(rw http.ResponseWriter, r *http.Request) { ...@@ -46,7 +46,7 @@ func ProfIndex(rw http.ResponseWriter, r *http.Request) {
46 r.ParseForm() 46 r.ParseForm()
47 command := r.Form.Get("command") 47 command := r.Form.Get("command")
48 if command != "" { 48 if command != "" {
49 admin.ProcessInput(command) 49 admin.ProcessInput(command, rw)
50 } else { 50 } else {
51 rw.Write([]byte("request url like '/prof?command=lookup goroutine'")) 51 rw.Write([]byte("request url like '/prof?command=lookup goroutine'"))
52 } 52 }
......
...@@ -2,6 +2,7 @@ package admin ...@@ -2,6 +2,7 @@ package admin
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "io"
5 "log" 6 "log"
6 "os" 7 "os"
7 "runtime" 8 "runtime"
...@@ -11,7 +12,6 @@ import ( ...@@ -11,7 +12,6 @@ import (
11 "time" 12 "time"
12 ) 13 )
13 14
14 var heapProfileCounter int32
15 var startTime = time.Now() 15 var startTime = time.Now()
16 var pid int 16 var pid int
17 17
...@@ -19,20 +19,20 @@ func init() { ...@@ -19,20 +19,20 @@ func init() {
19 pid = os.Getpid() 19 pid = os.Getpid()
20 } 20 }
21 21
22 func ProcessInput(input string) { 22 func ProcessInput(input string, w io.Writer) {
23 switch input { 23 switch input {
24 case "lookup goroutine": 24 case "lookup goroutine":
25 p := pprof.Lookup("goroutine") 25 p := pprof.Lookup("goroutine")
26 p.WriteTo(os.Stdout, 2) 26 p.WriteTo(w, 2)
27 case "lookup heap": 27 case "lookup heap":
28 p := pprof.Lookup("heap") 28 p := pprof.Lookup("heap")
29 p.WriteTo(os.Stdout, 2) 29 p.WriteTo(w, 2)
30 case "lookup threadcreate": 30 case "lookup threadcreate":
31 p := pprof.Lookup("threadcreate") 31 p := pprof.Lookup("threadcreate")
32 p.WriteTo(os.Stdout, 2) 32 p.WriteTo(w, 2)
33 case "lookup block": 33 case "lookup block":
34 p := pprof.Lookup("block") 34 p := pprof.Lookup("block")
35 p.WriteTo(os.Stdout, 2) 35 p.WriteTo(w, 2)
36 case "start cpuprof": 36 case "start cpuprof":
37 StartCPUProfile() 37 StartCPUProfile()
38 case "stop cpuprof": 38 case "stop cpuprof":
...@@ -40,7 +40,7 @@ func ProcessInput(input string) { ...@@ -40,7 +40,7 @@ func ProcessInput(input string) {
40 case "get memprof": 40 case "get memprof":
41 MemProf() 41 MemProf()
42 case "gc summary": 42 case "gc summary":
43 PrintGCSummary() 43 PrintGCSummary(w)
44 } 44 }
45 } 45 }
46 46
...@@ -66,16 +66,16 @@ func StopCPUProfile() { ...@@ -66,16 +66,16 @@ func StopCPUProfile() {
66 pprof.StopCPUProfile() 66 pprof.StopCPUProfile()
67 } 67 }
68 68
69 func PrintGCSummary() { 69 func PrintGCSummary(w io.Writer) {
70 memStats := &runtime.MemStats{} 70 memStats := &runtime.MemStats{}
71 runtime.ReadMemStats(memStats) 71 runtime.ReadMemStats(memStats)
72 gcstats := &debug.GCStats{PauseQuantiles: make([]time.Duration, 100)} 72 gcstats := &debug.GCStats{PauseQuantiles: make([]time.Duration, 100)}
73 debug.ReadGCStats(gcstats) 73 debug.ReadGCStats(gcstats)
74 74
75 printGC(memStats, gcstats) 75 printGC(memStats, gcstats, w)
76 } 76 }
77 77
78 func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats) { 78 func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats, w io.Writer) {
79 79
80 if gcstats.NumGC > 0 { 80 if gcstats.NumGC > 0 {
81 lastPause := gcstats.Pause[0] 81 lastPause := gcstats.Pause[0]
...@@ -83,7 +83,7 @@ func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats) { ...@@ -83,7 +83,7 @@ func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats) {
83 overhead := float64(gcstats.PauseTotal) / float64(elapsed) * 100 83 overhead := float64(gcstats.PauseTotal) / float64(elapsed) * 100
84 allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds() 84 allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds()
85 85
86 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", 86 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",
87 gcstats.NumGC, 87 gcstats.NumGC,
88 toS(lastPause), 88 toS(lastPause),
89 toS(avg(gcstats.Pause)), 89 toS(avg(gcstats.Pause)),
...@@ -99,7 +99,7 @@ func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats) { ...@@ -99,7 +99,7 @@ func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats) {
99 elapsed := time.Now().Sub(startTime) 99 elapsed := time.Now().Sub(startTime)
100 allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds() 100 allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds()
101 101
102 fmt.Printf("Alloc:%s Sys:%s Alloc(Rate):%s/s\n", 102 fmt.Fprintf(w, "Alloc:%s Sys:%s Alloc(Rate):%s/s\n",
103 toH(memStats.Alloc), 103 toH(memStats.Alloc),
104 toH(memStats.Sys), 104 toH(memStats.Sys),
105 toH(uint64(allocatedRate))) 105 toH(uint64(allocatedRate)))
......
1 package admin
2
3 import (
4 "os"
5 "testing"
6 )
7
8 func TestProcessInput(t *testing.T) {
9 ProcessInput("lookup goroutine", os.Stdout)
10 ProcessInput("lookup heap", os.Stdout)
11 ProcessInput("lookup threadcreate", os.Stdout)
12 ProcessInput("lookup block", os.Stdout)
13 ProcessInput("gc summary", os.Stdout)
14 }
...@@ -64,11 +64,11 @@ func (m *UrlMap) AddStatistics(requestMethod, requestUrl, requestController stri ...@@ -64,11 +64,11 @@ func (m *UrlMap) AddStatistics(requestMethod, requestUrl, requestController stri
64 func (m *UrlMap) GetMap(rw io.Writer) { 64 func (m *UrlMap) GetMap(rw io.Writer) {
65 m.lock.RLock() 65 m.lock.RLock()
66 defer m.lock.RUnlock() 66 defer m.lock.RUnlock()
67 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)") 67 fmt.Fprintf(rw, "| % -50s| % -10s | % -16s | % -16s | % -16s | % -16s | % -16s |\n", "requestUrl", "method", "times", "used", "max used", "min used", "avg used")
68 for k, v := range m.urlmap { 68 for k, v := range m.urlmap {
69 for kk, vv := range v { 69 for kk, vv := range v {
70 fmt.Fprintf(rw, "| % -30s| % -10s | % -16d | % -16f | % -16f | % -16f | % -16f |\n", k, 70 fmt.Fprintf(rw, "| % -50s| % -10s | % -16d | % -16s | % -16s | % -16s | % -16s |\n", k,
71 kk, vv.RequestNum, vv.TotalTime, vv.MaxTime, vv.MinTime, int64(vv.TotalTime)/vv.RequestNum, 71 kk, vv.RequestNum, toS(vv.TotalTime), toS(vv.MaxTime), toS(vv.MinTime), toS(time.Duration(int64(vv.TotalTime)/vv.RequestNum)),
72 ) 72 )
73 } 73 }
74 } 74 }
......
...@@ -7,12 +7,12 @@ import ( ...@@ -7,12 +7,12 @@ import (
7 ) 7 )
8 8
9 func TestStatics(t *testing.T) { 9 func TestStatics(t *testing.T) {
10 StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(1000000)) 10 StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(2000))
11 StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(1200000)) 11 StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(120000))
12 StatisticsMap.AddStatistics("GET", "/api/user", "&admin.user", time.Duration(1300000)) 12 StatisticsMap.AddStatistics("GET", "/api/user", "&admin.user", time.Duration(13000))
13 StatisticsMap.AddStatistics("POST", "/api/admin", "&admin.user", time.Duration(1400000)) 13 StatisticsMap.AddStatistics("POST", "/api/admin", "&admin.user", time.Duration(14000))
14 StatisticsMap.AddStatistics("POST", "/api/user/astaxie", "&admin.user", time.Duration(1200000)) 14 StatisticsMap.AddStatistics("POST", "/api/user/astaxie", "&admin.user", time.Duration(12000))
15 StatisticsMap.AddStatistics("POST", "/api/user/xiemengjun", "&admin.user", time.Duration(1300000)) 15 StatisticsMap.AddStatistics("POST", "/api/user/xiemengjun", "&admin.user", time.Duration(13000))
16 StatisticsMap.AddStatistics("DELETE", "/api/user", "&admin.user", time.Duration(1400000)) 16 StatisticsMap.AddStatistics("DELETE", "/api/user", "&admin.user", time.Duration(1400))
17 StatisticsMap.GetMap(os.Stdout) 17 StatisticsMap.GetMap(os.Stdout)
18 } 18 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!