diff --git a/internal/db/models/metric_item_dao.go b/internal/db/models/metric_item_dao.go index faf03514..d56a7959 100644 --- a/internal/db/models/metric_item_dao.go +++ b/internal/db/models/metric_item_dao.go @@ -49,7 +49,15 @@ func (this *MetricItemDAO) EnableMetricItem(tx *dbs.Tx, id int64) error { // DisableMetricItem 禁用条目 func (this *MetricItemDAO) DisableMetricItem(tx *dbs.Tx, itemId int64) error { - _, err := this.Query(tx). + isPublic, err := this.Query(tx). + Pk(itemId). + Result("isPublic"). + FindIntCol(0) + if err != nil { + return err + } + + _, err = this.Query(tx). Pk(itemId). Set("state", MetricItemStateDisabled). Update() @@ -58,7 +66,7 @@ func (this *MetricItemDAO) DisableMetricItem(tx *dbs.Tx, itemId int64) error { } // 通知更新 - err = this.NotifyUpdate(tx, itemId) + err = this.NotifyUpdate(tx, itemId, isPublic == 1) if err != nil { return err } @@ -92,7 +100,7 @@ func (this *MetricItemDAO) FindMetricItemName(tx *dbs.Tx, id int64) (string, err } // CreateItem 创建指标 -func (this *MetricItemDAO) CreateItem(tx *dbs.Tx, code string, category string, name string, keys []string, period int32, periodUnit string, value string) (int64, error) { +func (this *MetricItemDAO) CreateItem(tx *dbs.Tx, code string, category string, name string, keys []string, period int32, periodUnit string, value string, isPublic bool) (int64, error) { sort.Strings(keys) op := NewMetricItemOperator() @@ -111,13 +119,26 @@ func (this *MetricItemDAO) CreateItem(tx *dbs.Tx, code string, category string, op.Period = period op.PeriodUnit = periodUnit op.Value = value + op.IsPublic = isPublic op.IsOn = true op.State = MetricItemStateEnabled - return this.SaveInt64(tx, op) + itemId, err := this.SaveInt64(tx, op) + if err != nil { + return 0, err + } + + if isPublic { + err = this.NotifyUpdate(tx, itemId, isPublic) + if err != nil { + return 0, err + } + } + + return itemId, nil } // UpdateItem 修改\指标 -func (this *MetricItemDAO) UpdateItem(tx *dbs.Tx, itemId int64, name string, keys []string, period int32, periodUnit string, value string, isOn bool) error { +func (this *MetricItemDAO) UpdateItem(tx *dbs.Tx, itemId int64, name string, keys []string, period int32, periodUnit string, value string, isOn bool, isPublic bool) error { if itemId <= 0 { return errors.New("invalid itemId") } @@ -132,6 +153,7 @@ func (this *MetricItemDAO) UpdateItem(tx *dbs.Tx, itemId int64, name string, key if oldItem == nil { return nil } + oldIsPublic := oldItem.IsPublic == 1 var versionChanged = false if strings.Join(oldItem.DecodeKeys(), "&") != strings.Join(keys, "&") || types.Int32(oldItem.Period) != period || oldItem.PeriodUnit != periodUnit || oldItem.Value != value { versionChanged = true @@ -157,14 +179,15 @@ func (this *MetricItemDAO) UpdateItem(tx *dbs.Tx, itemId int64, name string, key if versionChanged { op.Version = dbs.SQL("version+1") } + op.IsPublic = isPublic err = this.Save(tx, op) if err != nil { return err } // 通知更新 - if versionChanged || (oldItem.IsOn == 0 && isOn) || (oldItem.IsOn == 1 && !isOn) { - err := this.NotifyUpdate(tx, itemId) + if versionChanged || (oldItem.IsOn == 0 && isOn) || (oldItem.IsOn == 1 && !isOn) || oldIsPublic != isPublic { + err := this.NotifyUpdate(tx, itemId, isPublic || oldIsPublic) if err != nil { return err } @@ -204,6 +227,18 @@ func (this *MetricItemDAO) ListEnabledItems(tx *dbs.Tx, category serverconfigs.M return } +// FindAllPublicItems 取得公用的指标 +func (this *MetricItemDAO) FindAllPublicItems(tx *dbs.Tx) (result []*MetricItem, err error) { + _, err = this.Query(tx). + State(MetricItemStateEnabled). + Attr("userId", 0). + Attr("isPublic", true). + DescPk(). + Slice(&result). + FindAll() + return +} + // ComposeItemConfig 组合指标配置 func (this *MetricItemDAO) ComposeItemConfig(tx *dbs.Tx, itemId int64) (*serverconfigs.MetricItemConfig, error) { if itemId <= 0 { @@ -234,6 +269,25 @@ func (this *MetricItemDAO) ComposeItemConfig(tx *dbs.Tx, itemId int64) (*serverc return config, nil } +// ComposeItemConfigWithItem 根据Item信息组合指标 +func (this *MetricItemDAO) ComposeItemConfigWithItem(item *MetricItem) *serverconfigs.MetricItemConfig { + if item == nil { + return nil + } + var config = &serverconfigs.MetricItemConfig{ + Id: int64(item.Id), + IsOn: item.IsOn == 1, + Period: types.Int(item.Period), + PeriodUnit: item.PeriodUnit, + Category: item.Category, + Value: item.Value, + Keys: item.DecodeKeys(), + Version: types.Int32(item.Version), + } + + return config +} + // FindItemVersion 获取指标的版本号 func (this *MetricItemDAO) FindItemVersion(tx *dbs.Tx, itemId int64) (int32, error) { version, err := this.Query(tx). @@ -247,7 +301,20 @@ func (this *MetricItemDAO) FindItemVersion(tx *dbs.Tx, itemId int64) (int32, err } // NotifyUpdate 通知更新 -func (this *MetricItemDAO) NotifyUpdate(tx *dbs.Tx, itemId int64) error { +func (this *MetricItemDAO) NotifyUpdate(tx *dbs.Tx, itemId int64, isPublic bool) error { + if isPublic { + clusterIds, err := SharedNodeClusterDAO.FindAllEnableClusterIds(tx) + if err != nil { + return err + } + for _, clusterId := range clusterIds { + err = SharedNodeTaskDAO.CreateClusterTask(tx, clusterId, NodeTaskTypeConfigChanged) + if err != nil { + return err + } + } + return nil + } clusterIds, err := SharedNodeClusterMetricItemDAO.FindAllClusterIdsWithItemId(tx, itemId) if err != nil { return err diff --git a/internal/db/models/metric_item_model.go b/internal/db/models/metric_item_model.go index 35802e19..ea47dc4f 100644 --- a/internal/db/models/metric_item_model.go +++ b/internal/db/models/metric_item_model.go @@ -15,6 +15,7 @@ type MetricItem struct { Value string `field:"value"` // 值运算 State uint8 `field:"state"` // 状态 Version uint32 `field:"version"` // 版本号 + IsPublic uint8 `field:"isPublic"` // 是否为公用 } type MetricItemOperator struct { @@ -31,6 +32,7 @@ type MetricItemOperator struct { Value interface{} // 值运算 State interface{} // 状态 Version interface{} // 版本号 + IsPublic interface{} // 是否为公用 } func NewMetricItemOperator() *MetricItemOperator { diff --git a/internal/db/models/metric_stat_dao.go b/internal/db/models/metric_stat_dao.go index 54ed1b8c..7f056313 100644 --- a/internal/db/models/metric_stat_dao.go +++ b/internal/db/models/metric_stat_dao.go @@ -101,6 +101,39 @@ func (this *MetricStatDAO) ListItemStats(tx *dbs.Tx, itemId int64, version int32 return } +// FindItemStatsAtLastTime 取得所有集群最近一次计时前 N 个数据 +// 适合每条数据中包含不同的Key的场景 +func (this *MetricStatDAO) FindItemStatsAtLastTime(tx *dbs.Tx, itemId int64, version int32, size int64) (result []*MetricStat, err error) { + // 最近一次时间 + statOne, err := this.Query(tx). + Attr("itemId", itemId). + Attr("version", version). + DescPk(). + Find() + if err != nil { + return nil, err + } + if statOne == nil { + return nil, nil + } + var lastStat = statOne.(*MetricStat) + var lastTime = lastStat.Time + + _, err = this.Query(tx). + Attr("itemId", itemId). + Attr("version", version). + Attr("time", lastTime). + // TODO 增加更多聚合算法,比如 AVG、MEDIAN、MIN、MAX 等 + // TODO 这里的 MIN(`keys`) 在MySQL8中可以换成FIRST_VALUE + Result("MIN(time) AS time", "SUM(value) AS value", "keys"). + Desc("value"). + Group("keys"). + Limit(size). + Slice(&result). + FindAll() + return +} + // FindItemStatsWithClusterIdAndLastTime 取得集群最近一次计时前 N 个数据 // 适合每条数据中包含不同的Key的场景 func (this *MetricStatDAO) FindItemStatsWithClusterIdAndLastTime(tx *dbs.Tx, clusterId int64, itemId int64, version int32, size int64) (result []*MetricStat, err error) { @@ -203,6 +236,27 @@ func (this *MetricStatDAO) FindItemStatsWithServerIdAndLastTime(tx *dbs.Tx, serv return } +// FindLatestItemStats 取得所有集群上最近 N 个时间的数据 +// 适合同个Key在不同时间段的变化场景 +func (this *MetricStatDAO) FindLatestItemStats(tx *dbs.Tx, itemId int64, version int32, size int64) (result []*MetricStat, err error) { + _, err = this.Query(tx). + Attr("itemId", itemId). + Attr("version", version). + // TODO 增加更多聚合算法,比如 AVG、MEDIAN、MIN、MAX 等 + // TODO 这里的 MIN(`keys`) 在MySQL8中可以换成FIRST_VALUE + Result("time", "SUM(value) AS value", "MIN(`keys`) AS `keys`"). + Desc("time"). + Group("time"). + Limit(size). + Slice(&result). + FindAll() + if err != nil { + return nil, err + } + lists.Reverse(result) + return +} + // FindLatestItemStatsWithClusterId 取得集群最近 N 个时间的数据 // 适合同个Key在不同时间段的变化场景 func (this *MetricStatDAO) FindLatestItemStatsWithClusterId(tx *dbs.Tx, clusterId int64, itemId int64, version int32, size int64) (result []*MetricStat, err error) { diff --git a/internal/db/models/metric_sum_stat_dao.go b/internal/db/models/metric_sum_stat_dao.go index 0524bdec..a27ae36d 100644 --- a/internal/db/models/metric_sum_stat_dao.go +++ b/internal/db/models/metric_sum_stat_dao.go @@ -64,6 +64,23 @@ func (this *MetricSumStatDAO) FindNodeServerSum(tx *dbs.Tx, nodeId int64, server return int64(one.(*MetricSumStat).Count), float32(one.(*MetricSumStat).Total), nil } +// FindSumAtTime 查找某个时间的统计数据 +func (this *MetricSumStatDAO) FindSumAtTime(tx *dbs.Tx, time string, itemId int64, version int32) (count int64, total float32, err error) { + one, err := this.Query(tx). + Attr("time", time). + Attr("itemId", itemId). + Attr("version", version). + Result("SUM(count) AS `count`, SUM(total) AS total"). + Find() + if err != nil { + return 0, 0, err + } + if one == nil { + return + } + return int64(one.(*MetricSumStat).Count), float32(one.(*MetricSumStat).Total), nil +} + // FindServerSum 查找某个服务的统计数据 func (this *MetricSumStatDAO) FindServerSum(tx *dbs.Tx, serverId int64, time string, itemId int64, version int32) (count int64, total float32, err error) { one, err := this.Query(tx). diff --git a/internal/db/models/node_dao.go b/internal/db/models/node_dao.go index b3285192..944caecf 100644 --- a/internal/db/models/node_dao.go +++ b/internal/db/models/node_dao.go @@ -14,6 +14,7 @@ import ( _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/lists" "github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/rands" "github.com/iwind/TeaGo/types" @@ -682,7 +683,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64) (*nodeconfigs.N } } - // 指标 + // 集群指标 metricItemIds, err := SharedNodeClusterMetricItemDAO.FindAllClusterItemIds(tx, int64(node.ClusterId)) if err != nil { return nil, err @@ -697,6 +698,19 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64) (*nodeconfigs.N metricItems = append(metricItems, itemConfig) } } + + // 公用指标 + publicMetricItems, err := SharedMetricItemDAO.FindAllPublicItems(tx) + if err != nil { + return nil, err + } + for _, item := range publicMetricItems { + itemConfig := SharedMetricItemDAO.ComposeItemConfigWithItem(item) + if itemConfig != nil && !lists.ContainsInt64(metricItemIds, itemConfig.Id) { + metricItems = append(metricItems, itemConfig) + } + } + config.MetricItems = metricItems return config, nil diff --git a/internal/rpc/services/service_admin.go b/internal/rpc/services/service_admin.go index be93a129..c5bee827 100644 --- a/internal/rpc/services/service_admin.go +++ b/internal/rpc/services/service_admin.go @@ -12,7 +12,10 @@ import ( rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils" "github.com/TeaOSLab/EdgeAPI/internal/utils" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/types" timeutil "github.com/iwind/TeaGo/utils/time" "time" ) @@ -643,40 +646,51 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com } // 域名排行 - topDomainStats, err := stats.SharedServerDomainHourlyStatDAO.FindTopDomainStats(tx, hourFrom, hourTo) - if err != nil { - return nil, err - } - for _, stat := range topDomainStats { - result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeAdminDashboardResponse_DomainStat{ - ServerId: int64(stat.ServerId), - Domain: stat.Domain, - CountRequests: int64(stat.CountRequests), - Bytes: int64(stat.Bytes), - }) - } - - // 节点排行 - topNodeStats, err := stats.SharedNodeTrafficHourlyStatDAO.FindTopNodeStats(tx, "node", hourFrom, hourTo) - if err != nil { - return nil, err - } - for _, stat := range topNodeStats { - nodeName, err := models.SharedNodeDAO.FindNodeName(tx, int64(stat.NodeId)) + if isPlus { + topDomainStats, err := stats.SharedServerDomainHourlyStatDAO.FindTopDomainStats(tx, hourFrom, hourTo) if err != nil { return nil, err } - if len(nodeName) == 0 { - continue + for _, stat := range topDomainStats { + result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeAdminDashboardResponse_DomainStat{ + ServerId: int64(stat.ServerId), + Domain: stat.Domain, + CountRequests: int64(stat.CountRequests), + Bytes: int64(stat.Bytes), + }) } - result.TopNodeStats = append(result.TopNodeStats, &pb.ComposeAdminDashboardResponse_NodeStat{ - NodeId: int64(stat.NodeId), - NodeName: nodeName, - CountRequests: int64(stat.CountRequests), - Bytes: int64(stat.Bytes), - }) } + // 节点排行 + if isPlus { + topNodeStats, err := stats.SharedNodeTrafficHourlyStatDAO.FindTopNodeStats(tx, "node", hourFrom, hourTo) + 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.ComposeAdminDashboardResponse_NodeStat{ + NodeId: int64(stat.NodeId), + NodeName: nodeName, + CountRequests: int64(stat.CountRequests), + Bytes: int64(stat.Bytes), + }) + } + } + + // 指标数据 + pbCharts, err := this.findMetricDataCharts(tx) + if err != nil { + return nil, err + } + result.MetricDataCharts = pbCharts + return result, nil } @@ -693,3 +707,111 @@ func (this *AdminService) UpdateAdminTheme(ctx context.Context, req *pb.UpdateAd } return this.Success() } + +// 查找集群、节点和服务的指标数据 +func (this *AdminService) findMetricDataCharts(tx *dbs.Tx) (result []*pb.MetricDataChart, err error) { + // 集群指标 + items, err := models.SharedMetricItemDAO.FindAllPublicItems(tx) + if err != nil { + return nil, err + } + var pbMetricCharts = []*pb.MetricDataChart{} + for _, item := range items { + var itemId = int64(item.Id) + charts, err := models.SharedMetricChartDAO.FindAllEnabledCharts(tx, itemId) + if err != nil { + return nil, err + } + + for _, chart := range charts { + if chart.IsOn == 0 { + continue + } + + var pbChart = &pb.MetricChart{ + Id: int64(chart.Id), + Name: chart.Name, + Type: chart.Type, + WidthDiv: chart.WidthDiv, + ParamsJSON: nil, + IsOn: chart.IsOn == 1, + MaxItems: types.Int32(chart.MaxItems), + MetricItem: &pb.MetricItem{ + Id: itemId, + PeriodUnit: item.PeriodUnit, + Period: types.Int32(item.Period), + Name: item.Name, + Value: item.Value, + Category: item.Category, + Keys: item.DecodeKeys(), + Code: item.Code, + IsOn: item.IsOn == 1, + }, + } + var pbStats = []*pb.MetricStat{} + switch chart.Type { + case serverconfigs.MetricChartTypeTimeLine: + itemStats, err := models.SharedMetricStatDAO.FindLatestItemStats(tx, itemId, types.Int32(item.Version), 10) + if err != nil { + return nil, err + } + + for _, stat := range itemStats { + // 当前时间总和 + count, total, err := models.SharedMetricSumStatDAO.FindSumAtTime(tx, stat.Time, itemId, types.Int32(item.Version)) + if err != nil { + return nil, err + } + + pbStats = append(pbStats, &pb.MetricStat{ + Id: int64(stat.Id), + Hash: stat.Hash, + ServerId: 0, + ItemId: 0, + Keys: stat.DecodeKeys(), + Value: types.Float32(stat.Value), + Time: stat.Time, + Version: 0, + NodeCluster: nil, + Node: nil, + Server: nil, + SumCount: count, + SumTotal: total, + }) + } + default: + itemStats, err := models.SharedMetricStatDAO.FindItemStatsAtLastTime(tx, itemId, types.Int32(item.Version), 10) + if err != nil { + return nil, err + } + for _, stat := range itemStats { + count, total, err := models.SharedMetricSumStatDAO.FindSumAtTime(tx, stat.Time, itemId, types.Int32(item.Version)) + if err != nil { + return nil, err + } + + pbStats = append(pbStats, &pb.MetricStat{ + Id: int64(stat.Id), + Hash: stat.Hash, + ServerId: 0, + ItemId: 0, + Keys: stat.DecodeKeys(), + Value: types.Float32(stat.Value), + Time: stat.Time, + Version: 0, + NodeCluster: nil, + Node: nil, + Server: nil, + SumCount: count, + SumTotal: total, + }) + } + } + pbMetricCharts = append(pbMetricCharts, &pb.MetricDataChart{ + MetricChart: pbChart, + MetricStats: pbStats, + }) + } + } + return pbMetricCharts, nil +} diff --git a/internal/rpc/services/service_metric_item.go b/internal/rpc/services/service_metric_item.go index cc15b6da..2e174a75 100644 --- a/internal/rpc/services/service_metric_item.go +++ b/internal/rpc/services/service_metric_item.go @@ -22,7 +22,7 @@ func (this *MetricItemService) CreateMetricItem(ctx context.Context, req *pb.Cre } var tx = this.NullTx() - itemId, err := models.SharedMetricItemDAO.CreateItem(tx, req.Code, req.Category, req.Name, req.Keys, req.Period, req.PeriodUnit, req.Value) + itemId, err := models.SharedMetricItemDAO.CreateItem(tx, req.Code, req.Category, req.Name, req.Keys, req.Period, req.PeriodUnit, req.Value, req.IsPublic) if err != nil { return nil, err } @@ -37,7 +37,7 @@ func (this *MetricItemService) UpdateMetricItem(ctx context.Context, req *pb.Upd } var tx = this.NullTx() - err = models.SharedMetricItemDAO.UpdateItem(tx, req.MetricItemId, req.Name, req.Keys, req.Period, req.PeriodUnit, req.Value, req.IsOn) + err = models.SharedMetricItemDAO.UpdateItem(tx, req.MetricItemId, req.Name, req.Keys, req.Period, req.PeriodUnit, req.Value, req.IsOn, req.IsPublic) if err != nil { return nil, err } @@ -69,6 +69,7 @@ func (this *MetricItemService) FindEnabledMetricItem(ctx context.Context, req *p Period: types.Int32(item.Period), PeriodUnit: item.PeriodUnit, Value: item.Value, + IsPublic: item.IsPublic == 1, }}, nil } @@ -111,8 +112,10 @@ func (this *MetricItemService) ListEnabledMetricItems(ctx context.Context, req * Period: types.Int32(item.Period), PeriodUnit: item.PeriodUnit, Value: item.Value, + IsPublic: item.IsPublic == 1, }) } + return &pb.ListEnabledMetricItemsResponse{MetricItems: pbItems}, nil } diff --git a/internal/rpc/services/service_node_cluster_metric_item.go b/internal/rpc/services/service_node_cluster_metric_item.go index 00202eee..139e861c 100644 --- a/internal/rpc/services/service_node_cluster_metric_item.go +++ b/internal/rpc/services/service_node_cluster_metric_item.go @@ -79,6 +79,7 @@ func (this *NodeClusterMetricItemService) FindAllNodeClusterMetricItems(ctx cont Period: types.Int32(item.Period), PeriodUnit: item.PeriodUnit, Value: item.Value, + IsPublic: item.IsPublic == 1, }) } } @@ -99,3 +100,33 @@ func (this *NodeClusterMetricItemService) ExistsNodeClusterMetricItem(ctx contex } return this.Exists(b) } + +// FindAllNodeClustersWithMetricItemId 查找使用指标的集群 +func (this *NodeClusterMetricItemService) FindAllNodeClustersWithMetricItemId(ctx context.Context, req *pb.FindAllNodeClustersWithMetricItemIdRequest) (*pb.FindAllNodeClustersWithMetricItemIdResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + var tx = this.NullTx() + clusterIds, err := models.SharedNodeClusterMetricItemDAO.FindAllClusterIdsWithItemId(tx, req.MetricItemId) + if err != nil { + return nil, err + } + var pbClusters []*pb.NodeCluster + for _, clusterId := range clusterIds { + cluster, err := models.SharedNodeClusterDAO.FindEnabledNodeCluster(tx, clusterId) + if err != nil { + return nil, err + } + if cluster == nil { + continue + } + pbClusters = append(pbClusters, &pb.NodeCluster{ + Id: int64(cluster.Id), + Name: cluster.Name, + }) + } + + return &pb.FindAllNodeClustersWithMetricItemIdResponse{NodeClusters: pbClusters}, nil +} diff --git a/internal/rpc/services/service_server_stat_board.go b/internal/rpc/services/service_server_stat_board.go index 95cbdc6f..1adac1c3 100644 --- a/internal/rpc/services/service_server_stat_board.go +++ b/internal/rpc/services/service_server_stat_board.go @@ -12,6 +12,8 @@ import ( "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/lists" "github.com/iwind/TeaGo/types" timeutil "github.com/iwind/TeaGo/utils/time" "time" @@ -205,122 +207,11 @@ func (this *ServerStatBoardService) ComposeServerStatNodeClusterBoard(ctx contex }) } - // 指标 - clusterMetricItems, err := models.SharedNodeClusterMetricItemDAO.FindAllClusterItems(tx, req.NodeClusterId, serverconfigs.MetricItemCategoryHTTP) + charts, err := this.findNodeClusterMetricDataCharts(tx, req.NodeClusterId, 0, 0, serverconfigs.MetricItemCategoryHTTP) if err != nil { return nil, err } - var pbMetricCharts = []*pb.ComposeServerStatNodeClusterBoardResponse_MetricData{} - for _, clusterMetricItem := range clusterMetricItems { - if clusterMetricItem.IsOn != 1 { - continue - } - var itemId = int64(clusterMetricItem.ItemId) - charts, err := models.SharedMetricChartDAO.FindAllEnabledCharts(tx, itemId) - if err != nil { - return nil, err - } - - item, err := models.SharedMetricItemDAO.FindEnabledMetricItem(tx, itemId) - if err != nil { - return nil, err - } - if item == nil || item.IsOn == 0 { - continue - } - - for _, chart := range charts { - if chart.IsOn == 0 { - continue - } - - var pbChart = &pb.MetricChart{ - Id: int64(chart.Id), - Name: chart.Name, - Type: chart.Type, - WidthDiv: chart.WidthDiv, - ParamsJSON: nil, - IsOn: chart.IsOn == 1, - MaxItems: types.Int32(chart.MaxItems), - MetricItem: &pb.MetricItem{ - Id: itemId, - PeriodUnit: item.PeriodUnit, - Period: types.Int32(item.Period), - Name: item.Name, - Value: item.Value, - Category: item.Category, - Keys: item.DecodeKeys(), - Code: item.Code, - IsOn: item.IsOn == 1, - }, - } - var pbStats = []*pb.MetricStat{} - switch chart.Type { - case serverconfigs.MetricChartTypeTimeLine: - itemStats, err := models.SharedMetricStatDAO.FindLatestItemStatsWithClusterId(tx, req.NodeClusterId, itemId, types.Int32(item.Version), 10) - if err != nil { - return nil, err - } - - for _, stat := range itemStats { - // 当前时间总和 - count, total, err := models.SharedMetricSumStatDAO.FindClusterSum(tx, req.NodeClusterId, stat.Time, itemId, types.Int32(item.Version)) - if err != nil { - return nil, err - } - - pbStats = append(pbStats, &pb.MetricStat{ - Id: int64(stat.Id), - Hash: stat.Hash, - ServerId: 0, - ItemId: 0, - Keys: stat.DecodeKeys(), - Value: types.Float32(stat.Value), - Time: stat.Time, - Version: 0, - NodeCluster: nil, - Node: nil, - Server: nil, - SumCount: count, - SumTotal: total, - }) - } - default: - itemStats, err := models.SharedMetricStatDAO.FindItemStatsWithClusterIdAndLastTime(tx, req.NodeClusterId, itemId, types.Int32(item.Version), 10) - if err != nil { - return nil, err - } - for _, stat := range itemStats { - // 当前时间总和 - count, total, err := models.SharedMetricSumStatDAO.FindClusterSum(tx, req.NodeClusterId, stat.Time, itemId, types.Int32(item.Version)) - if err != nil { - return nil, err - } - - pbStats = append(pbStats, &pb.MetricStat{ - Id: int64(stat.Id), - Hash: stat.Hash, - ServerId: 0, - ItemId: 0, - Keys: stat.DecodeKeys(), - Value: types.Float32(stat.Value), - Time: stat.Time, - Version: 0, - NodeCluster: nil, - Node: nil, - Server: nil, - SumCount: count, - SumTotal: total, - }) - } - } - pbMetricCharts = append(pbMetricCharts, &pb.ComposeServerStatNodeClusterBoardResponse_MetricData{ - MetricChart: pbChart, - MetricStats: pbStats, - }) - } - } - result.MetricCharts = pbMetricCharts + result.MetricDataCharts = charts return result, nil } @@ -551,121 +442,11 @@ func (this *ServerStatBoardService) ComposeServerStatNodeBoard(ctx context.Conte // 指标 var clusterId = int64(node.ClusterId) - clusterMetricItems, err := models.SharedNodeClusterMetricItemDAO.FindAllClusterItems(tx, clusterId, serverconfigs.MetricItemCategoryHTTP) + charts, err := this.findNodeClusterMetricDataCharts(tx, clusterId, req.NodeId, 0, serverconfigs.MetricItemCategoryHTTP) if err != nil { return nil, err } - var pbMetricCharts = []*pb.ComposeServerStatNodeBoardResponse_MetricData{} - for _, clusterMetricItem := range clusterMetricItems { - if clusterMetricItem.IsOn != 1 { - continue - } - var itemId = int64(clusterMetricItem.ItemId) - charts, err := models.SharedMetricChartDAO.FindAllEnabledCharts(tx, itemId) - if err != nil { - return nil, err - } - - item, err := models.SharedMetricItemDAO.FindEnabledMetricItem(tx, itemId) - if err != nil { - return nil, err - } - if item == nil || item.IsOn == 0 { - continue - } - - for _, chart := range charts { - if chart.IsOn == 0 { - continue - } - - var pbChart = &pb.MetricChart{ - Id: int64(chart.Id), - Name: chart.Name, - Type: chart.Type, - WidthDiv: chart.WidthDiv, - ParamsJSON: nil, - IsOn: chart.IsOn == 1, - MaxItems: types.Int32(chart.MaxItems), - MetricItem: &pb.MetricItem{ - Id: itemId, - PeriodUnit: item.PeriodUnit, - Period: types.Int32(item.Period), - Name: item.Name, - Value: item.Value, - Category: item.Category, - Keys: item.DecodeKeys(), - Code: item.Code, - IsOn: item.IsOn == 1, - }, - } - var pbStats = []*pb.MetricStat{} - switch chart.Type { - case serverconfigs.MetricChartTypeTimeLine: - itemStats, err := models.SharedMetricStatDAO.FindLatestItemStatsWithNodeId(tx, req.NodeId, itemId, types.Int32(item.Version), 10) - if err != nil { - return nil, err - } - - for _, stat := range itemStats { - // 当前时间总和 - count, total, err := models.SharedMetricSumStatDAO.FindNodeSum(tx, req.NodeId, stat.Time, itemId, types.Int32(item.Version)) - if err != nil { - return nil, err - } - - pbStats = append(pbStats, &pb.MetricStat{ - Id: int64(stat.Id), - Hash: stat.Hash, - ServerId: 0, - ItemId: 0, - Keys: stat.DecodeKeys(), - Value: types.Float32(stat.Value), - Time: stat.Time, - Version: 0, - NodeCluster: nil, - Node: nil, - Server: nil, - SumCount: count, - SumTotal: total, - }) - } - default: - itemStats, err := models.SharedMetricStatDAO.FindItemStatsWithNodeIdAndLastTime(tx, req.NodeId, itemId, types.Int32(item.Version), 10) - if err != nil { - return nil, err - } - for _, stat := range itemStats { - // 当前时间总和 - count, total, err := models.SharedMetricSumStatDAO.FindNodeSum(tx, req.NodeId, stat.Time, itemId, types.Int32(item.Version)) - if err != nil { - return nil, err - } - - pbStats = append(pbStats, &pb.MetricStat{ - Id: int64(stat.Id), - Hash: stat.Hash, - ServerId: 0, - ItemId: 0, - Keys: stat.DecodeKeys(), - Value: types.Float32(stat.Value), - Time: stat.Time, - Version: 0, - NodeCluster: nil, - Node: nil, - Server: nil, - SumCount: count, - SumTotal: total, - }) - } - } - pbMetricCharts = append(pbMetricCharts, &pb.ComposeServerStatNodeBoardResponse_MetricData{ - MetricChart: pbChart, - MetricStats: pbStats, - }) - } - } - result.MetricCharts = pbMetricCharts + result.MetricDataCharts = charts return result, nil } @@ -738,21 +519,30 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context, if err != nil { return nil, err } - clusterMetricItems, err := models.SharedNodeClusterMetricItemDAO.FindAllClusterItems(tx, clusterId, serverconfigs.MetricItemCategoryHTTP) + charts, err := this.findNodeClusterMetricDataCharts(tx, clusterId, 0, req.ServerId, serverconfigs.MetricItemCategoryHTTP) if err != nil { return nil, err } - var pbMetricCharts = []*pb.ComposeServerStatBoardResponse_MetricData{} + result.MetricDataCharts = charts + + return result, nil +} + +// 查找集群、节点和服务的指标数据 +func (this *ServerStatBoardService) findNodeClusterMetricDataCharts(tx *dbs.Tx, clusterId int64, nodeId int64, serverId int64, category string) (result []*pb.MetricDataChart, err error) { + // 集群指标 + clusterMetricItems, err := models.SharedNodeClusterMetricItemDAO.FindAllClusterItems(tx, clusterId, category) + if err != nil { + return nil, err + } + var pbMetricCharts = []*pb.MetricDataChart{} + var metricItemIds = []int64{} + var items = []*models.MetricItem{} for _, clusterMetricItem := range clusterMetricItems { if clusterMetricItem.IsOn != 1 { continue } var itemId = int64(clusterMetricItem.ItemId) - charts, err := models.SharedMetricChartDAO.FindAllEnabledCharts(tx, itemId) - if err != nil { - return nil, err - } - item, err := models.SharedMetricItemDAO.FindEnabledMetricItem(tx, itemId) if err != nil { return nil, err @@ -760,6 +550,30 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context, if item == nil || item.IsOn == 0 { continue } + items = append(items, item) + metricItemIds = append(metricItemIds, itemId) + } + + publicMetricItems, err := models.SharedMetricItemDAO.FindAllPublicItems(tx) + if err != nil { + return nil, err + } + for _, item := range publicMetricItems { + if item.IsOn != 1 { + continue + } + if lists.ContainsInt64(metricItemIds, int64(item.Id)) { + continue + } + items = append(items, item) + } + + for _, item := range items { + var itemId = int64(item.Id) + charts, err := models.SharedMetricChartDAO.FindAllEnabledCharts(tx, itemId) + if err != nil { + return nil, err + } for _, chart := range charts { if chart.IsOn == 0 { @@ -789,14 +603,29 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context, var pbStats = []*pb.MetricStat{} switch chart.Type { case serverconfigs.MetricChartTypeTimeLine: - itemStats, err := models.SharedMetricStatDAO.FindLatestItemStatsWithServerId(tx, req.ServerId, itemId, types.Int32(item.Version), 10) + var itemStats []*models.MetricStat + if serverId > 0 { + itemStats, err = models.SharedMetricStatDAO.FindLatestItemStatsWithServerId(tx, serverId, itemId, types.Int32(item.Version), 10) + } else if nodeId > 0 { + itemStats, err = models.SharedMetricStatDAO.FindLatestItemStatsWithNodeId(tx, nodeId, itemId, types.Int32(item.Version), 10) + } else { + itemStats, err = models.SharedMetricStatDAO.FindLatestItemStatsWithClusterId(tx, clusterId, itemId, types.Int32(item.Version), 10) + } if err != nil { return nil, err } for _, stat := range itemStats { // 当前时间总和 - count, total, err := models.SharedMetricSumStatDAO.FindServerSum(tx, req.ServerId, stat.Time, itemId, types.Int32(item.Version)) + var count int64 + var total float32 + if serverId > 0 { + count, total, err = models.SharedMetricSumStatDAO.FindServerSum(tx, serverId, stat.Time, itemId, types.Int32(item.Version)) + } else if nodeId > 0 { + count, total, err = models.SharedMetricSumStatDAO.FindNodeSum(tx, nodeId, stat.Time, itemId, types.Int32(item.Version)) + } else { + count, total, err = models.SharedMetricSumStatDAO.FindClusterSum(tx, clusterId, stat.Time, itemId, types.Int32(item.Version)) + } if err != nil { return nil, err } @@ -818,13 +647,28 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context, }) } default: - itemStats, err := models.SharedMetricStatDAO.FindItemStatsWithServerIdAndLastTime(tx, req.ServerId, itemId, types.Int32(item.Version), 10) + var itemStats []*models.MetricStat + if serverId > 0 { + itemStats, err = models.SharedMetricStatDAO.FindItemStatsWithServerIdAndLastTime(tx, serverId, itemId, types.Int32(item.Version), 10) + } else if nodeId > 0 { + itemStats, err = models.SharedMetricStatDAO.FindItemStatsWithNodeIdAndLastTime(tx, nodeId, itemId, types.Int32(item.Version), 10) + } else { + itemStats, err = models.SharedMetricStatDAO.FindItemStatsWithClusterIdAndLastTime(tx, clusterId, itemId, types.Int32(item.Version), 10) + } if err != nil { return nil, err } for _, stat := range itemStats { // 当前时间总和 - count, total, err := models.SharedMetricSumStatDAO.FindServerSum(tx, req.ServerId, stat.Time, itemId, types.Int32(item.Version)) + var count int64 + var total float32 + if serverId > 0 { + count, total, err = models.SharedMetricSumStatDAO.FindServerSum(tx, serverId, stat.Time, itemId, types.Int32(item.Version)) + } else if nodeId > 0 { + count, total, err = models.SharedMetricSumStatDAO.FindNodeSum(tx, nodeId, stat.Time, itemId, types.Int32(item.Version)) + } else { + count, total, err = models.SharedMetricSumStatDAO.FindClusterSum(tx, clusterId, stat.Time, itemId, types.Int32(item.Version)) + } if err != nil { return nil, err } @@ -846,13 +690,11 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context, }) } } - pbMetricCharts = append(pbMetricCharts, &pb.ComposeServerStatBoardResponse_MetricData{ + pbMetricCharts = append(pbMetricCharts, &pb.MetricDataChart{ MetricChart: pbChart, MetricStats: pbStats, }) } } - result.MetricCharts = pbMetricCharts - - return result, nil + return pbMetricCharts, nil }