diff --git a/admin.go b/admin.go
index fa9ef3b3..93b1894d 100644
--- a/admin.go
+++ b/admin.go
@@ -1,18 +1,15 @@
// Beego (http://beego.me/)
-//
// @description beego is an open-source, high-performance web framework for the Go programming language.
-//
// @link http://github.com/astaxie/beego for the canonical source repository
-//
// @license http://github.com/astaxie/beego/blob/master/LICENSE
-//
// @authors astaxie
package beego
import (
+ "bytes"
"fmt"
"net/http"
- "strconv"
+ "text/template"
"time"
"github.com/astaxie/beego/toolbox"
@@ -49,7 +46,6 @@ func init() {
beeAdminApp.Route("/prof", profIndex)
beeAdminApp.Route("/healthcheck", healthcheck)
beeAdminApp.Route("/task", taskStatus)
- beeAdminApp.Route("/runtask", runTask)
beeAdminApp.Route("/listconf", listConf)
FilterMonitorFunc = func(string, string, time.Duration) bool { return true }
}
@@ -57,22 +53,22 @@ func init() {
// AdminIndex is the default http.Handler for admin module.
// it matches url pattern "/".
func adminIndex(rw http.ResponseWriter, r *http.Request) {
- rw.Write([]byte("
beego admin dashboard"))
- rw.Write([]byte("Welcome to Admin Dashboard
\n"))
- rw.Write([]byte("There are servral functions:
\n"))
- rw.Write([]byte("1. Record all request and request time, http://localhost:" + strconv.Itoa(AdminHttpPort) + "/qps
\n"))
- rw.Write([]byte("2. Get runtime profiling data by the pprof, http://localhost:" + strconv.Itoa(AdminHttpPort) + "/prof
\n"))
- rw.Write([]byte("3. Get healthcheck result from http://localhost:" + strconv.Itoa(AdminHttpPort) + "/healthcheck
\n"))
- rw.Write([]byte("4. Get current task infomation from task http://localhost:" + strconv.Itoa(AdminHttpPort) + "/task
\n"))
- rw.Write([]byte("5. To run a task passed a param http://localhost:" + strconv.Itoa(AdminHttpPort) + "/runtask
\n"))
- rw.Write([]byte("6. Get all confige & router infomation http://localhost:" + strconv.Itoa(AdminHttpPort) + "/listconf
\n"))
- rw.Write([]byte(""))
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ tmpl = template.Must(tmpl.Parse(indexTpl))
+ data := make(map[interface{}]interface{})
+ tmpl.Execute(rw, data)
}
// QpsIndex is the http.Handler for writing qbs statistics map result info in http.ResponseWriter.
// it's registered with url pattern "/qbs" in admin module.
func qpsIndex(rw http.ResponseWriter, r *http.Request) {
- toolbox.StatisticsMap.GetMap(rw)
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ tmpl = template.Must(tmpl.Parse(qpsTpl))
+ data := make(map[interface{}]interface{})
+ data["Content"] = toolbox.StatisticsMap.GetMap()
+
+ tmpl.Execute(rw, data)
+
}
// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
@@ -81,112 +77,217 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
r.ParseForm()
command := r.Form.Get("command")
if command != "" {
+ data := make(map[interface{}]interface{})
switch command {
case "conf":
- fmt.Fprintln(rw, "list all beego's conf:")
- fmt.Fprintln(rw, "AppName:", AppName)
- fmt.Fprintln(rw, "AppPath:", AppPath)
- fmt.Fprintln(rw, "AppConfigPath:", AppConfigPath)
- fmt.Fprintln(rw, "StaticDir:", StaticDir)
- fmt.Fprintln(rw, "StaticExtensionsToGzip:", StaticExtensionsToGzip)
- fmt.Fprintln(rw, "HttpAddr:", HttpAddr)
- fmt.Fprintln(rw, "HttpPort:", HttpPort)
- fmt.Fprintln(rw, "HttpTLS:", EnableHttpTLS)
- fmt.Fprintln(rw, "HttpCertFile:", HttpCertFile)
- fmt.Fprintln(rw, "HttpKeyFile:", HttpKeyFile)
- fmt.Fprintln(rw, "RecoverPanic:", RecoverPanic)
- fmt.Fprintln(rw, "AutoRender:", AutoRender)
- fmt.Fprintln(rw, "ViewsPath:", ViewsPath)
- fmt.Fprintln(rw, "RunMode:", RunMode)
- fmt.Fprintln(rw, "SessionOn:", SessionOn)
- fmt.Fprintln(rw, "SessionProvider:", SessionProvider)
- fmt.Fprintln(rw, "SessionName:", SessionName)
- fmt.Fprintln(rw, "SessionGCMaxLifetime:", SessionGCMaxLifetime)
- fmt.Fprintln(rw, "SessionSavePath:", SessionSavePath)
- fmt.Fprintln(rw, "SessionHashFunc:", SessionHashFunc)
- fmt.Fprintln(rw, "SessionHashKey:", SessionHashKey)
- fmt.Fprintln(rw, "SessionCookieLifeTime:", SessionCookieLifeTime)
- fmt.Fprintln(rw, "UseFcgi:", UseFcgi)
- fmt.Fprintln(rw, "MaxMemory:", MaxMemory)
- fmt.Fprintln(rw, "EnableGzip:", EnableGzip)
- fmt.Fprintln(rw, "DirectoryIndex:", DirectoryIndex)
- fmt.Fprintln(rw, "HttpServerTimeOut:", HttpServerTimeOut)
- fmt.Fprintln(rw, "ErrorsShow:", ErrorsShow)
- fmt.Fprintln(rw, "XSRFKEY:", XSRFKEY)
- fmt.Fprintln(rw, "EnableXSRF:", EnableXSRF)
- fmt.Fprintln(rw, "XSRFExpire:", XSRFExpire)
- fmt.Fprintln(rw, "CopyRequestBody:", CopyRequestBody)
- fmt.Fprintln(rw, "TemplateLeft:", TemplateLeft)
- fmt.Fprintln(rw, "TemplateRight:", TemplateRight)
- fmt.Fprintln(rw, "BeegoServerName:", BeegoServerName)
- fmt.Fprintln(rw, "EnableAdmin:", EnableAdmin)
- fmt.Fprintln(rw, "AdminHttpAddr:", AdminHttpAddr)
- fmt.Fprintln(rw, "AdminHttpPort:", AdminHttpPort)
+ m := make(map[string]interface{})
+
+ m["AppName"] = AppName
+ m["AppPath"] = AppPath
+ m["AppConfigPath"] = AppConfigPath
+ m["StaticDir"] = StaticDir
+ m["StaticExtensionsToGzip"] = StaticExtensionsToGzip
+ m["HttpAddr"] = HttpAddr
+ m["HttpPort"] = HttpPort
+ m["HttpTLS"] = EnableHttpTLS
+ m["HttpCertFile"] = HttpCertFile
+ m["HttpKeyFile"] = HttpKeyFile
+ m["RecoverPanic"] = RecoverPanic
+ m["AutoRender"] = AutoRender
+ m["ViewsPath"] = ViewsPath
+ m["RunMode"] = RunMode
+ m["SessionOn"] = SessionOn
+ m["SessionProvider"] = SessionProvider
+ m["SessionName"] = SessionName
+ m["SessionGCMaxLifetime"] = SessionGCMaxLifetime
+ m["SessionSavePath"] = SessionSavePath
+ m["SessionHashFunc"] = SessionHashFunc
+ m["SessionHashKey"] = SessionHashKey
+ m["SessionCookieLifeTime"] = SessionCookieLifeTime
+ m["UseFcgi"] = UseFcgi
+ m["MaxMemory"] = MaxMemory
+ m["EnableGzip"] = EnableGzip
+ m["DirectoryIndex"] = DirectoryIndex
+ m["HttpServerTimeOut"] = HttpServerTimeOut
+ m["ErrorsShow"] = ErrorsShow
+ m["XSRFKEY"] = XSRFKEY
+ m["EnableXSRF"] = EnableXSRF
+ m["XSRFExpire"] = XSRFExpire
+ m["CopyRequestBody"] = CopyRequestBody
+ m["TemplateLeft"] = TemplateLeft
+ m["TemplateRight"] = TemplateRight
+ m["BeegoServerName"] = BeegoServerName
+ m["EnableAdmin"] = EnableAdmin
+ m["AdminHttpAddr"] = AdminHttpAddr
+ m["AdminHttpPort"] = AdminHttpPort
+
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ tmpl = template.Must(tmpl.Parse(configTpl))
+
+ data["Content"] = m
+
+ tmpl.Execute(rw, data)
+
case "router":
- fmt.Fprintln(rw, "Print all router infomation:")
- for method, t := range BeeApp.Handlers.routers {
- fmt.Fprintln(rw)
- fmt.Fprintln(rw)
- fmt.Fprintln(rw, " Method:", method)
- printTree(rw, t)
+ resultList := new([][]string)
+
+ var result = []string{
+ fmt.Sprintf("header"),
+ fmt.Sprintf("Router Pattern"),
+ fmt.Sprintf("Methods"),
+ fmt.Sprintf("Controller"),
}
- // @todo print routers
+ *resultList = append(*resultList, result)
+
+ for method, t := range BeeApp.Handlers.routers {
+ var result = []string{
+ fmt.Sprintf("success"),
+ fmt.Sprintf("Method: %s", method),
+ fmt.Sprintf(""),
+ fmt.Sprintf(""),
+ }
+ *resultList = append(*resultList, result)
+
+ printTree(resultList, t)
+ }
+ data["Content"] = resultList
+ data["Title"] = "Routers"
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ tmpl = template.Must(tmpl.Parse(routerAndFilterTpl))
+ tmpl.Execute(rw, data)
case "filter":
- fmt.Fprintln(rw, "Print all filter infomation:")
+ resultList := new([][]string)
+
+ var result = []string{
+ fmt.Sprintf("header"),
+ fmt.Sprintf("Router Pattern"),
+ fmt.Sprintf("Filter Function"),
+ }
+ *resultList = append(*resultList, result)
+
if BeeApp.Handlers.enableFilter {
- fmt.Fprintln(rw, "BeforeRouter:")
+ var result = []string{
+ fmt.Sprintf("success"),
+ fmt.Sprintf("Before Router"),
+ fmt.Sprintf(""),
+ }
+ *resultList = append(*resultList, result)
+
if bf, ok := BeeApp.Handlers.filters[BeforeRouter]; ok {
for _, f := range bf {
- fmt.Fprintln(rw, f.pattern, utils.GetFuncName(f.filterFunc))
+
+ var result = []string{
+ fmt.Sprintf(""),
+ fmt.Sprintf("%s", f.pattern),
+ fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
+ }
+ *resultList = append(*resultList, result)
+
}
}
- fmt.Fprintln(rw, "BeforeExec:")
+ result = []string{
+ fmt.Sprintf("success"),
+ fmt.Sprintf("Before Exec"),
+ fmt.Sprintf(""),
+ }
+ *resultList = append(*resultList, result)
if bf, ok := BeeApp.Handlers.filters[BeforeExec]; ok {
for _, f := range bf {
- fmt.Fprintln(rw, f.pattern, utils.GetFuncName(f.filterFunc))
+
+ var result = []string{
+ fmt.Sprintf(""),
+ fmt.Sprintf("%s", f.pattern),
+ fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
+ }
+ *resultList = append(*resultList, result)
+
}
}
- fmt.Fprintln(rw, "AfterExec:")
+ result = []string{
+ fmt.Sprintf("success"),
+ fmt.Sprintf("AfterExec Exec"),
+ fmt.Sprintf(""),
+ }
+ *resultList = append(*resultList, result)
+
if bf, ok := BeeApp.Handlers.filters[AfterExec]; ok {
for _, f := range bf {
- fmt.Fprintln(rw, f.pattern, utils.GetFuncName(f.filterFunc))
+
+ var result = []string{
+ fmt.Sprintf(""),
+ fmt.Sprintf("%s", f.pattern),
+ fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
+ }
+ *resultList = append(*resultList, result)
+
}
}
- fmt.Fprintln(rw, "FinishRouter:")
+ result = []string{
+ fmt.Sprintf("success"),
+ fmt.Sprintf("Finish Router"),
+ fmt.Sprintf(""),
+ }
+ *resultList = append(*resultList, result)
+
if bf, ok := BeeApp.Handlers.filters[FinishRouter]; ok {
for _, f := range bf {
- fmt.Fprintln(rw, f.pattern, utils.GetFuncName(f.filterFunc))
+
+ var result = []string{
+ fmt.Sprintf(""),
+ fmt.Sprintf("%s", f.pattern),
+ fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
+ }
+ *resultList = append(*resultList, result)
+
}
}
}
+ data["Content"] = resultList
+ data["Title"] = "Filters"
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ tmpl = template.Must(tmpl.Parse(routerAndFilterTpl))
+ tmpl.Execute(rw, data)
+
default:
rw.Write([]byte("command not support"))
}
} else {
- rw.Write([]byte("beego admin dashboard"))
- rw.Write([]byte("ListConf support this command:
\n"))
- rw.Write([]byte("1. command=conf
\n"))
- rw.Write([]byte("2. command=router
\n"))
- rw.Write([]byte("3. command=filter
\n"))
- rw.Write([]byte(""))
}
}
-func printTree(rw http.ResponseWriter, t *Tree) {
+func printTree(resultList *[][]string, t *Tree) {
for _, tr := range t.fixrouters {
- printTree(rw, tr)
+ printTree(resultList, tr)
}
if t.wildcard != nil {
- printTree(rw, t.wildcard)
+ printTree(resultList, t.wildcard)
}
for _, l := range t.leaves {
if v, ok := l.runObject.(*controllerInfo); ok {
if v.routerType == routerTypeBeego {
- fmt.Fprintln(rw, v.pattern, v.methods, v.controllerType.Name())
+ var result = []string{
+ fmt.Sprintf(""),
+ fmt.Sprintf("%s", v.pattern),
+ fmt.Sprintf("%s", v.methods),
+ fmt.Sprintf("%s", v.controllerType),
+ }
+ *resultList = append(*resultList, result)
} else if v.routerType == routerTypeRESTFul {
- fmt.Fprintln(rw, v.pattern, v.methods)
+ var result = []string{
+ fmt.Sprintf(""),
+ fmt.Sprintf("%s", v.pattern),
+ fmt.Sprintf("%s", v.methods),
+ fmt.Sprintf(""),
+ }
+ *resultList = append(*resultList, result)
} else if v.routerType == routerTypeHandler {
- fmt.Fprintln(rw, v.pattern, "handler")
+ var result = []string{
+ fmt.Sprintf(""),
+ fmt.Sprintf("%s", v.pattern),
+ fmt.Sprintf(""),
+ fmt.Sprintf(""),
+ }
+ *resultList = append(*resultList, result)
}
}
}
@@ -197,58 +298,106 @@ func printTree(rw http.ResponseWriter, t *Tree) {
func profIndex(rw http.ResponseWriter, r *http.Request) {
r.ParseForm()
command := r.Form.Get("command")
+ data := make(map[interface{}]interface{})
+
+ var result bytes.Buffer
if command != "" {
- toolbox.ProcessInput(command, rw)
+ toolbox.ProcessInput(command, &result)
+ data["Content"] = result.String()
+ data["Title"] = command
+
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ tmpl = template.Must(tmpl.Parse(profillingTpl))
+ tmpl.Execute(rw, data)
} else {
- rw.Write([]byte("beego admin dashboard"))
- rw.Write([]byte("request url like '/prof?command=lookup goroutine'
\n"))
- rw.Write([]byte("the command have below types:
\n"))
- rw.Write([]byte("1. lookup goroutine
\n"))
- rw.Write([]byte("2. lookup heap
\n"))
- rw.Write([]byte("3. lookup threadcreate
\n"))
- rw.Write([]byte("4. lookup block
\n"))
- rw.Write([]byte("5. start cpuprof
\n"))
- rw.Write([]byte("6. stop cpuprof
\n"))
- rw.Write([]byte("7. get memprof
\n"))
- rw.Write([]byte("8. gc summary
\n"))
- rw.Write([]byte(""))
}
}
// Healthcheck is a http.Handler calling health checking and showing the result.
// it's in "/healthcheck" pattern in admin module.
func healthcheck(rw http.ResponseWriter, req *http.Request) {
+ data := make(map[interface{}]interface{})
+
+ resultList := new([][]string)
+ var result = []string{
+ fmt.Sprintf("header"),
+ fmt.Sprintf("Name"),
+ fmt.Sprintf("Status"),
+ }
+ *resultList = append(*resultList, result)
+
for name, h := range toolbox.AdminCheckList {
if err := h.Check(); err != nil {
- fmt.Fprintf(rw, "%s : %s\n", name, err.Error())
+ result = []string{
+ fmt.Sprintf("error"),
+ fmt.Sprintf("%s", name),
+ fmt.Sprintf("%s", err.Error()),
+ }
+
} else {
- fmt.Fprintf(rw, "%s : ok\n", name)
+ result = []string{
+ fmt.Sprintf("success"),
+ fmt.Sprintf("%s", name),
+ fmt.Sprintf("OK"),
+ }
+
}
+ *resultList = append(*resultList, result)
}
+
+ data["Content"] = resultList
+ data["Title"] = "Health Check"
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ tmpl = template.Must(tmpl.Parse(healthCheckTpl))
+ tmpl.Execute(rw, data)
+
}
// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
// it's in "/task" pattern in admin module.
func taskStatus(rw http.ResponseWriter, req *http.Request) {
- for tname, tk := range toolbox.AdminTaskList {
- fmt.Fprintf(rw, "%s:%s:%s", tname, tk.GetStatus(), tk.GetPrev().String())
- }
-}
+ data := make(map[interface{}]interface{})
-// RunTask is a http.Handler to run a Task from the "query string.
-// the request url likes /runtask?taskname=sendmail.
-func runTask(rw http.ResponseWriter, req *http.Request) {
+ // Run Task
req.ParseForm()
taskname := req.Form.Get("taskname")
- if t, ok := toolbox.AdminTaskList[taskname]; ok {
- err := t.Run()
- if err != nil {
- fmt.Fprintf(rw, "%v", err)
+ if taskname != "" {
+
+ if t, ok := toolbox.AdminTaskList[taskname]; ok {
+ err := t.Run()
+ if err != nil {
+ data["Message"] = []string{"error", fmt.Sprintf("%s", err)}
+ }
+ data["Message"] = []string{"success", fmt.Sprintf("%s run success,Now the Status is %s", taskname, t.GetStatus())}
+ } else {
+ data["Message"] = []string{"warning", fmt.Sprintf("there's no task which named: %s", taskname)}
}
- fmt.Fprintf(rw, "%s run success,Now the Status is %s", taskname, t.GetStatus())
- } else {
- fmt.Fprintf(rw, "there's no task which named:%s", taskname)
}
+
+ // List Tasks
+ resultList := new([][]string)
+ var result = []string{
+ fmt.Sprintf("header"),
+ fmt.Sprintf("Task Name"),
+ fmt.Sprintf("Task Spec"),
+ fmt.Sprintf("Task Function"),
+ }
+ *resultList = append(*resultList, result)
+ for tname, tk := range toolbox.AdminTaskList {
+ result = []string{
+ fmt.Sprintf(""),
+ fmt.Sprintf("%s", tname),
+ fmt.Sprintf("%s", tk.GetStatus()),
+ fmt.Sprintf("%s", tk.GetPrev().String()),
+ }
+ *resultList = append(*resultList, result)
+ }
+
+ data["Content"] = resultList
+ data["Title"] = "Tasks"
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ tmpl = template.Must(tmpl.Parse(tasksTpl))
+ tmpl.Execute(rw, data)
}
// adminApp is an http.HandlerFunc map used as beeAdminApp.
diff --git a/adminui.go b/adminui.go
new file mode 100644
index 00000000..a030563a
--- /dev/null
+++ b/adminui.go
@@ -0,0 +1,313 @@
+// Beego (http://beego.me/)
+// @description beego is an open-source, high-performance web framework for the Go programming language.
+// @link http://github.com/astaxie/beego for the canonical source repository
+// @license http://github.com/astaxie/beego/blob/master/LICENSE
+// @authors astaxie
+
+package beego
+
+var indexTpl = `
+{{define "content"}}
+Beego Admin Dashboard
+
+For detail usage please check our document:
+
+
+Toolbox
+
+
+Live Monitor
+
+{{.Content}}
+{{end}}`
+
+var profillingTpl = `
+{{define "content"}}
+{{.Title}}
+
+{{.Content}}
+
+{{end}}`
+
+var qpsTpl = `
+{{define "content"}}
+Requests statistics
+
+{{range $i, $slice := .Content}}
+
+{{range $j, $elem := $slice}}
+{{if eq $i 0}}
+
+{{else}}
+ |
+{{end}}
+{{$elem}}
+{{if eq $i 0}}
+
+{{else}}
+ |
+{{end}}
+{{end}}
+
+
+{{end}}
+
+{{end}}
+`
+
+var configTpl = `
+{{define "content"}}
+Configurations
+
+{{range $index, $elem := .Content}}
+{{$index}}={{$elem}}
+{{end}}
+
+{{end}}
+`
+
+var routerAndFilterTpl = `
+{{define "content"}}
+
+{{.Title}}
+
+{{range $i, $slice := .Content}}
+
+
+{{ $header := index $slice 0}}
+{{if eq "header" $header }}
+ {{range $j, $elem := $slice}}
+ {{if ne $j 0}}
+
+ {{$elem}}
+ |
+ {{end}}
+ {{end}}
+{{else if eq "success" $header}}
+ {{range $j, $elem := $slice}}
+ {{if ne $j 0}}
+
+ {{$elem}}
+ |
+ {{end}}
+ {{end}}
+{{else}}
+ {{range $j, $elem := $slice}}
+ {{if ne $j 0}}
+
+ {{$elem}}
+ |
+ {{end}}
+ {{end}}
+{{end}}
+
+
+{{end}}
+
+{{end}}
+`
+
+var tasksTpl = `
+{{define "content"}}
+
+{{.Title}}
+
+{{if .Message }}
+{{ $messageType := index .Message 0}}
+
+{{index .Message 1}}
+
+{{end}}
+
+
+
+{{range $i, $slice := .Content}}
+
+
+{{ $header := index $slice 0}}
+{{if eq "header" $header }}
+ {{range $j, $elem := $slice}}
+ {{if ne $j 0}}
+
+ {{$elem}}
+ |
+ {{end}}
+ {{end}}
+
+ Run Task
+ |
+{{else}}
+ {{range $j, $elem := $slice}}
+ {{if ne $j 0}}
+
+ {{$elem}}
+ |
+ {{end}}
+ {{end}}
+
+ Run
+ |
+{{end}}
+
+
+{{end}}
+
+{{end}}
+`
+
+var healthCheckTpl = `
+{{define "content"}}
+
+{{.Title}}
+
+{{range $i, $slice := .Content}}
+
+{{ $header := index $slice 0}}
+{{if eq "header" $header }}
+
+ {{range $j, $elem := $slice}}
+ {{if ne $j 0}}
+
+ {{$elem}}
+ |
+ {{end}}
+ {{end}}
+
+{{else}}
+ {{ if eq "success" $header}}
+
+ {{else if eq "error" $header}}
+
+ {{else}}
+
+ {{end}}
+ {{range $j, $elem := $slice}}
+ {{if ne $j 0}}
+
+ {{$elem}}
+ |
+ {{end}}
+ {{end}}
+
+{{end}}
+
+{{end}}
+
+{{end}}`
+
+// The base dashboardTpl
+var dashboardTpl = `
+
+
+
+
+
+
+
+
+
+
+Welcome to Beego Admin Dashboard
+
+
+
+
+
+
+
+
+
+
+
+
+
+{{template "content" .}}
+
+
+
+
+
+
+
+`
diff --git a/toolbox/statistics.go b/toolbox/statistics.go
index fed8cc2b..e9ebc8f8 100644
--- a/toolbox/statistics.go
+++ b/toolbox/statistics.go
@@ -1,17 +1,12 @@
// Beego (http://beego.me/)
-//
// @description beego is an open-source, high-performance web framework for the Go programming language.
-//
// @link http://github.com/astaxie/beego for the canonical source repository
-//
// @license http://github.com/astaxie/beego/blob/master/LICENSE
-//
// @authors astaxie
package toolbox
import (
"fmt"
- "io"
"sync"
"time"
)
@@ -79,17 +74,29 @@ func (m *UrlMap) AddStatistics(requestMethod, requestUrl, requestController stri
}
// put url statistics result in io.Writer
-func (m *UrlMap) GetMap(rw io.Writer) {
+func (m *UrlMap) GetMap() [][]string {
m.lock.RLock()
defer m.lock.RUnlock()
- fmt.Fprintf(rw, "| % -50s| % -10s | % -16s | % -16s | % -16s | % -16s | % -16s |\n", "requestUrl", "method", "times", "used", "max used", "min used", "avg used")
+ resultLists := make([][]string, 0)
+
+ var result = []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"}
+ resultLists = append(resultLists, result)
for k, v := range m.urlmap {
for kk, vv := range v {
- 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)),
- )
+ result := []string{
+ fmt.Sprintf("% -50s", k),
+ fmt.Sprintf("% -10s", kk),
+ fmt.Sprintf("% -16d", vv.RequestNum),
+ fmt.Sprintf("% -16s", toS(vv.TotalTime)),
+ fmt.Sprintf("% -16s", toS(vv.MaxTime)),
+ fmt.Sprintf("% -16s", toS(vv.MinTime)),
+ fmt.Sprintf("% -16s", toS(time.Duration(int64(vv.TotalTime)/vv.RequestNum))),
+ }
+ resultLists = append(resultLists, result)
}
}
+ fmt.Println(resultLists)
+ return resultLists
}
// global statistics data map