增加API方法调用耗时统计

This commit is contained in:
GoEdgeLab
2022-01-19 16:53:52 +08:00
parent 933edea4e0
commit 72668b68e9
24 changed files with 427 additions and 22 deletions

View File

@@ -83,6 +83,20 @@ func main() {
}
}
})
app.On("debug", func() {
var sock = gosock.NewTmpSock(teaconst.ProcessName)
reply, err := sock.Send(&gosock.Command{Code: "debug"})
if err != nil {
fmt.Println("[ERROR]" + err.Error())
} else {
var isDebug = maps.NewMap(reply.Params).GetBool("debug")
if isDebug {
fmt.Println("debug on")
} else {
fmt.Println("debug off")
}
}
})
app.Run(func() {
nodes.NewAPINode().Start()
})

View File

@@ -1,7 +1,7 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build community
// +build community
//go:build !plus
// +build !plus
package accesslogs

View File

@@ -1,5 +1,6 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
// +build community
//go:build !plus
// +build !plus
package teaconst

View File

@@ -6,4 +6,5 @@ var (
IsPlus = false
MaxNodes int32 = 0
NodeId int64 = 0
Debug = false
)

View File

@@ -0,0 +1,76 @@
package models
import (
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
timeutil "github.com/iwind/TeaGo/utils/time"
)
type APIMethodStatDAO dbs.DAO
func NewAPIMethodStatDAO() *APIMethodStatDAO {
return dbs.NewDAO(&APIMethodStatDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeAPIMethodStats",
Model: new(APIMethodStat),
PkName: "id",
},
}).(*APIMethodStatDAO)
}
var SharedAPIMethodStatDAO *APIMethodStatDAO
func init() {
dbs.OnReady(func() {
SharedAPIMethodStatDAO = NewAPIMethodStatDAO()
})
}
// CreateStat 记录统计数据
func (this *APIMethodStatDAO) CreateStat(tx *dbs.Tx, method string, tag string, costMs float64) error {
var day = timeutil.Format("Ymd")
return this.Query(tx).
Param("costMs", costMs).
InsertOrUpdateQuickly(map[string]interface{}{
"apiNodeId": teaconst.NodeId,
"method": method,
"tag": tag,
"costMs": costMs,
"peekMs": costMs,
"countCalls": 1,
"day": day,
}, map[string]interface{}{
"costMs": dbs.SQL("(costMs*countCalls+:costMs)/(countCalls+1)"),
"peekMs": dbs.SQL("IF(peekMs>:costMs, peekMs, :costMs)"),
"countCalls": dbs.SQL("countCalls+1"),
})
}
// FindAllStatsWithDay 查询当前统计
func (this *APIMethodStatDAO) FindAllStatsWithDay(tx *dbs.Tx, day string) (result []*APIMethodStat, err error) {
_, err = this.Query(tx).
Attr("day", day).
Slice(&result).
FindAll()
return
}
// CountAllStatsWithDay 统计当天数量
func (this *APIMethodStatDAO) CountAllStatsWithDay(tx *dbs.Tx, day string) (int64, error) {
return this.Query(tx).
Attr("day", day).
Count()
}
// Clean 清理数据
func (this *APIMethodStatDAO) Clean(tx *dbs.Tx) error {
var day = timeutil.Format("Ymd")
_, err := this.Query(tx).
Param("day", day).
Where("day<:day").
Delete()
return err
}

View File

@@ -0,0 +1,19 @@
package models
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/dbs"
"testing"
)
func TestAPIMethodStatDAO_CreateStat(t *testing.T) {
var dao = NewAPIMethodStatDAO()
var tx *dbs.Tx
err := dao.CreateStat(tx, "/pb.Hello/World", "tag", 1.123)
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}

View File

