diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go
index 0c42d9e7..b39278b1 100644
--- a/internal/rpc/rpc_client.go
+++ b/internal/rpc/rpc_client.go
@@ -161,6 +161,10 @@ func (this *RPCClient) APINodeRPC() pb.APINodeServiceClient {
return pb.NewAPINodeServiceClient(this.pickConn())
}
+func (this *RPCClient) APIMethodStatRPC() pb.APIMethodStatServiceClient {
+ return pb.NewAPIMethodStatServiceClient(this.pickConn())
+}
+
func (this *RPCClient) UserNodeRPC() pb.UserNodeServiceClient {
return pb.NewUserNodeServiceClient(this.pickConn())
}
diff --git a/internal/web/actions/default/api/index.go b/internal/web/actions/default/api/index.go
index 7cda3313..292e6978 100644
--- a/internal/web/actions/default/api/index.go
+++ b/internal/web/actions/default/api/index.go
@@ -9,6 +9,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/maps"
+ timeutil "github.com/iwind/TeaGo/utils/time"
"time"
)
@@ -26,11 +27,11 @@ func (this *IndexAction) RunGet(params struct{}) {
this.ErrorPage(err)
return
}
- count := countResp.Count
- page := this.NewPage(count)
+ var count = countResp.Count
+ var page = this.NewPage(count)
this.Data["page"] = page.AsHTML()
- nodeMaps := []maps.Map{}
+ var nodeMaps = []maps.Map{}
if count > 0 {
nodesResp, err := this.RPC().APINodeRPC().ListEnabledAPINodes(this.AdminContext(), &pb.ListEnabledAPINodesRequest{
Offset: page.Offset,
@@ -106,5 +107,13 @@ func (this *IndexAction) RunGet(params struct{}) {
}
this.Data["nodes"] = nodeMaps
+ // 检查是否有调试数据
+ countMethodStatsResp, err := this.RPC().APIMethodStatRPC().CountAPIMethodStatsWithDay(this.AdminContext(), &pb.CountAPIMethodStatsWithDayRequest{Day: timeutil.Format("Ymd")})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ this.Data["hasMethodStats"] = countMethodStatsResp.Count > 0
+
this.Show()
}
diff --git a/internal/web/actions/default/api/init.go b/internal/web/actions/default/api/init.go
index 03c74fae..8e12573e 100644
--- a/internal/web/actions/default/api/init.go
+++ b/internal/web/actions/default/api/init.go
@@ -16,6 +16,7 @@ func init() {
Helper(settingutils.NewAdvancedHelper("apiNodes")).
Prefix("/api").
Get("", new(IndexAction)).
+ Get("/methodStats", new(MethodStatsAction)).
GetPost("/node/createPopup", new(node.CreatePopupAction)).
Post("/delete", new(DeleteAction)).
EndAll()
diff --git a/internal/web/actions/default/api/methodStats.go b/internal/web/actions/default/api/methodStats.go
new file mode 100644
index 00000000..00eeaac2
--- /dev/null
+++ b/internal/web/actions/default/api/methodStats.go
@@ -0,0 +1,78 @@
+// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
+
+package api
+
+import (
+ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
+ "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
+ "github.com/iwind/TeaGo/maps"
+ timeutil "github.com/iwind/TeaGo/utils/time"
+ "sort"
+ "strings"
+)
+
+type MethodStatsAction struct {
+ actionutils.ParentAction
+}
+
+func (this *MethodStatsAction) Init() {
+ this.Nav("", "", "")
+}
+
+func (this *MethodStatsAction) RunGet(params struct {
+ Order string
+ Method string
+ Tag string
+}) {
+ this.Data["order"] = params.Order
+ this.Data["method"] = params.Method
+ this.Data["tag"] = params.Tag
+
+ statsResp, err := this.RPC().APIMethodStatRPC().FindAPIMethodStatsWithDay(this.AdminContext(), &pb.FindAPIMethodStatsWithDayRequest{Day: timeutil.Format("Ymd")})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ var pbStats = statsResp.ApiMethodStats
+
+ switch params.Order {
+ case "method":
+ sort.Slice(pbStats, func(i, j int) bool {
+ return pbStats[i].Method < pbStats[j].Method
+ })
+ case "costMs.desc":
+ sort.Slice(pbStats, func(i, j int) bool {
+ return pbStats[i].CostMs > pbStats[j].CostMs
+ })
+ case "peekMs.desc":
+ sort.Slice(pbStats, func(i, j int) bool {
+ return pbStats[i].PeekMs > pbStats[j].PeekMs
+ })
+ case "calls.desc":
+ sort.Slice(pbStats, func(i, j int) bool {
+ return pbStats[i].CountCalls > pbStats[j].CountCalls
+ })
+ }
+
+ var statMaps = []maps.Map{}
+ for _, stat := range pbStats {
+ if len(params.Method) > 0 && !strings.Contains(strings.ToLower(stat.Method), strings.ToLower(params.Method)) {
+ continue
+ }
+ if len(params.Tag) > 0 && !strings.Contains(strings.ToLower(stat.Tag), strings.ToLower(params.Tag)) {
+ continue
+ }
+
+ statMaps = append(statMaps, maps.Map{
+ "id": stat.Id,
+ "method": stat.Method,
+ "tag": stat.Tag,
+ "costMs": stat.CostMs,
+ "peekMs": stat.PeekMs,
+ "countCalls": stat.CountCalls,
+ })
+ }
+ this.Data["stats"] = statMaps
+
+ this.Show()
+}
diff --git a/web/views/@default/api/index.html b/web/views/@default/api/index.html
index d15974cf..73bf2fa3 100644
--- a/web/views/@default/api/index.html
+++ b/web/views/@default/api/index.html
@@ -2,6 +2,7 @@
暂时还没有节点。
diff --git a/web/views/@default/api/methodStats.html b/web/views/@default/api/methodStats.html new file mode 100644 index 00000000..df95dcb1 --- /dev/null +++ b/web/views/@default/api/methodStats.html @@ -0,0 +1,46 @@ +{$layout} + + + + +| 方法 | +标签 | +平均耗时 | +峰值耗时 | +调用次数 | +
|---|---|---|---|---|
| {{stat.method}} | +{{stat.tag}} | +{{stat.costMs}}ms | +{{stat.peekMs}}ms | +{{stat.countCalls}}次 | +