diff --git a/internal/db/models/node_ip_address_dao.go b/internal/db/models/node_ip_address_dao.go index 696cf124..3bc7c3d7 100644 --- a/internal/db/models/node_ip_address_dao.go +++ b/internal/db/models/node_ip_address_dao.go @@ -1,6 +1,7 @@ package models import ( + "encoding/json" "errors" "github.com/TeaOSLab/EdgeAPI/internal/db/models/dns" "github.com/TeaOSLab/EdgeCommon/pkg/configutils" @@ -346,12 +347,13 @@ func (this *NodeIPAddressDAO) ListEnabledIPAddresses(tx *dbs.Tx, role string, no return } -// FindAllEnabledAndOnIPAddressesWithClusterId 列出所有的正在启用的IP地址 -func (this *NodeIPAddressDAO) FindAllEnabledAndOnIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64) (result []*NodeIPAddress, err error) { +// FindAllAccessibleIPAddressesWithClusterId 列出所有的正在启用的IP地址 +func (this *NodeIPAddressDAO) FindAllAccessibleIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64) (result []*NodeIPAddress, err error) { _, err = this.Query(tx). State(NodeIPAddressStateEnabled). Attr("role", role). Attr("isOn", true). + Attr("canAccess", true). Where("nodeId IN (SELECT id FROM "+SharedNodeDAO.Table+" WHERE state=1 AND clusterId=:clusterId)"). Param("clusterId", clusterId). Slice(&result). @@ -359,6 +361,46 @@ func (this *NodeIPAddressDAO) FindAllEnabledAndOnIPAddressesWithClusterId(tx *db return } +// CountAllAccessibleIPAddressesWithClusterId 计算集群中的可用IP地址数量 +func (this *NodeIPAddressDAO) CountAllAccessibleIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64) (count int64, err error) { + return this.Query(tx). + State(NodeIPAddressStateEnabled). + Attr("role", role). + Attr("isOn", true). + Attr("canAccess", true). + Where("nodeId IN (SELECT id FROM "+SharedNodeDAO.Table+" WHERE state=1 AND clusterId=:clusterId)"). + Param("clusterId", clusterId). + Count() +} + +// ListAccessibleIPAddressesWithClusterId 列出单页集群中的可用IP地址 +func (this *NodeIPAddressDAO) ListAccessibleIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64, offset int64, size int64) (result []*NodeIPAddress, err error) { + _, err = this.Query(tx). + State(NodeIPAddressStateEnabled). + Attr("role", role). + Attr("isOn", true). + Attr("canAccess", true). + Where("nodeId IN (SELECT id FROM "+SharedNodeDAO.Table+" WHERE state=1 AND clusterId=:clusterId)"). + Param("clusterId", clusterId). + Offset(offset). + Limit(size). + Slice(&result). + FindAll() + return +} + +// UpdateAddressConnectivity 设置连通性数据 +func (this *NodeIPAddressDAO) UpdateAddressConnectivity(tx *dbs.Tx, addrId int64, connectivity *nodeconfigs.Connectivity) error { + connectivityJSON, err := json.Marshal(connectivity) + if err != nil { + return err + } + return this.Query(tx). + Pk(addrId). + Set("connectivity", connectivityJSON). + UpdateQuickly() +} + // NotifyUpdate 通知更新 func (this *NodeIPAddressDAO) NotifyUpdate(tx *dbs.Tx, addressId int64) error { address, err := this.Query(tx). diff --git a/internal/db/models/node_ip_address_model.go b/internal/db/models/node_ip_address_model.go index 531d8495..297ba02e 100644 --- a/internal/db/models/node_ip_address_model.go +++ b/internal/db/models/node_ip_address_model.go @@ -2,33 +2,35 @@ package models // NodeIPAddress 节点IP地址 type NodeIPAddress struct { - Id uint32 `field:"id"` // ID - NodeId uint32 `field:"nodeId"` // 节点ID - Role string `field:"role"` // 节点角色 - Name string `field:"name"` // 名称 - Ip string `field:"ip"` // IP地址 - Description string `field:"description"` // 描述 - State uint8 `field:"state"` // 状态 - Order uint32 `field:"order"` // 排序 - CanAccess uint8 `field:"canAccess"` // 是否可以访问 - IsOn uint8 `field:"isOn"` // 是否启用 - IsUp uint8 `field:"isUp"` // 是否上线 - Thresholds string `field:"thresholds"` // 上线阈值 + Id uint32 `field:"id"` // ID + NodeId uint32 `field:"nodeId"` // 节点ID + Role string `field:"role"` // 节点角色 + Name string `field:"name"` // 名称 + Ip string `field:"ip"` // IP地址 + Description string `field:"description"` // 描述 + State uint8 `field:"state"` // 状态 + Order uint32 `field:"order"` // 排序 + CanAccess uint8 `field:"canAccess"` // 是否可以访问 + IsOn uint8 `field:"isOn"` // 是否启用 + IsUp uint8 `field:"isUp"` // 是否上线 + Thresholds string `field:"thresholds"` // 上线阈值 + Connectivity string `field:"connectivity"` // 连通性状态 } type NodeIPAddressOperator struct { - Id interface{} // ID - NodeId interface{} // 节点ID - Role interface{} // 节点角色 - Name interface{} // 名称 - Ip interface{} // IP地址 - Description interface{} // 描述 - State interface{} // 状态 - Order interface{} // 排序 - CanAccess interface{} // 是否可以访问 - IsOn interface{} // 是否启用 - IsUp interface{} // 是否上线 - Thresholds interface{} // 上线阈值 + Id interface{} // ID + NodeId interface{} // 节点ID + Role interface{} // 节点角色 + Name interface{} // 名称 + Ip interface{} // IP地址 + Description interface{} // 描述 + State interface{} // 状态 + Order interface{} // 排序 + CanAccess interface{} // 是否可以访问 + IsOn interface{} // 是否启用 + IsUp interface{} // 是否上线 + Thresholds interface{} // 上线阈值 + Connectivity interface{} // 连通性状态 } func NewNodeIPAddressOperator() *NodeIPAddressOperator { diff --git a/internal/db/models/node_ip_address_model_ext.go b/internal/db/models/node_ip_address_model_ext.go index 923de037..77d28d2b 100644 --- a/internal/db/models/node_ip_address_model_ext.go +++ b/internal/db/models/node_ip_address_model_ext.go @@ -2,6 +2,7 @@ package models import ( "encoding/json" + "github.com/TeaOSLab/EdgeAPI/internal/remotelogs" "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/iwind/TeaGo/logs" ) @@ -18,3 +19,14 @@ func (this *NodeIPAddress) DecodeThresholds() []*nodeconfigs.NodeValueThresholdC } return result } + +func (this *NodeIPAddress) DecodeConnectivity() *nodeconfigs.Connectivity { + var connectivity = &nodeconfigs.Connectivity{} + if len(this.Connectivity) > 0 { + err := json.Unmarshal([]byte(this.Connectivity), connectivity) + if err != nil { + remotelogs.Error("NodeIPAddress.DecodeConnectivity", "decode failed: "+err.Error()) + } + } + return connectivity +} diff --git a/internal/db/models/report_node_dao.go b/internal/db/models/report_node_dao.go index af9ba6f8..67aaca1e 100644 --- a/internal/db/models/report_node_dao.go +++ b/internal/db/models/report_node_dao.go @@ -3,12 +3,14 @@ package models import ( "encoding/json" "github.com/TeaOSLab/EdgeAPI/internal/errors" + "github.com/TeaOSLab/EdgeAPI/internal/utils" "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/reporterconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/rands" + "github.com/iwind/TeaGo/types" ) const ( @@ -76,7 +78,7 @@ func (this *ReportNodeDAO) FindReportNodeName(tx *dbs.Tx, id int64) (string, err } // CreateReportNode 创建终端 -func (this *ReportNodeDAO) CreateReportNode(tx *dbs.Tx, name string, location string, isp string, allowIPs []string) (int64, error) { +func (this *ReportNodeDAO) CreateReportNode(tx *dbs.Tx, name string, location string, isp string, allowIPs []string, groupIds []int64) (int64, error) { uniqueId, err := this.GenUniqueId(tx) if err != nil { return 0, err @@ -107,13 +109,23 @@ func (this *ReportNodeDAO) CreateReportNode(tx *dbs.Tx, name string, location st op.AllowIPs = "[]" } + if len(groupIds) > 0 { + groupIdsJSON, err := json.Marshal(groupIds) + if err != nil { + return 0, err + } + op.GroupIds = groupIdsJSON + } else { + op.GroupIds = "[]" + } + op.IsOn = true op.State = ReportNodeStateEnabled return this.SaveInt64(tx, op) } // UpdateReportNode 修改终端 -func (this *ReportNodeDAO) UpdateReportNode(tx *dbs.Tx, nodeId int64, name string, location string, isp string, allowIPs []string, isOn bool) error { +func (this *ReportNodeDAO) UpdateReportNode(tx *dbs.Tx, nodeId int64, name string, location string, isp string, allowIPs []string, groupIds []int64, isOn bool) error { if nodeId <= 0 { return errors.New("invalid nodeId") } @@ -134,14 +146,27 @@ func (this *ReportNodeDAO) UpdateReportNode(tx *dbs.Tx, nodeId int64, name strin op.AllowIPs = "[]" } + if len(groupIds) > 0 { + groupIdsJSON, err := json.Marshal(groupIds) + if err != nil { + return err + } + op.GroupIds = groupIdsJSON + } else { + op.GroupIds = "[]" + } + op.IsOn = isOn return this.Save(tx, op) } // CountAllEnabledReportNodes 计算终端数量 -func (this *ReportNodeDAO) CountAllEnabledReportNodes(tx *dbs.Tx, keyword string) (int64, error) { +func (this *ReportNodeDAO) CountAllEnabledReportNodes(tx *dbs.Tx, groupId int64, keyword string) (int64, error) { var query = this.Query(tx). State(ReportNodeStateEnabled) + if groupId > 0 { + query.JSONContains("groupIds", types.String(groupId)) + } if len(keyword) > 0 { query.Where("(name LIKE :keyword OR location LIKE :keyword OR isp LIKE :keyword OR allowIPs LIKE :keyword OR (status IS NOT NULL AND JSON_EXTRACT(status, 'ip') LIKE :keyword))") query.Param("keyword", "%"+keyword+"%") @@ -149,10 +174,21 @@ func (this *ReportNodeDAO) CountAllEnabledReportNodes(tx *dbs.Tx, keyword string return query.Count() } +// CountAllEnabledAndOnReportNodes 计算可用的终端数量 +func (this *ReportNodeDAO) CountAllEnabledAndOnReportNodes(tx *dbs.Tx) (int64, error) { + var query = this.Query(tx). + Attr("isOn", true). + State(ReportNodeStateEnabled) + return query.Count() +} + // ListEnabledReportNodes 列出单页终端 -func (this *ReportNodeDAO) ListEnabledReportNodes(tx *dbs.Tx, keyword string, offset int64, size int64) (result []*ReportNode, err error) { +func (this *ReportNodeDAO) ListEnabledReportNodes(tx *dbs.Tx, groupId int64, keyword string, offset int64, size int64) (result []*ReportNode, err error) { var query = this.Query(tx). State(ReportNodeStateEnabled) + if groupId > 0 { + query.JSONContains("groupIds", types.String(groupId)) + } if len(keyword) > 0 { query.Where(`( name LIKE :keyword @@ -267,3 +303,13 @@ func (this *ReportNodeDAO) FindNodeAllowIPs(tx *dbs.Tx, nodeId int64) ([]string, } return node.(*ReportNode).DecodeAllowIPs(), nil } + +// CountAllLowerVersionNodes 计算所有节点中低于某个版本的节点数量 +func (this *ReportNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) { + return this.Query(tx). + State(ReportNodeStateEnabled). + Where("status IS NOT NULL"). + Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)"). + Param("version", utils.VersionToLong(version)). + Count() +} diff --git a/internal/db/models/report_node_group_dao.go b/internal/db/models/report_node_group_dao.go new file mode 100644 index 00000000..7343a469 --- /dev/null +++ b/internal/db/models/report_node_group_dao.go @@ -0,0 +1,109 @@ +package models + +import ( + "github.com/TeaOSLab/EdgeAPI/internal/errors" + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" +) + +const ( + ReportNodeGroupStateEnabled = 1 // 已启用 + ReportNodeGroupStateDisabled = 0 // 已禁用 +) + +type ReportNodeGroupDAO dbs.DAO + +func NewReportNodeGroupDAO() *ReportNodeGroupDAO { + return dbs.NewDAO(&ReportNodeGroupDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeReportNodeGroups", + Model: new(ReportNodeGroup), + PkName: "id", + }, + }).(*ReportNodeGroupDAO) +} + +var SharedReportNodeGroupDAO *ReportNodeGroupDAO + +func init() { + dbs.OnReady(func() { + SharedReportNodeGroupDAO = NewReportNodeGroupDAO() + }) +} + +// EnableReportNodeGroup 启用条目 +func (this *ReportNodeGroupDAO) EnableReportNodeGroup(tx *dbs.Tx, id uint32) error { + _, err := this.Query(tx). + Pk(id). + Set("state", ReportNodeGroupStateEnabled). + Update() + return err +} + +// DisableReportNodeGroup 禁用条目 +func (this *ReportNodeGroupDAO) DisableReportNodeGroup(tx *dbs.Tx, id int64) error { + _, err := this.Query(tx). + Pk(id). + Set("state", ReportNodeGroupStateDisabled). + Update() + return err +} + +// FindEnabledReportNodeGroup 查找启用中的条目 +func (this *ReportNodeGroupDAO) FindEnabledReportNodeGroup(tx *dbs.Tx, id int64) (*ReportNodeGroup, error) { + result, err := this.Query(tx). + Pk(id). + Attr("state", ReportNodeGroupStateEnabled). + Find() + if result == nil { + return nil, err + } + return result.(*ReportNodeGroup), err +} + +// FindReportNodeGroupName 根据主键查找名称 +func (this *ReportNodeGroupDAO) FindReportNodeGroupName(tx *dbs.Tx, id int64) (string, error) { + return this.Query(tx). + Pk(id). + Result("name"). + FindStringCol("") +} + +// CreateGroup 创建 +func (this *ReportNodeGroupDAO) CreateGroup(tx *dbs.Tx, name string) (int64, error) { + var op = NewReportNodeGroupOperator() + op.Name = name + op.IsOn = true + op.State = ReportNodeGroupStateEnabled + return this.SaveInt64(tx, op) +} + +// UpdateGroup 修改 +func (this *ReportNodeGroupDAO) UpdateGroup(tx *dbs.Tx, groupId int64, name string) error { + if groupId <= 0 { + return errors.New("invalid groupId") + } + var op = NewReportNodeGroupOperator() + op.Id = groupId + op.Name = name + return this.Save(tx, op) +} + +// FindAllEnabledGroups 查找所有可用的分组 +func (this *ReportNodeGroupDAO) FindAllEnabledGroups(tx *dbs.Tx) (result []*ReportNodeGroup, err error) { + _, err = this.Query(tx). + State(ReportNodeGroupStateEnabled). + AscPk(). + Slice(&result). + FindAll() + return +} + +// CountAllEnabledGroups 查找所有分组的数量 +func (this *ReportNodeGroupDAO) CountAllEnabledGroups(tx *dbs.Tx) (int64, error) { + return this.Query(tx). + State(ReportNodeGroupStateEnabled). + Count() +} diff --git a/internal/db/models/report_node_group_dao_test.go b/internal/db/models/report_node_group_dao_test.go new file mode 100644 index 00000000..224e9db7 --- /dev/null +++ b/internal/db/models/report_node_group_dao_test.go @@ -0,0 +1,6 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" + _ "github.com/iwind/TeaGo/bootstrap" +) diff --git a/internal/db/models/report_node_group_model.go b/internal/db/models/report_node_group_model.go new file mode 100644 index 00000000..d56639a2 --- /dev/null +++ b/internal/db/models/report_node_group_model.go @@ -0,0 +1,20 @@ +package models + +// ReportNodeGroup 监控终端区域 +type ReportNodeGroup struct { + Id uint32 `field:"id"` // ID + Name string `field:"name"` // 名称 + State uint8 `field:"state"` // 状态 + IsOn uint8 `field:"isOn"` // 是否启用 +} + +type ReportNodeGroupOperator struct { + Id interface{} // ID + Name interface{} // 名称 + State interface{} // 状态 + IsOn interface{} // 是否启用 +} + +func NewReportNodeGroupOperator() *ReportNodeGroupOperator { + return &ReportNodeGroupOperator{} +} diff --git a/internal/db/models/report_node_group_model_ext.go b/internal/db/models/report_node_group_model_ext.go new file mode 100644 index 00000000..2640e7f9 --- /dev/null +++ b/internal/db/models/report_node_group_model_ext.go @@ -0,0 +1 @@ +package models diff --git a/internal/db/models/report_node_model.go b/internal/db/models/report_node_model.go index 3fd6530e..1fa6a50e 100644 --- a/internal/db/models/report_node_model.go +++ b/internal/db/models/report_node_model.go @@ -14,6 +14,7 @@ type ReportNode struct { Status string `field:"status"` // 状态 State uint8 `field:"state"` // 状态 CreatedAt uint64 `field:"createdAt"` // 创建时间 + GroupIds string `field:"groupIds"` // 分组ID } type ReportNodeOperator struct { @@ -29,6 +30,7 @@ type ReportNodeOperator struct { Status interface{} // 状态 State interface{} // 状态 CreatedAt interface{} // 创建时间 + GroupIds interface{} // 分组ID } func NewReportNodeOperator() *ReportNodeOperator { diff --git a/internal/db/models/report_node_model_ext.go b/internal/db/models/report_node_model_ext.go index 2f8c3953..a979b5dc 100644 --- a/internal/db/models/report_node_model_ext.go +++ b/internal/db/models/report_node_model_ext.go @@ -1,12 +1,28 @@ package models -import "encoding/json" +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAPI/internal/remotelogs" +) func (this *ReportNode) DecodeAllowIPs() []string { var result = []string{} if len(this.AllowIPs) > 0 { - // 忽略错误 - _ = json.Unmarshal([]byte(this.AllowIPs), &result) + err := json.Unmarshal([]byte(this.AllowIPs), &result) + if err != nil { + remotelogs.Error("ReportNode.DecodeGroupIds", err.Error()) + } + } + return result +} + +func (this *ReportNode) DecodeGroupIds() []int64 { + var result = []int64{} + if len(this.GroupIds) > 0 { + err := json.Unmarshal([]byte(this.GroupIds), &result) + if err != nil { + remotelogs.Error("ReportNode.DecodeGroupIds", err.Error()) + } } return result } diff --git a/internal/db/models/report_result_dao.go b/internal/db/models/report_result_dao.go index 05e233c3..9a9c0689 100644 --- a/internal/db/models/report_result_dao.go +++ b/internal/db/models/report_result_dao.go @@ -2,6 +2,7 @@ package models import ( "github.com/TeaOSLab/EdgeCommon/pkg/configutils" + "github.com/TeaOSLab/EdgeCommon/pkg/reporterconfigs" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" @@ -31,7 +32,7 @@ func init() { } // UpdateResult 创建结果 -func (this *ReportResultDAO) UpdateResult(tx *dbs.Tx, taskType string, targetId int64, targetDesc string, reportNodeId int64, isOk bool, costMs float64, errString string) error { +func (this *ReportResultDAO) UpdateResult(tx *dbs.Tx, taskType string, targetId int64, targetDesc string, reportNodeId int64, level reporterconfigs.ReportLevel, isOk bool, costMs float64, errString string) error { var countUp interface{} = 0 var countDown interface{} = 0 if isOk { @@ -52,6 +53,7 @@ func (this *ReportResultDAO) UpdateResult(tx *dbs.Tx, taskType string, targetId "error": errString, "countUp": countUp, "countDown": countDown, + "level": level, }, maps.Map{ "targetDesc": targetDesc, "updatedAt": time.Now().Unix(), @@ -60,11 +62,12 @@ func (this *ReportResultDAO) UpdateResult(tx *dbs.Tx, taskType string, targetId "error": errString, "countUp": countUp, "countDown": countDown, + "level": level, }) } // CountAllResults 计算结果数量 -func (this *ReportResultDAO) CountAllResults(tx *dbs.Tx, reportNodeId int64, okState configutils.BoolState) (int64, error) { +func (this *ReportResultDAO) CountAllResults(tx *dbs.Tx, reportNodeId int64, level reporterconfigs.ReportLevel, okState configutils.BoolState) (int64, error) { var query = this.Query(tx). Attr("reportNodeId", reportNodeId) switch okState { @@ -73,12 +76,16 @@ func (this *ReportResultDAO) CountAllResults(tx *dbs.Tx, reportNodeId int64, okS case configutils.BoolStateNo: query.Attr("isOk", 0) } + if len(level) > 0 { + query.Attr("level", level) + } return query. + Gt("updatedAt", time.Now().Unix()-600). Count() } // ListResults 列出单页结果 -func (this *ReportResultDAO) ListResults(tx *dbs.Tx, reportNodeId int64, okState configutils.BoolState, offset int64, size int64) (result []*ReportResult, err error) { +func (this *ReportResultDAO) ListResults(tx *dbs.Tx, reportNodeId int64, okState configutils.BoolState, level reporterconfigs.ReportLevel, offset int64, size int64) (result []*ReportResult, err error) { var query = this.Query(tx). Attr("reportNodeId", reportNodeId) switch okState { @@ -87,8 +94,12 @@ func (this *ReportResultDAO) ListResults(tx *dbs.Tx, reportNodeId int64, okState case configutils.BoolStateNo: query.Attr("isOk", 0) } + if len(level) > 0 { + query.Attr("level", level) + } _, err = query. Attr("reportNodeId", reportNodeId). + Gt("updatedAt", time.Now().Unix()-600). Offset(offset). Limit(size). Desc("targetId"). @@ -96,3 +107,87 @@ func (this *ReportResultDAO) ListResults(tx *dbs.Tx, reportNodeId int64, okState FindAll() return } + +// FindAvgCostMsWithTarget 获取某个对象的平均耗时 +func (this *ReportResultDAO) FindAvgCostMsWithTarget(tx *dbs.Tx, taskType reporterconfigs.TaskType, targetId int64) (float64, error) { + return this.Query(tx). + Attr("type", taskType). + Attr("targetId", targetId). + Where("reportNodeId IN (SELECT id FROM "+SharedReportNodeDAO.Table+" WHERE state=1 AND isOn=1)"). + Attr("isOk", true). + Gt("updatedAt", time.Now().Unix()-600). + Avg("costMs", 0) +} + +// FindAvgLevelWithTarget 获取某个对象的平均级别 +func (this *ReportResultDAO) FindAvgLevelWithTarget(tx *dbs.Tx, taskType reporterconfigs.TaskType, targetId int64) (string, error) { + ones, _, err := this.Query(tx). + Result("COUNT(*) AS c, level"). + Attr("type", taskType). + Attr("targetId", targetId). + Where("reportNodeId IN (SELECT id FROM "+SharedReportNodeDAO.Table+" WHERE state=1 AND isOn=1)"). + Gt("updatedAt", time.Now().Unix()-600). + Group("level"). + FindOnes() + if err != nil { + return "", err + } + + if len(ones) == 0 { + return reporterconfigs.ReportLevelNormal, nil + } + + var total = 0 + var levelMap = map[string]int{} // code => count + for _, one := range ones { + var c = one.GetInt("c") + total += c + levelMap[one.GetString("level")] = c + } + if total == 0 { + return reporterconfigs.ReportLevelNormal, nil + } + + var half = total / 2 + for _, def := range reporterconfigs.FindAllReportLevels() { + c, ok := levelMap[def.Code] + if ok { + half -= c + if half <= 0 { + return def.Code, nil + } + } + } + + return "", nil +} + +// FindConnectivityWithTarget 获取某个对象的连通率 +func (this *ReportResultDAO) FindConnectivityWithTarget(tx *dbs.Tx, taskType reporterconfigs.TaskType, targetId int64) (float64, error) { + // 已汇报数据的数量 + total, err := this.Query(tx). + Attr("type", taskType). + Attr("targetId", targetId). + Where("reportNodeId IN (SELECT id FROM "+SharedReportNodeDAO.Table+" WHERE state=1 AND isOn=1)"). + Gt("updatedAt", time.Now().Unix()-600). + Count() + if err != nil { + return 0, err + } + if total == 0 { + return 0, nil + } + + // 连通的数量 + countConnected, err := this.Query(tx). + Attr("type", taskType). + Attr("targetId", targetId). + Where("reportNodeId IN (SELECT id FROM "+SharedReportNodeDAO.Table+" WHERE state=1 AND isOn=1)"). + Attr("isOk", true). + Gt("updatedAt", time.Now().Unix()-600). + Count() + if err != nil { + return 0, err + } + return float64(countConnected) / float64(total), nil +} diff --git a/internal/db/models/report_result_model.go b/internal/db/models/report_result_model.go index f514cc85..3704dfae 100644 --- a/internal/db/models/report_result_model.go +++ b/internal/db/models/report_result_model.go @@ -9,6 +9,7 @@ type ReportResult struct { UpdatedAt uint64 `field:"updatedAt"` // 更新时间 ReportNodeId uint32 `field:"reportNodeId"` // 监控节点ID IsOk uint8 `field:"isOk"` // 是否可连接 + Level string `field:"level"` // 级别 CostMs float64 `field:"costMs"` // 单次连接花费的时间 Error string `field:"error"` // 产生的错误信息 CountUp uint32 `field:"countUp"` // 连续上线次数 @@ -23,6 +24,7 @@ type ReportResultOperator struct { UpdatedAt interface{} // 更新时间 ReportNodeId interface{} // 监控节点ID IsOk interface{} // 是否可连接 + Level interface{} // 级别 CostMs interface{} // 单次连接花费的时间 Error interface{} // 产生的错误信息 CountUp interface{} // 连续上线次数 diff --git a/internal/rpc/services/service_admin.go b/internal/rpc/services/service_admin.go index 0bc8b7c5..cd99c34c 100644 --- a/internal/rpc/services/service_admin.go +++ b/internal/rpc/services/service_admin.go @@ -657,6 +657,19 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com result.NsNodeUpgradeInfo = upgradeInfo } + // Report节点升级信息 + if isPlus { + upgradeInfo := &pb.ComposeAdminDashboardResponse_UpgradeInfo{ + NewVersion: teaconst.ReportNodeVersion, + } + countNodes, err := models.SharedReportNodeDAO.CountAllLowerVersionNodes(tx, upgradeInfo.NewVersion) + if err != nil { + return nil, err + } + upgradeInfo.CountNodes = countNodes + result.ReportNodeUpgradeInfo = upgradeInfo + } + // 域名排行 if isPlus { topDomainStats, err := stats.SharedServerDomainHourlyStatDAO.FindTopDomainStats(tx, hourFrom, hourTo, 10)