@@ -0,0 +1,28 @@
package models
// APIMethodStat API方法统计
type APIMethodStat struct {
Id uint64 `field:"id"` // ID
ApiNodeId uint32 `field:"apiNodeId"` // API节点ID
Method string `field:"method"` // 方法
Tag string `field:"tag"` // 标签方法
CostMs float64 `field:"costMs"` // 耗时Ms
PeekMs float64 `field:"peekMs"` // 峰值耗时
CountCalls uint64 `field:"countCalls"` // 调用次数
Day string `field:"day"` // 日期
}
type APIMethodStatOperator struct {
Id interface{} // ID
ApiNodeId interface{} // API节点ID
Method interface{} // 方法
Tag interface{} // 标签方法
CostMs interface{} // 耗时Ms
PeekMs interface{} // 峰值耗时
CountCalls interface{} // 调用次数
Day interface{} // 日期
}
func NewAPIMethodStatOperator() *APIMethodStatOperator {
return &APIMethodStatOperator{}
}

View File

@@ -0,0 +1 @@
package models

View File

@@ -62,7 +62,15 @@ func (this *APINodeDAO) DisableAPINode(tx *dbs.Tx, id int64) error {
}
// FindEnabledAPINode 查找启用中的条目
func (this *APINodeDAO) FindEnabledAPINode(tx *dbs.Tx, id int64) (*APINode, error) {
func (this *APINodeDAO) FindEnabledAPINode(tx *dbs.Tx, id int64, cacheMap *utils.CacheMap) (*APINode, error) {
var cacheKey = this.Table + ":FindEnabledAPINode:" + types.String(id)
if cacheMap != nil {
cache, ok := cacheMap.Get(cacheKey)
if ok {
return cache.(*APINode), nil
}
}
result, err := this.Query(tx).
Pk(id).
Attr("state", APINodeStateEnabled).
@@ -70,6 +78,11 @@ func (this *APINodeDAO) FindEnabledAPINode(tx *dbs.Tx, id int64) (*APINode, erro
if result == nil {
return nil, err
}
if cacheMap != nil {
cacheMap.Put(cacheKey, result)
}
return result.(*APINode), err
}

View File

@@ -1,6 +1,6 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build community
// +build community
//go:build !plus
// +build !plus
package authority

View File

@@ -53,7 +53,7 @@ func TestHTTPAccessLogDAO_ListAccessLogs(t *testing.T) {
t.Fatal(err)
}
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, "", 10, timeutil.Format("Ymd"), 0, false, false, 0, 0, 0, false, 0, "", "", "")
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, "", 10, timeutil.Format("Ymd"), 0, 0, 0, false, false, 0, 0, 0, false, 0, "", "", "")
if err != nil {
t.Fatal(err)
}
@@ -80,7 +80,7 @@ func TestHTTPAccessLogDAO_ListAccessLogs_Page(t *testing.T) {
times := 0 // 防止循环次数太多
for {
before := time.Now()
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, lastRequestId, 2, timeutil.Format("Ymd"), 0, false, false, 0, 0, 0, false, 0, "", "", "")
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, lastRequestId, 2, timeutil.Format("Ymd"), 0, 0, 0, false, false, 0, 0, 0, false, 0, "", "", "")
cost := time.Since(before).Seconds()
if err != nil {
t.Fatal(err)
@@ -111,7 +111,7 @@ func TestHTTPAccessLogDAO_ListAccessLogs_Reverse(t *testing.T) {
}
before := time.Now()
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, "16023261176446590001000000000000003500000004", 2, timeutil.Format("Ymd"), 0, true, false, 0, 0, 0, false, 0, "", "", "")
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, "16023261176446590001000000000000003500000004", 2, timeutil.Format("Ymd"), 0, 0, 0, true, false, 0, 0, 0, false, 0, "", "", "")
cost := time.Since(before).Seconds()
if err != nil {
t.Fatal(err)
@@ -136,7 +136,7 @@ func TestHTTPAccessLogDAO_ListAccessLogs_Page_NotExists(t *testing.T) {
times := 0 // 防止循环次数太多
for {
before := time.Now()
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, lastRequestId, 2, timeutil.Format("Ymd", time.Now().AddDate(0, 0, 1)), 0, false, false, 0, 0, 0, false, 0, "", "", "")
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, lastRequestId, 2, timeutil.Format("Ymd", time.Now().AddDate(0, 0, 1)), 0, 0, 0, false, false, 0, 0, 0, false, 0, "", "", "")
cost := time.Since(before).Seconds()
if err != nil {
t.Fatal(err)

View File

@@ -275,7 +275,7 @@ func (this *NodeClusterDAO) FindAllAPINodeAddrsWithCluster(tx *dbs.Tx, clusterId
return nil, err
}
for _, apiNodeId := range apiNodeIds {
apiNode, err := SharedAPINodeDAO.FindEnabledAPINode(tx, apiNodeId)
apiNode, err := SharedAPINodeDAO.FindEnabledAPINode(tx, apiNodeId, nil)
if err != nil {
return nil, err
}

View File

@@ -1,6 +1,7 @@
package nodes
import (
"context"
"crypto/tls"
"errors"
"fmt"
@@ -11,6 +12,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/events"
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeAPI/internal/rpc"
"github.com/TeaOSLab/EdgeAPI/internal/setup"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/go-yaml/yaml"
@@ -214,10 +216,10 @@ func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) err
var rpcServer *grpc.Server
if tlsConfig == nil {
remotelogs.Println("API_NODE", "listening GRPC http://"+listener.Addr().String()+" ...")
rpcServer = grpc.NewServer(grpc.MaxRecvMsgSize(128 * 1024 * 1024))
rpcServer = grpc.NewServer(grpc.MaxRecvMsgSize(128*1024*1024), grpc.UnaryInterceptor(this.unaryInterceptor))
} else {
logs.Println("[API_NODE]listening GRPC https://" + listener.Addr().String() + " ...")
rpcServer = grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsConfig)), grpc.MaxRecvMsgSize(128*1024*1024))
rpcServer = grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsConfig)), grpc.MaxRecvMsgSize(128*1024*1024), grpc.UnaryInterceptor(this.unaryInterceptor))
}
this.registerServices(rpcServer)
err := rpcServer.Serve(listener)
@@ -572,6 +574,11 @@ func (this *APINode) listenSock() error {
"result": result,
},
})
case "debug":
teaconst.Debug = !teaconst.Debug
_ = cmd.Reply(&gosock.Command{
Params: map[string]interface{}{"debug": teaconst.Debug},
})
}
})
@@ -588,3 +595,29 @@ func (this *APINode) listenSock() error {
return nil
}
// 服务过滤器
func (this *APINode) unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
if teaconst.Debug {
var before = time.Now()
var traceCtx = rpc.NewContext(ctx)
resp, err = handler(traceCtx, req)
var costMs = time.Since(before).Seconds() * 1000
statErr := models.SharedAPIMethodStatDAO.CreateStat(nil, info.FullMethod, "", costMs)
if statErr != nil {
remotelogs.Error("API_NODE", "create method stat failed: "+statErr.Error())
}
var tagMap = traceCtx.TagMap()
for tag, tagCostMs := range tagMap {
statErr = models.SharedAPIMethodStatDAO.CreateStat(nil, info.FullMethod, tag, tagCostMs)
if statErr != nil {
remotelogs.Error("API_NODE", "create method stat failed: "+statErr.Error())
}
}
return
}
return handler(ctx, req)
}

