mirror of
https://github.com/astaxie/beego.git
synced 2024-11-25 22:51:29 +00:00
Added the UI for Admin monitor page
This commit is contained in:
parent
14cd9e51ac
commit
d314d12c77
367
admin.go
367
admin.go
@ -1,18 +1,15 @@
|
|||||||
// Beego (http://beego.me/)
|
// Beego (http://beego.me/)
|
||||||
//
|
|
||||||
// @description beego is an open-source, high-performance web framework for the Go programming language.
|
// @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
|
// @link http://github.com/astaxie/beego for the canonical source repository
|
||||||
//
|
|
||||||
// @license http://github.com/astaxie/beego/blob/master/LICENSE
|
// @license http://github.com/astaxie/beego/blob/master/LICENSE
|
||||||
//
|
|
||||||
// @authors astaxie
|
// @authors astaxie
|
||||||
package beego
|
package beego
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/astaxie/beego/toolbox"
|
"github.com/astaxie/beego/toolbox"
|
||||||
@ -49,7 +46,6 @@ func init() {
|
|||||||
beeAdminApp.Route("/prof", profIndex)
|
beeAdminApp.Route("/prof", profIndex)
|
||||||
beeAdminApp.Route("/healthcheck", healthcheck)
|
beeAdminApp.Route("/healthcheck", healthcheck)
|
||||||
beeAdminApp.Route("/task", taskStatus)
|
beeAdminApp.Route("/task", taskStatus)
|
||||||
beeAdminApp.Route("/runtask", runTask)
|
|
||||||
beeAdminApp.Route("/listconf", listConf)
|
beeAdminApp.Route("/listconf", listConf)
|
||||||
FilterMonitorFunc = func(string, string, time.Duration) bool { return true }
|
FilterMonitorFunc = func(string, string, time.Duration) bool { return true }
|
||||||
}
|
}
|
||||||
@ -57,22 +53,22 @@ func init() {
|
|||||||
// AdminIndex is the default http.Handler for admin module.
|
// AdminIndex is the default http.Handler for admin module.
|
||||||
// it matches url pattern "/".
|
// it matches url pattern "/".
|
||||||
func adminIndex(rw http.ResponseWriter, r *http.Request) {
|
func adminIndex(rw http.ResponseWriter, r *http.Request) {
|
||||||
rw.Write([]byte("<html><head><title>beego admin dashboard</title></head><body>"))
|
tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
|
||||||
rw.Write([]byte("Welcome to Admin Dashboard<br>\n"))
|
tmpl = template.Must(tmpl.Parse(indexTpl))
|
||||||
rw.Write([]byte("There are servral functions:<br>\n"))
|
data := make(map[interface{}]interface{})
|
||||||
rw.Write([]byte("1. Record all request and request time, <a href='/qps'>http://localhost:" + strconv.Itoa(AdminHttpPort) + "/qps</a><br>\n"))
|
tmpl.Execute(rw, data)
|
||||||
rw.Write([]byte("2. Get runtime profiling data by the pprof, <a href='/prof'>http://localhost:" + strconv.Itoa(AdminHttpPort) + "/prof</a><br>\n"))
|
|
||||||
rw.Write([]byte("3. Get healthcheck result from <a href='/healthcheck'>http://localhost:" + strconv.Itoa(AdminHttpPort) + "/healthcheck</a><br>\n"))
|
|
||||||
rw.Write([]byte("4. Get current task infomation from task <a href='/task'>http://localhost:" + strconv.Itoa(AdminHttpPort) + "/task</a><br> \n"))
|
|
||||||
rw.Write([]byte("5. To run a task passed a param <a href='/runtask'>http://localhost:" + strconv.Itoa(AdminHttpPort) + "/runtask</a><br>\n"))
|
|
||||||
rw.Write([]byte("6. Get all confige & router infomation <a href='/listconf'>http://localhost:" + strconv.Itoa(AdminHttpPort) + "/listconf</a><br>\n"))
|
|
||||||
rw.Write([]byte("</body></html>"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// QpsIndex is the http.Handler for writing qbs statistics map result info in http.ResponseWriter.
|
// 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.
|
// it's registered with url pattern "/qbs" in admin module.
|
||||||
func qpsIndex(rw http.ResponseWriter, r *http.Request) {
|
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.
|
// 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()
|
r.ParseForm()
|
||||||
command := r.Form.Get("command")
|
command := r.Form.Get("command")
|
||||||
if command != "" {
|
if command != "" {
|
||||||
|
data := make(map[interface{}]interface{})
|
||||||
switch command {
|
switch command {
|
||||||
case "conf":
|
case "conf":
|
||||||
fmt.Fprintln(rw, "list all beego's conf:")
|
m := make(map[string]interface{})
|
||||||
fmt.Fprintln(rw, "AppName:", AppName)
|
|
||||||
fmt.Fprintln(rw, "AppPath:", AppPath)
|
m["AppName"] = AppName
|
||||||
fmt.Fprintln(rw, "AppConfigPath:", AppConfigPath)
|
m["AppPath"] = AppPath
|
||||||
fmt.Fprintln(rw, "StaticDir:", StaticDir)
|
m["AppConfigPath"] = AppConfigPath
|
||||||
fmt.Fprintln(rw, "StaticExtensionsToGzip:", StaticExtensionsToGzip)
|
m["StaticDir"] = StaticDir
|
||||||
fmt.Fprintln(rw, "HttpAddr:", HttpAddr)
|
m["StaticExtensionsToGzip"] = StaticExtensionsToGzip
|
||||||
fmt.Fprintln(rw, "HttpPort:", HttpPort)
|
m["HttpAddr"] = HttpAddr
|
||||||
fmt.Fprintln(rw, "HttpTLS:", EnableHttpTLS)
|
m["HttpPort"] = HttpPort
|
||||||
fmt.Fprintln(rw, "HttpCertFile:", HttpCertFile)
|
m["HttpTLS"] = EnableHttpTLS
|
||||||
fmt.Fprintln(rw, "HttpKeyFile:", HttpKeyFile)
|
m["HttpCertFile"] = HttpCertFile
|
||||||
fmt.Fprintln(rw, "RecoverPanic:", RecoverPanic)
|
m["HttpKeyFile"] = HttpKeyFile
|
||||||
fmt.Fprintln(rw, "AutoRender:", AutoRender)
|
m["RecoverPanic"] = RecoverPanic
|
||||||
fmt.Fprintln(rw, "ViewsPath:", ViewsPath)
|
m["AutoRender"] = AutoRender
|
||||||
fmt.Fprintln(rw, "RunMode:", RunMode)
|
m["ViewsPath"] = ViewsPath
|
||||||
fmt.Fprintln(rw, "SessionOn:", SessionOn)
|
m["RunMode"] = RunMode
|
||||||
fmt.Fprintln(rw, "SessionProvider:", SessionProvider)
|
m["SessionOn"] = SessionOn
|
||||||
fmt.Fprintln(rw, "SessionName:", SessionName)
|
m["SessionProvider"] = SessionProvider
|
||||||
fmt.Fprintln(rw, "SessionGCMaxLifetime:", SessionGCMaxLifetime)
|
m["SessionName"] = SessionName
|
||||||
fmt.Fprintln(rw, "SessionSavePath:", SessionSavePath)
|
m["SessionGCMaxLifetime"] = SessionGCMaxLifetime
|
||||||
fmt.Fprintln(rw, "SessionHashFunc:", SessionHashFunc)
|
m["SessionSavePath"] = SessionSavePath
|
||||||
fmt.Fprintln(rw, "SessionHashKey:", SessionHashKey)
|
m["SessionHashFunc"] = SessionHashFunc
|
||||||
fmt.Fprintln(rw, "SessionCookieLifeTime:", SessionCookieLifeTime)
|
m["SessionHashKey"] = SessionHashKey
|
||||||
fmt.Fprintln(rw, "UseFcgi:", UseFcgi)
|
m["SessionCookieLifeTime"] = SessionCookieLifeTime
|
||||||
fmt.Fprintln(rw, "MaxMemory:", MaxMemory)
|
m["UseFcgi"] = UseFcgi
|
||||||
fmt.Fprintln(rw, "EnableGzip:", EnableGzip)
|
m["MaxMemory"] = MaxMemory
|
||||||
fmt.Fprintln(rw, "DirectoryIndex:", DirectoryIndex)
|
m["EnableGzip"] = EnableGzip
|
||||||
fmt.Fprintln(rw, "HttpServerTimeOut:", HttpServerTimeOut)
|
m["DirectoryIndex"] = DirectoryIndex
|
||||||
fmt.Fprintln(rw, "ErrorsShow:", ErrorsShow)
|
m["HttpServerTimeOut"] = HttpServerTimeOut
|
||||||
fmt.Fprintln(rw, "XSRFKEY:", XSRFKEY)
|
m["ErrorsShow"] = ErrorsShow
|
||||||
fmt.Fprintln(rw, "EnableXSRF:", EnableXSRF)
|
m["XSRFKEY"] = XSRFKEY
|
||||||
fmt.Fprintln(rw, "XSRFExpire:", XSRFExpire)
|
m["EnableXSRF"] = EnableXSRF
|
||||||
fmt.Fprintln(rw, "CopyRequestBody:", CopyRequestBody)
|
m["XSRFExpire"] = XSRFExpire
|
||||||
fmt.Fprintln(rw, "TemplateLeft:", TemplateLeft)
|
m["CopyRequestBody"] = CopyRequestBody
|
||||||
fmt.Fprintln(rw, "TemplateRight:", TemplateRight)
|
m["TemplateLeft"] = TemplateLeft
|
||||||
fmt.Fprintln(rw, "BeegoServerName:", BeegoServerName)
|
m["TemplateRight"] = TemplateRight
|
||||||
fmt.Fprintln(rw, "EnableAdmin:", EnableAdmin)
|
m["BeegoServerName"] = BeegoServerName
|
||||||
fmt.Fprintln(rw, "AdminHttpAddr:", AdminHttpAddr)
|
m["EnableAdmin"] = EnableAdmin
|
||||||
fmt.Fprintln(rw, "AdminHttpPort:", AdminHttpPort)
|
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":
|
case "router":
|
||||||
fmt.Fprintln(rw, "Print all router infomation:")
|
resultList := new([][]string)
|
||||||
for method, t := range BeeApp.Handlers.routers {
|
|
||||||
fmt.Fprintln(rw)
|
var result = []string{
|
||||||
fmt.Fprintln(rw)
|
fmt.Sprintf("header"),
|
||||||
fmt.Fprintln(rw, " Method:", method)
|
fmt.Sprintf("Router Pattern"),
|
||||||
printTree(rw, t)
|
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":
|
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 {
|
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 {
|
if bf, ok := BeeApp.Handlers.filters[BeforeRouter]; ok {
|
||||||
for _, f := range bf {
|
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 {
|
if bf, ok := BeeApp.Handlers.filters[BeforeExec]; ok {
|
||||||
for _, f := range bf {
|
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 {
|
if bf, ok := BeeApp.Handlers.filters[AfterExec]; ok {
|
||||||
for _, f := range bf {
|
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 {
|
if bf, ok := BeeApp.Handlers.filters[FinishRouter]; ok {
|
||||||
for _, f := range bf {
|
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:
|
default:
|
||||||
rw.Write([]byte("command not support"))
|
rw.Write([]byte("command not support"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rw.Write([]byte("<html><head><title>beego admin dashboard</title></head><body>"))
|
|
||||||
rw.Write([]byte("ListConf support this command:<br>\n"))
|
|
||||||
rw.Write([]byte("1. <a href='?command=conf'>command=conf</a><br>\n"))
|
|
||||||
rw.Write([]byte("2. <a href='?command=router'>command=router</a><br>\n"))
|
|
||||||
rw.Write([]byte("3. <a href='?command=filter'>command=filter</a><br>\n"))
|
|
||||||
rw.Write([]byte("</body></html>"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func printTree(rw http.ResponseWriter, t *Tree) {
|
func printTree(resultList *[][]string, t *Tree) {
|
||||||
for _, tr := range t.fixrouters {
|
for _, tr := range t.fixrouters {
|
||||||
printTree(rw, tr)
|
printTree(resultList, tr)
|
||||||
}
|
}
|
||||||
if t.wildcard != nil {
|
if t.wildcard != nil {
|
||||||
printTree(rw, t.wildcard)
|
printTree(resultList, t.wildcard)
|
||||||
}
|
}
|
||||||
for _, l := range t.leaves {
|
for _, l := range t.leaves {
|
||||||
if v, ok := l.runObject.(*controllerInfo); ok {
|
if v, ok := l.runObject.(*controllerInfo); ok {
|
||||||
if v.routerType == routerTypeBeego {
|
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 {
|
} 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 {
|
} 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) {
|
func profIndex(rw http.ResponseWriter, r *http.Request) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
command := r.Form.Get("command")
|
command := r.Form.Get("command")
|
||||||
|
data := make(map[interface{}]interface{})
|
||||||
|
|
||||||
|
var result bytes.Buffer
|
||||||
if command != "" {
|
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 {
|
} else {
|
||||||
rw.Write([]byte("<html><head><title>beego admin dashboard</title></head><body>"))
|
|
||||||
rw.Write([]byte("request url like '/prof?command=lookup goroutine'<br>\n"))
|
|
||||||
rw.Write([]byte("the command have below types:<br>\n"))
|
|
||||||
rw.Write([]byte("1. <a href='?command=lookup goroutine'>lookup goroutine</a><br>\n"))
|
|
||||||
rw.Write([]byte("2. <a href='?command=lookup heap'>lookup heap</a><br>\n"))
|
|
||||||
rw.Write([]byte("3. <a href='?command=lookup threadcreate'>lookup threadcreate</a><br>\n"))
|
|
||||||
rw.Write([]byte("4. <a href='?command=lookup block'>lookup block</a><br>\n"))
|
|
||||||
rw.Write([]byte("5. <a href='?command=start cpuprof'>start cpuprof</a><br>\n"))
|
|
||||||
rw.Write([]byte("6. <a href='?command=stop cpuprof'>stop cpuprof</a><br>\n"))
|
|
||||||
rw.Write([]byte("7. <a href='?command=get memprof'>get memprof</a><br>\n"))
|
|
||||||
rw.Write([]byte("8. <a href='?command=gc summary'>gc summary</a><br>\n"))
|
|
||||||
rw.Write([]byte("</body></html>"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Healthcheck is a http.Handler calling health checking and showing the result.
|
// Healthcheck is a http.Handler calling health checking and showing the result.
|
||||||
// it's in "/healthcheck" pattern in admin module.
|
// it's in "/healthcheck" pattern in admin module.
|
||||||
func healthcheck(rw http.ResponseWriter, req *http.Request) {
|
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 {
|
for name, h := range toolbox.AdminCheckList {
|
||||||
if err := h.Check(); err != nil {
|
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 {
|
} 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).
|
// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
|
||||||
// it's in "/task" pattern in admin module.
|
// it's in "/task" pattern in admin module.
|
||||||
func taskStatus(rw http.ResponseWriter, req *http.Request) {
|
func taskStatus(rw http.ResponseWriter, req *http.Request) {
|
||||||
for tname, tk := range toolbox.AdminTaskList {
|
data := make(map[interface{}]interface{})
|
||||||
fmt.Fprintf(rw, "%s:%s:%s", tname, tk.GetStatus(), tk.GetPrev().String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunTask is a http.Handler to run a Task from the "query string.
|
// Run Task
|
||||||
// the request url likes /runtask?taskname=sendmail.
|
|
||||||
func runTask(rw http.ResponseWriter, req *http.Request) {
|
|
||||||
req.ParseForm()
|
req.ParseForm()
|
||||||
taskname := req.Form.Get("taskname")
|
taskname := req.Form.Get("taskname")
|
||||||
|
if taskname != "" {
|
||||||
|
|
||||||
if t, ok := toolbox.AdminTaskList[taskname]; ok {
|
if t, ok := toolbox.AdminTaskList[taskname]; ok {
|
||||||
err := t.Run()
|
err := t.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(rw, "%v", err)
|
data["Message"] = []string{"error", fmt.Sprintf("%s", err)}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(rw, "%s run success,Now the Status is %s", taskname, t.GetStatus())
|
data["Message"] = []string{"success", fmt.Sprintf("%s run success,Now the Status is %s", taskname, t.GetStatus())}
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(rw, "there's no task which named:%s", taskname)
|
data["Message"] = []string{"warning", fmt.Sprintf("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.
|
// adminApp is an http.HandlerFunc map used as beeAdminApp.
|
||||||
|
313
adminui.go
Normal file
313
adminui.go
Normal file
File diff suppressed because one or more lines are too long
@ -1,17 +1,12 @@
|
|||||||
// Beego (http://beego.me/)
|
// Beego (http://beego.me/)
|
||||||
//
|
|
||||||
// @description beego is an open-source, high-performance web framework for the Go programming language.
|
// @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
|
// @link http://github.com/astaxie/beego for the canonical source repository
|
||||||
//
|
|
||||||
// @license http://github.com/astaxie/beego/blob/master/LICENSE
|
// @license http://github.com/astaxie/beego/blob/master/LICENSE
|
||||||
//
|
|
||||||
// @authors astaxie
|
// @authors astaxie
|
||||||
package toolbox
|
package toolbox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -79,17 +74,29 @@ func (m *UrlMap) AddStatistics(requestMethod, requestUrl, requestController stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// put url statistics result in io.Writer
|
// put url statistics result in io.Writer
|
||||||
func (m *UrlMap) GetMap(rw io.Writer) {
|
func (m *UrlMap) GetMap() [][]string {
|
||||||
m.lock.RLock()
|
m.lock.RLock()
|
||||||
defer m.lock.RUnlock()
|
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 k, v := range m.urlmap {
|
||||||
for kk, vv := range v {
|
for kk, vv := range v {
|
||||||
fmt.Fprintf(rw, "| % -50s| % -10s | % -16d | % -16s | % -16s | % -16s | % -16s |\n", k,
|
result := []string{
|
||||||
kk, vv.RequestNum, toS(vv.TotalTime), toS(vv.MaxTime), toS(vv.MinTime), toS(time.Duration(int64(vv.TotalTime)/vv.RequestNum)),
|
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
|
// global statistics data map
|
||||||
|
Loading…
Reference in New Issue
Block a user