diff --git a/internal/db/models/stats/node_traffic_hourly_stat_dao.go b/internal/db/models/stats/node_traffic_hourly_stat_dao.go index 373bf93d..ad5ec827 100644 --- a/internal/db/models/stats/node_traffic_hourly_stat_dao.go +++ b/internal/db/models/stats/node_traffic_hourly_stat_dao.go @@ -132,6 +132,22 @@ func (this *NodeTrafficHourlyStatDAO) FindTopNodeStats(tx *dbs.Tx, role string, return } +// FindTopNodeStatsWithAttack 取得防火墙相关的节点排行数据 +func (this *NodeTrafficHourlyStatDAO) FindTopNodeStatsWithAttack(tx *dbs.Tx, role string, hourFrom string, hourTo string, size int64) (result []*NodeTrafficHourlyStat, err error) { + // TODO 节点如果已经被删除,则忽略 + _, err = this.Query(tx). + Attr("role", role). + Gt("countAttackRequests", 0). + Between("hour", hourFrom, hourTo). + Result("nodeId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes"). + Group("nodeId"). + Desc("countRequests"). + Limit(size). + Slice(&result). + FindAll() + return +} + // FindTopNodeStatsWithClusterId 取得集群一定时间内的节点排行数据 func (this *NodeTrafficHourlyStatDAO) FindTopNodeStatsWithClusterId(tx *dbs.Tx, role string, clusterId int64, hourFrom string, hourTo string, size int64) (result []*NodeTrafficHourlyStat, err error) { // TODO 节点如果已经被删除,则忽略 diff --git a/internal/db/models/stats/server_domain_hourly_stat_dao.go b/internal/db/models/stats/server_domain_hourly_stat_dao.go index 48ffd79b..52100090 100644 --- a/internal/db/models/stats/server_domain_hourly_stat_dao.go +++ b/internal/db/models/stats/server_domain_hourly_stat_dao.go @@ -166,6 +166,55 @@ func (this *ServerDomainHourlyStatDAO) FindTopDomainStats(tx *dbs.Tx, hourFrom s return } +// FindTopDomainStatsWithAttack 取得一定时间内的域名排行数据 +func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithAttack(tx *dbs.Tx, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, resultErr error) { + var tables = this.FindAllPartitionTables() + var wg = sync.WaitGroup{} + wg.Add(len(tables)) + var locker = sync.Mutex{} + + for _, table := range tables { + go func(table string) { + defer wg.Done() + + var topResults = []*ServerDomainHourlyStat{} + + // TODO 节点如果已经被删除,则忽略 + _, err := this.Query(tx). + Table(table). + Gt("countAttackRequests", 0). + Between("hour", hourFrom, hourTo). + Result("domain, MIN(serverId) AS serverId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes"). + Group("domain"). + Desc("countRequests"). + Limit(size). + Slice(&topResults). + FindAll() + if err != nil { + resultErr = err + return + } + + if len(topResults) > 0 { + locker.Lock() + result = append(result, topResults...) + locker.Unlock() + } + }(table) + } + wg.Wait() + + sort.Slice(result, func(i, j int) bool { + return result[i].CountRequests > result[j].CountRequests + }) + + if len(result) > types.Int(size) { + result = result[:types.Int(size)] + } + + return +} + // FindTopDomainStatsWithClusterId 取得集群上的一定时间内的域名排行数据 func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithClusterId(tx *dbs.Tx, clusterId int64, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, resultErr error) { var tables = this.FindAllPartitionTables() diff --git a/internal/rpc/services/service_firewall.go b/internal/rpc/services/service_firewall.go index 48e43480..cbdd5812 100644 --- a/internal/rpc/services/service_firewall.go +++ b/internal/rpc/services/service_firewall.go @@ -176,6 +176,45 @@ func (this *FirewallService) ComposeFirewallGlobalBoard(ctx context.Context, req }) } + // 节点排行 + topNodeStats, err := stats.SharedNodeTrafficHourlyStatDAO.FindTopNodeStatsWithAttack(tx, "node", hourFrom, hourTo, 10) + if err != nil { + return nil, err + } + for _, stat := range topNodeStats { + nodeName, err := models.SharedNodeDAO.FindNodeName(tx, int64(stat.NodeId)) + if err != nil { + return nil, err + } + if len(nodeName) == 0 { + continue + } + result.TopNodeStats = append(result.TopNodeStats, &pb.ComposeFirewallGlobalBoardResponse_NodeStat{ + NodeId: int64(stat.NodeId), + NodeName: nodeName, + CountRequests: int64(stat.CountRequests), + Bytes: int64(stat.Bytes), + CountAttackRequests: int64(stat.CountAttackRequests), + AttackBytes: int64(stat.AttackBytes), + }) + } + + // 域名排行 + topDomainStats, err := stats.SharedServerDomainHourlyStatDAO.FindTopDomainStatsWithAttack(tx, hourFrom, hourTo, 10) + if err != nil { + return nil, err + } + for _, stat := range topDomainStats { + result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeFirewallGlobalBoardResponse_DomainStat{ + ServerId: int64(stat.ServerId), + Domain: stat.Domain, + CountRequests: int64(stat.CountRequests), + Bytes: int64(stat.Bytes), + CountAttackRequests: int64(stat.CountAttackRequests), + AttackBytes: int64(stat.AttackBytes), + }) + } + return result, nil }