View File

@@ -63,6 +63,11 @@ func (this *APINode) registerServices(server *grpc.Server) {
pb.RegisterAPINodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.APIMethodStatService{}).(*services.APIMethodStatService)
pb.RegisterAPIMethodStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.OriginService{}).(*services.OriginService)
pb.RegisterOriginServiceServer(server, instance)

View File

@@ -1,5 +1,6 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
// +build community
//go:build !plus
// +build !plus
package nodes

46
internal/rpc/context.go Normal file
View File

@@ -0,0 +1,46 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package rpc
import (
"context"
"sync"
"time"
)
type Context struct {
context.Context
tagMap map[string]time.Time
costMap map[string]float64 // tag => costMs
locker sync.Mutex
}
func NewContext(ctx context.Context) *Context {
return &Context{
Context: ctx,
tagMap: map[string]time.Time{},
costMap: map[string]float64{},
}
}
func (this *Context) Begin(tag string) {
this.locker.Lock()
this.tagMap[tag] = time.Now()
this.locker.Unlock()
}
func (this *Context) End(tag string) {
this.locker.Lock()
begin, ok := this.tagMap[tag]
if ok {
this.costMap[tag] = time.Since(begin).Seconds() * 1000
}
this.locker.Unlock()
}
func (this *Context) TagMap() map[string]float64 {
this.locker.Lock()
defer this.locker.Unlock()
return this.costMap
}

