1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-22 09:20:55 +00:00

Merge pull request #773 from lei-cao/develop

Added data table admin ui
This commit is contained in:
astaxie 2014-08-25 07:32:07 +08:00
commit f6a1a6c9bf
3 changed files with 171 additions and 159 deletions

122
admin.go
View File

@ -142,121 +142,116 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
tmpl.Execute(rw, data) tmpl.Execute(rw, data)
case "router": case "router":
resultList := new([][]string) content := make(map[string]interface{})
var result = []string{ var fields = []string{
fmt.Sprintf("header"),
fmt.Sprintf("Router Pattern"), fmt.Sprintf("Router Pattern"),
fmt.Sprintf("Methods"), fmt.Sprintf("Methods"),
fmt.Sprintf("Controller"), fmt.Sprintf("Controller"),
} }
*resultList = append(*resultList, result) content["Fields"] = fields
methods := []string{}
methodsData := make(map[string]interface{})
for method, t := range BeeApp.Handlers.routers { for method, t := range BeeApp.Handlers.routers {
var result = []string{
fmt.Sprintf("success"), resultList := new([][]string)
fmt.Sprintf("Method: %s", method),
fmt.Sprintf(""),
fmt.Sprintf(""),
}
*resultList = append(*resultList, result)
printTree(resultList, t) printTree(resultList, t)
methods = append(methods, method)
methodsData[method] = resultList
} }
data["Content"] = resultList
content["Data"] = methodsData
content["Methods"] = methods
data["Content"] = content
data["Title"] = "Routers" data["Title"] = "Routers"
tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl)) tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
tmpl = template.Must(tmpl.Parse(routerAndFilterTpl)) tmpl = template.Must(tmpl.Parse(routerAndFilterTpl))
tmpl = template.Must(tmpl.Parse(defaultScriptsTpl)) tmpl = template.Must(tmpl.Parse(defaultScriptsTpl))
tmpl.Execute(rw, data) tmpl.Execute(rw, data)
case "filter": case "filter":
resultList := new([][]string) content := make(map[string]interface{})
var result = []string{ var fields = []string{
fmt.Sprintf("header"),
fmt.Sprintf("Router Pattern"), fmt.Sprintf("Router Pattern"),
fmt.Sprintf("Filter Function"), fmt.Sprintf("Filter Function"),
} }
*resultList = append(*resultList, result) content["Fields"] = fields
filterTypes := []string{}
filterTypeData := make(map[string]interface{})
if BeeApp.Handlers.enableFilter { if BeeApp.Handlers.enableFilter {
var result = []string{ var filterType 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 {
filterType = "Before Router"
filterTypes = append(filterTypes, filterType)
resultList := new([][]string)
for _, f := range bf { for _, f := range bf {
var result = []string{ var result = []string{
fmt.Sprintf(""),
fmt.Sprintf("%s", f.pattern), fmt.Sprintf("%s", f.pattern),
fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)), fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
} }
*resultList = append(*resultList, result) *resultList = append(*resultList, result)
} }
filterTypeData[filterType] = resultList
} }
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 {
filterType = "Before Exec"
filterTypes = append(filterTypes, filterType)
resultList := new([][]string)
for _, f := range bf { for _, f := range bf {
var result = []string{ var result = []string{
fmt.Sprintf(""),
fmt.Sprintf("%s", f.pattern), fmt.Sprintf("%s", f.pattern),
fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)), fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
} }
*resultList = append(*resultList, result) *resultList = append(*resultList, result)
} }
filterTypeData[filterType] = resultList
} }
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 {
filterType = "After Exec"
filterTypes = append(filterTypes, filterType)
resultList := new([][]string)
for _, f := range bf { for _, f := range bf {
var result = []string{ var result = []string{
fmt.Sprintf(""),
fmt.Sprintf("%s", f.pattern), fmt.Sprintf("%s", f.pattern),
fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)), fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
} }
*resultList = append(*resultList, result) *resultList = append(*resultList, result)
} }
filterTypeData[filterType] = resultList
} }
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 {
filterType = "Finish Router"
filterTypes = append(filterTypes, filterType)
resultList := new([][]string)
for _, f := range bf { for _, f := range bf {
var result = []string{ var result = []string{
fmt.Sprintf(""),
fmt.Sprintf("%s", f.pattern), fmt.Sprintf("%s", f.pattern),
fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)), fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
} }
*resultList = append(*resultList, result) *resultList = append(*resultList, result)
} }
filterTypeData[filterType] = resultList
} }
} }
data["Content"] = resultList
content["Data"] = filterTypeData
content["Methods"] = filterTypes
data["Content"] = content
data["Title"] = "Filters" data["Title"] = "Filters"
tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl)) tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
tmpl = template.Must(tmpl.Parse(routerAndFilterTpl)) tmpl = template.Must(tmpl.Parse(routerAndFilterTpl))
@ -281,7 +276,6 @@ func printTree(resultList *[][]string, t *Tree) {
if v, ok := l.runObject.(*controllerInfo); ok { if v, ok := l.runObject.(*controllerInfo); ok {
if v.routerType == routerTypeBeego { if v.routerType == routerTypeBeego {
var result = []string{ var result = []string{
fmt.Sprintf(""),
fmt.Sprintf("%s", v.pattern), fmt.Sprintf("%s", v.pattern),
fmt.Sprintf("%s", v.methods), fmt.Sprintf("%s", v.methods),
fmt.Sprintf("%s", v.controllerType), fmt.Sprintf("%s", v.controllerType),
@ -289,7 +283,6 @@ func printTree(resultList *[][]string, t *Tree) {
*resultList = append(*resultList, result) *resultList = append(*resultList, result)
} else if v.routerType == routerTypeRESTFul { } else if v.routerType == routerTypeRESTFul {
var result = []string{ var result = []string{
fmt.Sprintf(""),
fmt.Sprintf("%s", v.pattern), fmt.Sprintf("%s", v.pattern),
fmt.Sprintf("%s", v.methods), fmt.Sprintf("%s", v.methods),
fmt.Sprintf(""), fmt.Sprintf(""),
@ -297,7 +290,6 @@ func printTree(resultList *[][]string, t *Tree) {
*resultList = append(*resultList, result) *resultList = append(*resultList, result)
} else if v.routerType == routerTypeHandler { } else if v.routerType == routerTypeHandler {
var result = []string{ var result = []string{
fmt.Sprintf(""),
fmt.Sprintf("%s", v.pattern), fmt.Sprintf("%s", v.pattern),
fmt.Sprintf(""), fmt.Sprintf(""),
fmt.Sprintf(""), fmt.Sprintf(""),
@ -352,13 +344,15 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
func healthcheck(rw http.ResponseWriter, req *http.Request) { func healthcheck(rw http.ResponseWriter, req *http.Request) {
data := make(map[interface{}]interface{}) data := make(map[interface{}]interface{})
resultList := new([][]string) var result = []string{}
var result = []string{ fields := []string{
fmt.Sprintf("header"),
fmt.Sprintf("Name"), fmt.Sprintf("Name"),
fmt.Sprintf("Message"),
fmt.Sprintf("Status"), fmt.Sprintf("Status"),
} }
*resultList = append(*resultList, result) resultList := new([][]string)
content := make(map[string]interface{})
for name, h := range toolbox.AdminCheckList { for name, h := range toolbox.AdminCheckList {
if err := h.Check(); err != nil { if err := h.Check(); err != nil {
@ -379,7 +373,9 @@ func healthcheck(rw http.ResponseWriter, req *http.Request) {
*resultList = append(*resultList, result) *resultList = append(*resultList, result)
} }
data["Content"] = resultList content["Fields"] = fields
content["Data"] = resultList
data["Content"] = content
data["Title"] = "Health Check" data["Title"] = "Health Check"
tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl)) tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
tmpl = template.Must(tmpl.Parse(healthCheckTpl)) tmpl = template.Must(tmpl.Parse(healthCheckTpl))
@ -410,17 +406,17 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
} }
// List Tasks // List Tasks
content := make(map[string]interface{})
resultList := new([][]string) resultList := new([][]string)
var result = []string{ var result = []string{}
fmt.Sprintf("header"), var fields = []string{
fmt.Sprintf("Task Name"), fmt.Sprintf("Task Name"),
fmt.Sprintf("Task Spec"), fmt.Sprintf("Task Spec"),
fmt.Sprintf("Task Function"), fmt.Sprintf("Task Function"),
fmt.Sprintf(""),
} }
*resultList = append(*resultList, result)
for tname, tk := range toolbox.AdminTaskList { for tname, tk := range toolbox.AdminTaskList {
result = []string{ result = []string{
fmt.Sprintf(""),
fmt.Sprintf("%s", tname), fmt.Sprintf("%s", tname),
fmt.Sprintf("%s", tk.GetStatus()), fmt.Sprintf("%s", tk.GetStatus()),
fmt.Sprintf("%s", tk.GetPrev().String()), fmt.Sprintf("%s", tk.GetPrev().String()),
@ -428,7 +424,9 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
*resultList = append(*resultList, result) *resultList = append(*resultList, result)
} }
data["Content"] = resultList content["Fields"] = fields
content["Data"] = resultList
data["Content"] = content
data["Title"] = "Tasks" data["Title"] = "Tasks"
tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl)) tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
tmpl = template.Must(tmpl.Parse(tasksTpl)) tmpl = template.Must(tmpl.Parse(tasksTpl))

View File

@ -61,31 +61,35 @@ var gcAjaxTpl = `
{{end}} {{end}}
` `
var qpsTpl = ` var qpsTpl = `{{define "content"}}
{{define "content"}}
<h1>Requests statistics</h1> <h1>Requests statistics</h1>
<table class="table table-striped table-hover "> <table class="table table-striped table-hover ">
{{range $i, $slice := .Content}} <thead>
<tr> <tr>
{{range $j, $elem := $slice}} {{range .Content.Fields}}
{{if eq $i 0}} <th>
<th> {{.}}
{{else}} </th>
<td> {{end}}
{{end}} </tr>
{{$elem}} </thead>
{{if eq $i 0}}
</th> <tbody>
{{else}} {{range $i, $elem := .Content.Data}}
</td>
{{end}} <tr>
{{end}} {{range $elem}}
<td>
{{.}}
</td>
{{end}}
</tr>
{{end}}
</tbody>
</tr>
{{end}}
</table> </table>
{{end}} {{end}}`
`
var configTpl = ` var configTpl = `
{{define "content"}} {{define "content"}}
@ -98,49 +102,51 @@ var configTpl = `
{{end}} {{end}}
` `
var routerAndFilterTpl = ` var routerAndFilterTpl = `{{define "content"}}
{{define "content"}}
<h1>{{.Title}}</h1> <h1>{{.Title}}</h1>
{{range .Content.Methods}}
<div class="panel panel-default">
<div class="panel-heading lead success"><strong>{{.}}</strong></div>
<div class="panel-body">
<table class="table table-striped table-hover "> <table class="table table-striped table-hover ">
{{range $i, $slice := .Content}} <thead>
<tr> <tr>
{{range $.Content.Fields}}
<th>
{{.}}
</th>
{{end}}
</tr>
</thead>
{{ $header := index $slice 0}} <tbody>
{{if eq "header" $header }} {{$slice := index $.Content.Data .}}
{{range $j, $elem := $slice}} {{range $i, $elem := $slice}}
{{if ne $j 0}}
<th> <tr>
{{$elem}} {{range $elem}}
</th> <td>
{{end}} {{.}}
{{end}} </td>
{{else if eq "success" $header}} {{end}}
{{range $j, $elem := $slice}} </tr>
{{if ne $j 0}}
<th class="success"> {{end}}
{{$elem}} </tbody>
</th>
{{end}}
{{end}}
{{else}}
{{range $j, $elem := $slice}}
{{if ne $j 0}}
<td>
{{$elem}}
</td>
{{end}}
{{end}}
{{end}}
</tr>
{{end}}
</table> </table>
</div>
</div>
{{end}} {{end}}
`
var tasksTpl = `
{{define "content"}} {{end}}`
var tasksTpl = `{{define "content"}}
<h1>{{.Title}}</h1> <h1>{{.Title}}</h1>
@ -161,59 +167,51 @@ bg-warning
<table class="table table-striped table-hover "> <table class="table table-striped table-hover ">
{{range $i, $slice := .Content}} <thead>
<tr> <tr>
{{range .Content.Fields}}
<th>
{{.}}
</th>
{{end}}
</tr>
</thead>
{{ $header := index $slice 0}} <tbody>
{{if eq "header" $header }} {{range $i, $slice := .Content.Data}}
{{range $j, $elem := $slice}} <tr>
{{if ne $j 0}} {{range $slice}}
<th>
{{$elem}}
</th>
{{end}}
{{end}}
<th>
Run Task
</th>
{{else}}
{{range $j, $elem := $slice}}
{{if ne $j 0}}
<td> <td>
{{$elem}} {{.}}
</td> </td>
{{end}} {{end}}
{{end}}
<td> <td>
<a class="btn btn-primary btn-sm" href="/task?taskname={{index $slice 1}}">Run</a> <a class="btn btn-primary btn-sm" href="/task?taskname={{index $slice 1}}">Run</a>
</td> </td>
{{end}}
</tr> </tr>
{{end}} {{end}}
</tbody>
</table> </table>
{{end}}
` {{end}}`
var healthCheckTpl = ` var healthCheckTpl = `
{{define "content"}} {{define "content"}}
<h1>{{.Title}}</h1> <h1>{{.Title}}</h1>
<table class="table table-striped table-hover "> <table class="table table-striped table-hover ">
{{range $i, $slice := .Content}} <thead>
{{ $header := index $slice 0}}
{{if eq "header" $header }}
<tr> <tr>
{{range $j, $elem := $slice}} {{range .Content.Fields}}
{{if ne $j 0}}
<th> <th>
{{$elem}} {{.}}
</th> </th>
{{end}} {{end}}
{{end}}
</tr> </tr>
{{else}} </thead>
<tbody>
{{range $i, $slice := .Content.Data}}
{{ $header := index $slice 0}}
{{ if eq "success" $header}} {{ if eq "success" $header}}
<tr class="success"> <tr class="success">
{{else if eq "error" $header}} {{else if eq "error" $header}}
@ -228,10 +226,13 @@ var healthCheckTpl = `
</td> </td>
{{end}} {{end}}
{{end}} {{end}}
<td>
{{$header}}
</td>
</tr> </tr>
{{end}} {{end}}
{{end}} </tbody>
</table> </table>
{{end}}` {{end}}`
@ -251,7 +252,8 @@ Welcome to Beego Admin Dashboard
</title> </title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"> <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<link href="//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.css" rel="stylesheet">
<style type="text/css"> <style type="text/css">
ul.nav li.dropdown:hover > ul.dropdown-menu { ul.nav li.dropdown:hover > ul.dropdown-menu {
@ -336,9 +338,17 @@ Healthcheck
{{template "content" .}} {{template "content" .}}
</div> </div>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<script src="//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.js
"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.table').dataTable();
});
</script>
{{template "scripts" .}} {{template "scripts" .}}
</body> </body>
</html> </html>

View File

@ -83,13 +83,16 @@ 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() [][]string { func (m *UrlMap) GetMap() map[string]interface{} {
m.lock.RLock() m.lock.RLock()
defer m.lock.RUnlock() defer m.lock.RUnlock()
resultLists := make([][]string, 0)
var result = []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"} var fields = []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"}
resultLists = append(resultLists, result)
resultLists := make([][]string, 0)
content := make(map[string]interface{})
content["Fields"] = fields
for k, v := range m.urlmap { for k, v := range m.urlmap {
for kk, vv := range v { for kk, vv := range v {
result := []string{ result := []string{
@ -104,7 +107,8 @@ func (m *UrlMap) GetMap() [][]string {
resultLists = append(resultLists, result) resultLists = append(resultLists, result)
} }
} }
return resultLists content["Data"] = resultLists
return content
} }
// global statistics data map // global statistics data map