325 lines
9.5 KiB
Go
325 lines
9.5 KiB
Go
package httpdns
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/TeaOSLab/EdgeAPI/internal/clickhouse"
|
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
"github.com/iwind/TeaGo/dbs"
|
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
|
)
|
|
|
|
// HTTPDNSBoardService HTTPDNS 仪表盘服务
|
|
type HTTPDNSBoardService struct {
|
|
services.BaseService
|
|
}
|
|
|
|
// ComposeHTTPDNSBoard 组合看板数据
|
|
func (this *HTTPDNSBoardService) ComposeHTTPDNSBoard(ctx context.Context, req *pb.ComposeHTTPDNSBoardRequest) (*pb.ComposeHTTPDNSBoardResponse, error) {
|
|
_, err := this.ValidateAdmin(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tx := this.NullTx()
|
|
result := &pb.ComposeHTTPDNSBoardResponse{}
|
|
|
|
countApps, err := models.SharedHTTPDNSAppDAO.CountEnabledApps(tx, "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result.CountApps = countApps
|
|
|
|
countDomains, err := models.SharedHTTPDNSDomainDAO.CountEnabledDomains(tx, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result.CountDomains = countDomains
|
|
|
|
countClusters, err := models.SharedHTTPDNSClusterDAO.CountEnabledClusters(tx, "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result.CountClusters = countClusters
|
|
|
|
allNodes, err := models.SharedHTTPDNSNodeDAO.ListEnabledNodes(tx, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result.CountNodes = int64(len(allNodes))
|
|
|
|
var countOffline int64
|
|
for _, node := range allNodes {
|
|
if !node.IsActive {
|
|
countOffline++
|
|
}
|
|
}
|
|
result.CountOfflineNodes = countOffline
|
|
|
|
hourFrom := timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
|
|
hourTo := timeutil.Format("YmdH")
|
|
dayFrom := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
|
|
dayTo := timeutil.Format("Ymd")
|
|
todayFrom := timeutil.Format("Ymd", time.Now().Add(-24*time.Hour))
|
|
|
|
store := clickhouse.NewHTTPDNSAccessLogsStore()
|
|
if store.Client().IsConfigured() {
|
|
err = this.composeTrafficAndRanksFromClickHouse(ctx, tx, store, result, hourFrom, hourTo, dayFrom, dayTo, todayFrom)
|
|
}
|
|
if err != nil || !store.Client().IsConfigured() {
|
|
err = this.composeTrafficAndRanksFromMySQL(tx, result, hourFrom, hourTo, dayFrom, dayTo, todayFrom)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
err = this.fillNodeValues(tx, result)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (this *HTTPDNSBoardService) composeTrafficAndRanksFromClickHouse(ctx context.Context, tx *dbs.Tx, store *clickhouse.HTTPDNSAccessLogsStore, result *pb.ComposeHTTPDNSBoardResponse, hourFrom string, hourTo string, dayFrom string, dayTo string, todayFrom string) error {
|
|
hourlyStats, err := store.FindHourlyStats(ctx, hourFrom, hourTo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
hourlyMap := map[string]*clickhouse.HTTPDNSAccessLogHourlyStat{}
|
|
for _, stat := range hourlyStats {
|
|
hourlyMap[stat.Hour] = stat
|
|
}
|
|
hours, err := utils.RangeHours(hourFrom, hourTo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, hour := range hours {
|
|
stat, ok := hourlyMap[hour]
|
|
if ok {
|
|
result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_HourlyTrafficStat{
|
|
Hour: hour,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
} else {
|
|
result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_HourlyTrafficStat{Hour: hour})
|
|
}
|
|
}
|
|
|
|
dailyStats, err := store.FindDailyStats(ctx, dayFrom, dayTo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
dailyMap := map[string]*clickhouse.HTTPDNSAccessLogDailyStat{}
|
|
for _, stat := range dailyStats {
|
|
dailyMap[stat.Day] = stat
|
|
}
|
|
days, err := utils.RangeDays(dayFrom, dayTo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, day := range days {
|
|
stat, ok := dailyMap[day]
|
|
if ok {
|
|
result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_DailyTrafficStat{
|
|
Day: day,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
} else {
|
|
result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_DailyTrafficStat{Day: day})
|
|
}
|
|
}
|
|
|
|
topAppStats, err := store.ListTopApps(ctx, todayFrom, dayTo, 10)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, stat := range topAppStats {
|
|
appName := stat.AppName
|
|
if len(appName) == 0 {
|
|
appName = stat.AppId
|
|
}
|
|
result.TopAppStats = append(result.TopAppStats, &pb.ComposeHTTPDNSBoardResponse_TopAppStat{
|
|
AppId: 0,
|
|
AppName: appName,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
}
|
|
|
|
topDomainStats, err := store.ListTopDomains(ctx, todayFrom, dayTo, 10)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, stat := range topDomainStats {
|
|
result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeHTTPDNSBoardResponse_TopDomainStat{
|
|
DomainName: stat.Domain,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
}
|
|
|
|
topNodeStats, err := store.ListTopNodes(ctx, todayFrom, dayTo, 10)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, stat := range topNodeStats {
|
|
nodeName := ""
|
|
node, nodeErr := models.SharedHTTPDNSNodeDAO.FindEnabledNode(tx, int64(stat.NodeId))
|
|
if nodeErr == nil && node != nil {
|
|
nodeName = node.Name
|
|
}
|
|
if len(nodeName) == 0 {
|
|
continue
|
|
}
|
|
result.TopNodeStats = append(result.TopNodeStats, &pb.ComposeHTTPDNSBoardResponse_TopNodeStat{
|
|
ClusterId: int64(stat.ClusterId),
|
|
NodeId: int64(stat.NodeId),
|
|
NodeName: nodeName,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (this *HTTPDNSBoardService) composeTrafficAndRanksFromMySQL(tx *dbs.Tx, result *pb.ComposeHTTPDNSBoardResponse, hourFrom string, hourTo string, dayFrom string, dayTo string, todayFrom string) error {
|
|
hourlyStats, err := models.SharedHTTPDNSAccessLogDAO.FindHourlyStats(tx, hourFrom, hourTo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
hourlyMap := map[string]*models.HTTPDNSAccessLogHourlyStat{}
|
|
for _, stat := range hourlyStats {
|
|
hourlyMap[stat.Hour] = stat
|
|
}
|
|
hours, err := utils.RangeHours(hourFrom, hourTo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, hour := range hours {
|
|
stat, ok := hourlyMap[hour]
|
|
if ok {
|
|
result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_HourlyTrafficStat{
|
|
Hour: hour,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
} else {
|
|
result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_HourlyTrafficStat{Hour: hour})
|
|
}
|
|
}
|
|
|
|
dailyStats, err := models.SharedHTTPDNSAccessLogDAO.FindDailyStats(tx, dayFrom, dayTo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
dailyMap := map[string]*models.HTTPDNSAccessLogDailyStat{}
|
|
for _, stat := range dailyStats {
|
|
dailyMap[stat.Day] = stat
|
|
}
|
|
days, err := utils.RangeDays(dayFrom, dayTo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, day := range days {
|
|
stat, ok := dailyMap[day]
|
|
if ok {
|
|
result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_DailyTrafficStat{
|
|
Day: day,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
} else {
|
|
result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_DailyTrafficStat{Day: day})
|
|
}
|
|
}
|
|
|
|
topAppStats, err := models.SharedHTTPDNSAccessLogDAO.ListTopApps(tx, todayFrom, dayTo, 10)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, stat := range topAppStats {
|
|
appName := stat.AppName
|
|
if len(appName) == 0 {
|
|
appName = stat.AppId
|
|
}
|
|
result.TopAppStats = append(result.TopAppStats, &pb.ComposeHTTPDNSBoardResponse_TopAppStat{
|
|
AppId: 0,
|
|
AppName: appName,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
}
|
|
|
|
topDomainStats, err := models.SharedHTTPDNSAccessLogDAO.ListTopDomains(tx, todayFrom, dayTo, 10)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, stat := range topDomainStats {
|
|
result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeHTTPDNSBoardResponse_TopDomainStat{
|
|
DomainName: stat.Domain,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
}
|
|
|
|
topNodeStats, err := models.SharedHTTPDNSAccessLogDAO.ListTopNodes(tx, todayFrom, dayTo, 10)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, stat := range topNodeStats {
|
|
nodeName := ""
|
|
node, nodeErr := models.SharedHTTPDNSNodeDAO.FindEnabledNode(tx, int64(stat.NodeId))
|
|
if nodeErr == nil && node != nil {
|
|
nodeName = node.Name
|
|
}
|
|
if len(nodeName) == 0 {
|
|
continue
|
|
}
|
|
result.TopNodeStats = append(result.TopNodeStats, &pb.ComposeHTTPDNSBoardResponse_TopNodeStat{
|
|
ClusterId: int64(stat.ClusterId),
|
|
NodeId: int64(stat.NodeId),
|
|
NodeName: nodeName,
|
|
CountRequests: stat.CountRequests,
|
|
})
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (this *HTTPDNSBoardService) fillNodeValues(tx *dbs.Tx, result *pb.ComposeHTTPDNSBoardResponse) error {
|
|
cpuValues, err := models.SharedNodeValueDAO.ListValuesForHTTPDNSNodes(tx, nodeconfigs.NodeValueItemCPU, "usage", nodeconfigs.NodeValueRangeMinute)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, v := range cpuValues {
|
|
result.CpuNodeValues = append(result.CpuNodeValues, &pb.NodeValue{
|
|
ValueJSON: v.Value,
|
|
CreatedAt: int64(v.CreatedAt),
|
|
})
|
|
}
|
|
|
|
memoryValues, err := models.SharedNodeValueDAO.ListValuesForHTTPDNSNodes(tx, nodeconfigs.NodeValueItemMemory, "usage", nodeconfigs.NodeValueRangeMinute)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, v := range memoryValues {
|
|
result.MemoryNodeValues = append(result.MemoryNodeValues, &pb.NodeValue{
|
|
ValueJSON: v.Value,
|
|
CreatedAt: int64(v.CreatedAt),
|
|
})
|
|
}
|
|
|
|
loadValues, err := models.SharedNodeValueDAO.ListValuesForHTTPDNSNodes(tx, nodeconfigs.NodeValueItemLoad, "load1m", nodeconfigs.NodeValueRangeMinute)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, v := range loadValues {
|
|
result.LoadNodeValues = append(result.LoadNodeValues, &pb.NodeValue{
|
|
ValueJSON: v.Value,
|
|
CreatedAt: int64(v.CreatedAt),
|
|
})
|
|
}
|
|
|
|
return nil
|
|
}
|