View File

@@ -477,7 +477,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
var tx = this.NullTx()
// 默认集群
this.BeginTag(ctx, "SharedNodeClusterDAO.ListEnabledClusters")
nodeClusters, err := models.SharedNodeClusterDAO.ListEnabledClusters(tx, "", 0, 1)
this.EndTag(ctx, "SharedNodeClusterDAO.ListEnabledClusters")
if err != nil {
return nil, err
}
@@ -486,84 +488,108 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
}
// 集群数
this.BeginTag(ctx, "SharedNodeClusterDAO.CountAllEnabledClusters")
countClusters, err := models.SharedNodeClusterDAO.CountAllEnabledClusters(tx, "")
this.EndTag(ctx, "SharedNodeClusterDAO.CountAllEnabledClusters")
if err != nil {
return nil, err
}
result.CountNodeClusters = countClusters
// 节点数
this.BeginTag(ctx, "SharedNodeDAO.CountAllEnabledNodes")
countNodes, err := models.SharedNodeDAO.CountAllEnabledNodes(tx)
this.EndTag(ctx, "SharedNodeDAO.CountAllEnabledNodes")
if err != nil {
return nil, err
}
result.CountNodes = countNodes
// 离线节点
this.BeginTag(ctx, "SharedNodeDAO.CountAllEnabledOfflineNodes")
countOfflineNodes, err := models.SharedNodeDAO.CountAllEnabledOfflineNodes(tx)
this.EndTag(ctx, "SharedNodeDAO.CountAllEnabledOfflineNodes")
if err != nil {
return nil, err
}
result.CountOfflineNodes = countOfflineNodes
// 服务数
this.BeginTag(ctx, "SharedServerDAO.CountAllEnabledServers")
countServers, err := models.SharedServerDAO.CountAllEnabledServers(tx)
this.EndTag(ctx, "SharedServerDAO.CountAllEnabledServers")
if err != nil {
return nil, err
}
result.CountServers = countServers
this.BeginTag(ctx, "SharedServerDAO.CountAllEnabledServersMatch")
countAuditingServers, err := models.SharedServerDAO.CountAllEnabledServersMatch(tx, 0, "", 0, 0, configutils.BoolStateYes, nil)
this.EndTag(ctx, "SharedServerDAO.CountAllEnabledServersMatch")
if err != nil {
return nil, err
}
result.CountAuditingServers = countAuditingServers
// 用户数
this.BeginTag(ctx, "SharedUserDAO.CountAllEnabledUsers")
countUsers, err := models.SharedUserDAO.CountAllEnabledUsers(tx, 0, "", false)
this.EndTag(ctx, "SharedUserDAO.CountAllEnabledUsers")
if err != nil {
return nil, err
}
result.CountUsers = countUsers
// API节点数
this.BeginTag(ctx, "SharedAPINodeDAO.CountAllEnabledAndOnAPINodes")
countAPINodes, err := models.SharedAPINodeDAO.CountAllEnabledAndOnAPINodes(tx)
this.EndTag(ctx, "SharedAPINodeDAO.CountAllEnabledAndOnAPINodes")
if err != nil {
return nil, err
}
result.CountAPINodes = countAPINodes
// 离线API节点
this.BeginTag(ctx, "SharedAPINodeDAO.CountAllEnabledAndOnOfflineAPINodes")
countOfflineAPINodes, err := models.SharedAPINodeDAO.CountAllEnabledAndOnOfflineAPINodes(tx)
this.EndTag(ctx, "SharedAPINodeDAO.CountAllEnabledAndOnOfflineAPINodes")
if err != nil {
return nil, err
}
result.CountOfflineAPINodes = countOfflineAPINodes
// 数据库节点数
this.BeginTag(ctx, "SharedDBNodeDAO.CountAllEnabledNodes")
countDBNodes, err := models.SharedDBNodeDAO.CountAllEnabledNodes(tx)
this.EndTag(ctx, "SharedDBNodeDAO.CountAllEnabledNodes")
if err != nil {
return nil, err
}
result.CountDBNodes = countDBNodes
// 用户节点数
this.BeginTag(ctx, "SharedUserNodeDAO.CountAllEnabledAndOnUserNodes")
countUserNodes, err := models.SharedUserNodeDAO.CountAllEnabledAndOnUserNodes(tx)
this.EndTag(ctx, "SharedUserNodeDAO.CountAllEnabledAndOnUserNodes")
if err != nil {
return nil, err
}
result.CountUserNodes = countUserNodes
// 离线用户节点数
this.BeginTag(ctx, "SharedUserNodeDAO.CountAllEnabledAndOnOfflineNodes")
countOfflineUserNodes, err := models.SharedUserNodeDAO.CountAllEnabledAndOnOfflineNodes(tx)
this.EndTag(ctx, "SharedUserNodeDAO.CountAllEnabledAndOnOfflineNodes")
if err != nil {
return nil, err
}
result.CountOfflineUserNodes = countOfflineUserNodes
// 按日流量统计
this.BeginTag(ctx, "SharedTrafficDailyStatDAO.FindDailyStats")
dayFrom := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
dailyTrafficStats, err := stats.SharedTrafficDailyStatDAO.FindDailyStats(tx, dayFrom, timeutil.Format("Ymd"))
this.EndTag(ctx, "SharedTrafficDailyStatDAO.FindDailyStats")
if err != nil {
return nil, err
}
@@ -582,7 +608,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
// 小时流量统计
hourFrom := timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
hourTo := timeutil.Format("YmdH")
this.BeginTag(ctx, "SharedTrafficHourlyStatDAO.FindHourlyStats")
hourlyTrafficStats, err := stats.SharedTrafficHourlyStatDAO.FindHourlyStats(tx, hourFrom, hourTo)
this.EndTag(ctx, "SharedTrafficHourlyStatDAO.FindHourlyStats")
if err != nil {
return nil, err
}
@@ -609,7 +637,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
upgradeInfo := &pb.ComposeAdminDashboardResponse_UpgradeInfo{
NewVersion: teaconst.NodeVersion,
}
this.BeginTag(ctx, "SharedNodeDAO.CountAllLowerVersionNodes")
countNodes, err := models.SharedNodeDAO.CountAllLowerVersionNodes(tx, upgradeInfo.NewVersion)
this.EndTag(ctx, "SharedNodeDAO.CountAllLowerVersionNodes")
if err != nil {
return nil, err
}
@@ -622,7 +652,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
upgradeInfo := &pb.ComposeAdminDashboardResponse_UpgradeInfo{
NewVersion: teaconst.MonitorNodeVersion,
}
this.BeginTag(ctx, "SharedMonitorNodeDAO.CountAllLowerVersionNodes")
countNodes, err := models.SharedMonitorNodeDAO.CountAllLowerVersionNodes(tx, upgradeInfo.NewVersion)
this.EndTag(ctx, "SharedMonitorNodeDAO.CountAllLowerVersionNodes")
if err != nil {
return nil, err
}
@@ -635,7 +667,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
upgradeInfo := &pb.ComposeAdminDashboardResponse_UpgradeInfo{
NewVersion: teaconst.AuthorityNodeVersion,
}
this.BeginTag(ctx, "SharedAuthorityNodeDAO.CountAllLowerVersionNodes")
countNodes, err := authority.SharedAuthorityNodeDAO.CountAllLowerVersionNodes(tx, upgradeInfo.NewVersion)
this.EndTag(ctx, "SharedAuthorityNodeDAO.CountAllLowerVersionNodes")
if err != nil {
return nil, err
}
@@ -648,7 +682,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
upgradeInfo := &pb.ComposeAdminDashboardResponse_UpgradeInfo{
NewVersion: teaconst.UserNodeVersion,
}
this.BeginTag(ctx, "SharedUserNodeDAO.CountAllLowerVersionNodes")
countNodes, err := models.SharedUserNodeDAO.CountAllLowerVersionNodes(tx, upgradeInfo.NewVersion)
this.EndTag(ctx, "SharedUserNodeDAO.CountAllLowerVersionNodes")
if err != nil {
return nil, err
}
@@ -665,7 +701,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
upgradeInfo := &pb.ComposeAdminDashboardResponse_UpgradeInfo{
NewVersion: apiVersion,
}
this.BeginTag(ctx, "SharedAPINodeDAO.CountAllLowerVersionNodes")
countNodes, err := models.SharedAPINodeDAO.CountAllLowerVersionNodes(tx, upgradeInfo.NewVersion)
this.EndTag(ctx, "SharedAPINodeDAO.CountAllLowerVersionNodes")
if err != nil {
return nil, err
}
@@ -678,7 +716,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
upgradeInfo := &pb.ComposeAdminDashboardResponse_UpgradeInfo{
NewVersion: teaconst.DNSNodeVersion,
}
this.BeginTag(ctx, "SharedNSNodeDAO.CountAllLowerVersionNodes")
countNodes, err := models.SharedNSNodeDAO.CountAllLowerVersionNodes(tx, upgradeInfo.NewVersion)
this.EndTag(ctx, "SharedNSNodeDAO.CountAllLowerVersionNodes")
if err != nil {
return nil, err
}
@@ -691,7 +731,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
upgradeInfo := &pb.ComposeAdminDashboardResponse_UpgradeInfo{
NewVersion: teaconst.ReportNodeVersion,
}
this.BeginTag(ctx, "SharedReportNodeDAO.CountAllLowerVersionNodes")
countNodes, err := models.SharedReportNodeDAO.CountAllLowerVersionNodes(tx, upgradeInfo.NewVersion)
this.EndTag(ctx, "SharedReportNodeDAO.CountAllLowerVersionNodes")
if err != nil {
return nil, err
}
@@ -700,7 +742,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
}
// 域名排行
this.BeginTag(ctx, "SharedServerDomainHourlyStatDAO.FindTopDomainStats")
topDomainStats, err := stats.SharedServerDomainHourlyStatDAO.FindTopDomainStats(tx, hourFrom, hourTo, 10)
this.EndTag(ctx, "SharedServerDomainHourlyStatDAO.FindTopDomainStats")
if err != nil {
return nil, err
}
@@ -715,7 +759,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
// 节点排行
if isPlus {
this.BeginTag(ctx, "SharedNodeTrafficHourlyStatDAO.FindTopNodeStats")
topNodeStats, err := stats.SharedNodeTrafficHourlyStatDAO.FindTopNodeStats(tx, "node", hourFrom, hourTo, 10)
this.EndTag(ctx, "SharedNodeTrafficHourlyStatDAO.FindTopNodeStats")
if err != nil {
return nil, err
}
@@ -738,7 +784,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
// 地区流量排行
if isPlus {
this.BeginTag(ctx, "SharedServerRegionCountryDailyStatDAO.SumDailyTotalBytes")
totalCountryBytes, err := stats.SharedServerRegionCountryDailyStatDAO.SumDailyTotalBytes(tx, timeutil.Format("Ymd"))
this.EndTag(ctx, "SharedServerRegionCountryDailyStatDAO.SumDailyTotalBytes")
if err != nil {
return nil, err
}
@@ -767,7 +815,9 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
}
// 指标数据
this.BeginTag(ctx, "findMetricDataCharts")
pbCharts, err := this.findMetricDataCharts(tx)
this.EndTag(ctx, "findMetricDataCharts")
if err != nil {
return nil, err
}

View File

@@ -0,0 +1,83 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package services
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
timeutil "github.com/iwind/TeaGo/utils/time"
)
// APIMethodStatService API方法统计服务
type APIMethodStatService struct {
BaseService
}
// FindAPIMethodStatsWithDay 查找某天的统计
func (this *APIMethodStatService) FindAPIMethodStatsWithDay(ctx context.Context, req *pb.FindAPIMethodStatsWithDayRequest) (*pb.FindAPIMethodStatsWithDayResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var day = req.Day
if len(day) == 0 {
day = timeutil.Format("Ymd")
}
var tx = this.NullTx()
stats, err := models.SharedAPIMethodStatDAO.FindAllStatsWithDay(tx, day)
if err != nil {
return nil, err
}
var pbStats = []*pb.APIMethodStat{}
var cacheMap = utils.NewCacheMap()
for _, stat := range stats {
apiNode, err := models.SharedAPINodeDAO.FindEnabledAPINode(tx, int64(stat.ApiNodeId), cacheMap)
if err != nil {
return nil, err
}
if apiNode == nil {
continue
}
pbStats = append(pbStats, &pb.APIMethodStat{
Id: int64(stat.Id),
ApiNodeId: int64(stat.ApiNodeId),
Method: stat.Method,
Tag: stat.Tag,
CostMs: float32(stat.CostMs),
PeekMs: float32(stat.PeekMs),
CountCalls: int64(stat.CountCalls),
ApiNode: &pb.APINode{
Id: int64(apiNode.Id),
Name: apiNode.Name,
},
})
}
return &pb.FindAPIMethodStatsWithDayResponse{
ApiMethodStats: pbStats,
}, nil
}
// CountAPIMethodStatsWithDay 检查是否有统计数据
func (this *APIMethodStatService) CountAPIMethodStatsWithDay(ctx context.Context, req *pb.CountAPIMethodStatsWithDayRequest) (*pb.RPCCountResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var day = req.Day
if len(day) == 0 {
day = timeutil.Format("Ymd")
}
var tx = this.NullTx()
count, err := models.SharedAPIMethodStatDAO.CountAllStatsWithDay(tx, day)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}

View File

@@ -189,7 +189,7 @@ func (this *APINodeService) FindEnabledAPINode(ctx context.Context, req *pb.Find
tx := this.NullTx()
node, err := models.SharedAPINodeDAO.FindEnabledAPINode(tx, req.ApiNodeId)
node, err := models.SharedAPINodeDAO.FindEnabledAPINode(tx, req.ApiNodeId, nil)
if err != nil {
return nil, err
}
@@ -241,7 +241,7 @@ func (this *APINodeService) FindCurrentAPINode(ctx context.Context, req *pb.Find
var nodeId = teaconst.NodeId
var tx *dbs.Tx
node, err := models.SharedAPINodeDAO.FindEnabledAPINode(tx, nodeId)
node, err := models.SharedAPINodeDAO.FindEnabledAPINode(tx, nodeId, nil)
if err != nil {
return nil, err
}
@@ -295,3 +295,14 @@ func (this *APINodeService) CountAllEnabledAPINodesWithSSLCertId(ctx context.Con
}
return this.SuccessCount(count)
}
// DebugAPINode 修改调试模式状态
func (this *APINodeService) DebugAPINode(ctx context.Context, req *pb.DebugAPINodeRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
teaconst.Debug = req.Debug
return this.Success()
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models/authority"
"github.com/TeaOSLab/EdgeAPI/internal/encrypt"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/rpc"
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -236,3 +237,25 @@ func (this *BaseService) RunTx(callback func(tx *dbs.Tx) error) error {
}
return db.RunTx(callback)
}
// BeginTag 开始标签统计
func (this *BaseService) BeginTag(ctx context.Context, name string) {
if !teaconst.Debug {
return
}
traceCtx, ok := ctx.(*rpc.Context)
if ok {
traceCtx.Begin(name)
}
}
// EndTag 结束标签统计
func (this *BaseService) EndTag(ctx context.Context, name string) {
if !teaconst.Debug {
return
}
traceCtx, ok := ctx.(*rpc.Context)
if ok {
traceCtx.End(name)
}
}

View File

@@ -197,7 +197,7 @@ func (this *NodeClusterService) FindAPINodesWithNodeCluster(ctx context.Context,
if len(apiNodeIds) > 0 {
apiNodes := []*pb.APINode{}
for _, apiNodeId := range apiNodeIds {
apiNode, err := models.SharedAPINodeDAO.FindEnabledAPINode(tx, apiNodeId)
apiNode, err := models.SharedAPINodeDAO.FindEnabledAPINode(tx, apiNodeId, nil)
if err != nil {
return nil, err
}

View File

@@ -1,6 +1,6 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build community
// +build community
//go:build !plus
// +build !plus
package services

View File

@@ -1,6 +1,6 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build community
// +build community
//go:build !plus
// +build !plus
package services

View File

@@ -167,7 +167,7 @@ func (this *Setup) Run() error {
apiNodeId = nodeId
}
apiNode, err := dao.FindEnabledAPINode(nil, apiNodeId)
apiNode, err := dao.FindEnabledAPINode(nil, apiNodeId, nil)
if err != nil {
return err
}