mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-03 20:40:26 +08:00
节点列表增加下行流量,节点列表可以按CPU、内存、下行流量排序
This commit is contained in:
@@ -44,7 +44,7 @@ func init() {
|
||||
Post("/up", new(node.UpAction)).
|
||||
Get("/thresholds", new(thresholds.IndexAction)).
|
||||
Get("/detail", new(node.DetailAction)).
|
||||
Get("/boards", new(nodeboards.IndexAction)).
|
||||
GetPost("/boards", new(nodeboards.IndexAction)).
|
||||
|
||||
// 分组相关
|
||||
Prefix("/clusters/cluster/groups").
|
||||
|
||||
@@ -178,3 +178,31 @@ func (this *IndexAction) RunGet(params struct {
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
}) {
|
||||
resp, err := this.RPC().ServerStatBoardRPC().ComposeServerStatNodeBoard(this.AdminContext(), &pb.ComposeServerStatNodeBoardRequest{NodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["board"] = maps.Map{
|
||||
"isActive": resp.IsActive,
|
||||
"trafficInBytes": resp.TrafficInBytes,
|
||||
"trafficOutBytes": resp.TrafficOutBytes,
|
||||
"countConnections": resp.CountConnections,
|
||||
"countRequests": resp.CountRequests,
|
||||
"countAttackRequests": resp.CountAttackRequests,
|
||||
"cpuUsage": resp.CpuUsage,
|
||||
"memoryUsage": resp.MemoryUsage,
|
||||
"memoryTotalSize": resp.MemoryTotalSize,
|
||||
"load": resp.Load,
|
||||
"cacheDiskSize": resp.CacheDiskSize,
|
||||
"cacheMemorySize": resp.CacheMemorySize,
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ func (this *NodesAction) RunGet(params struct {
|
||||
InstalledState int
|
||||
ActiveState int
|
||||
Keyword string
|
||||
|
||||
CpuOrder string
|
||||
MemoryOrder string
|
||||
TrafficInOrder string
|
||||
TrafficOutOrder string
|
||||
}) {
|
||||
this.Data["groupId"] = params.GroupId
|
||||
this.Data["regionId"] = params.RegionId
|
||||
@@ -61,7 +66,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
page := this.NewPage(countResp.Count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
nodesResp, err := this.RPC().NodeRPC().ListEnabledNodesMatch(this.AdminContext(), &pb.ListEnabledNodesMatchRequest{
|
||||
var req = &pb.ListEnabledNodesMatchRequest{
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
NodeClusterId: params.ClusterId,
|
||||
@@ -70,7 +75,25 @@ func (this *NodesAction) RunGet(params struct {
|
||||
InstallState: types.Int32(params.InstalledState),
|
||||
ActiveState: types.Int32(params.ActiveState),
|
||||
Keyword: params.Keyword,
|
||||
})
|
||||
}
|
||||
if params.CpuOrder == "asc" {
|
||||
req.CpuAsc = true
|
||||
} else if params.CpuOrder == "desc" {
|
||||
req.CpuDesc = true
|
||||
} else if params.MemoryOrder == "asc" {
|
||||
req.MemoryAsc = true
|
||||
} else if params.MemoryOrder == "desc" {
|
||||
req.MemoryDesc = true
|
||||
} else if params.TrafficInOrder == "asc" {
|
||||
req.TrafficInAsc = true
|
||||
} else if params.TrafficInOrder == "desc" {
|
||||
req.TrafficInDesc = true
|
||||
} else if params.TrafficOutOrder == "asc" {
|
||||
req.TrafficOutAsc = true
|
||||
} else if params.TrafficOutOrder == "desc" {
|
||||
req.TrafficOutDesc = true
|
||||
}
|
||||
nodesResp, err := this.RPC().NodeRPC().ListEnabledNodesMatch(this.AdminContext(), req)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
@@ -146,13 +169,15 @@ func (this *NodesAction) RunGet(params struct {
|
||||
"error": node.InstallStatus.Error,
|
||||
},
|
||||
"status": maps.Map{
|
||||
"isActive": status.IsActive,
|
||||
"updatedAt": status.UpdatedAt,
|
||||
"hostname": status.Hostname,
|
||||
"cpuUsage": status.CPUUsage,
|
||||
"cpuUsageText": fmt.Sprintf("%.2f%%", status.CPUUsage*100),
|
||||
"memUsage": status.MemoryUsage,
|
||||
"memUsageText": fmt.Sprintf("%.2f%%", status.MemoryUsage*100),
|
||||
"isActive": status.IsActive,
|
||||
"updatedAt": status.UpdatedAt,
|
||||
"hostname": status.Hostname,
|
||||
"cpuUsage": status.CPUUsage,
|
||||
"cpuUsageText": fmt.Sprintf("%.2f%%", status.CPUUsage*100),
|
||||
"memUsage": status.MemoryUsage,
|
||||
"memUsageText": fmt.Sprintf("%.2f%%", status.MemoryUsage*100),
|
||||
"trafficInBytes": status.TrafficInBytes,
|
||||
"trafficOutBytes": status.TrafficOutBytes,
|
||||
},
|
||||
"cluster": maps.Map{
|
||||
"id": node.NodeCluster.Id,
|
||||
|
||||
48
web/public/js/components/common/sort-arrow.js
Normal file
48
web/public/js/components/common/sort-arrow.js
Normal file
@@ -0,0 +1,48 @@
|
||||
// 排序使用的箭头
|
||||
Vue.component("sort-arrow", {
|
||||
props: ["name"],
|
||||
data: function () {
|
||||
let url = window.location.toString()
|
||||
let order = ""
|
||||
let newArgs = []
|
||||
if (window.location.search != null && window.location.search.length > 0) {
|
||||
let queryString = window.location.search.substring(1)
|
||||
let pieces = queryString.split("&")
|
||||
let that = this
|
||||
pieces.forEach(function (v) {
|
||||
let eqIndex = v.indexOf("=")
|
||||
if (eqIndex > 0) {
|
||||
let argName = v.substring(0, eqIndex)
|
||||
let argValue = v.substring(eqIndex + 1)
|
||||
if (argName == that.name) {
|
||||
order = argValue
|
||||
} else if (argValue != "asc" && argValue != "desc") {
|
||||
newArgs.push(v)
|
||||
}
|
||||
} else {
|
||||
newArgs.push(v)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (order == "asc") {
|
||||
newArgs.push(this.name + "=")
|
||||
} else if (order == "desc") {
|
||||
newArgs.push(this.name + "=asc")
|
||||
} else {
|
||||
newArgs.push(this.name + "=desc")
|
||||
}
|
||||
|
||||
let qIndex = url.indexOf("?")
|
||||
if (qIndex > 0) {
|
||||
url = url.substring(0, qIndex) + "?" + newArgs.join("&")
|
||||
} else {
|
||||
url = url + "?" + newArgs.join("&")
|
||||
}
|
||||
|
||||
return {
|
||||
order: order,
|
||||
url: url
|
||||
}
|
||||
},
|
||||
template: `<a :href="url" title="排序"> <i class="ui icon long arrow small" :class="{down: order == 'asc', up: order == 'desc', 'down grey': order == '' || order == null}"></i></a>`
|
||||
})
|
||||
@@ -21,6 +21,8 @@ form .fields {
|
||||
table th.center,
|
||||
table td.center {
|
||||
text-align: center !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
table th.width10 {
|
||||
width: 10em;
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sources":["@layout_override.less"],"names":[],"mappings":"AACA,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,QAAO;EACrG,oCAAA;;AAGD,GAAG,OAAO,SAAU,MAAK,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,QAAS,QAAO;EACzF,oCAAA;;AAGD,GAAG,MAAM;EACR,kCAAA;;AAID,IACC;EACC,2BAAA;;AAKF,KAAK;EACJ,sBAAA;;AAGD,KAAK,KAAK;EACT,yBAAA;;AAID,KACC,GAAE;AADH,KACY,GAAE;EACZ,6BAAA;;AAFF,KAKC,GAAE;EACD,WAAA;;AANF,KASC,GAAE;EACD,UAAA;;AAVF,KAaC,GAAE;EACD,UAAA;;AAKF,QAAQ;EACP,qBAAA;;AAID,MAAM;EACL,uBAAA","file":"@layout_override.css"}
|
||||
{"version":3,"sources":["@layout_override.less"],"names":[],"mappings":"AACA,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,QAAO;EACrG,oCAAA;;AAGD,GAAG,OAAO,SAAU,MAAK,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,QAAS,QAAO;EACzF,oCAAA;;AAGD,GAAG,MAAM;EACR,kCAAA;;AAID,IACC;EACC,2BAAA;;AAKF,KAAK;EACJ,sBAAA;;AAGD,KAAK,KAAK;EACT,yBAAA;;AAID,KACC,GAAE;AADH,KACY,GAAE;EACZ,6BAAA;EACA,0BAAA;EACA,2BAAA;;AAJF,KAOC,GAAE;EACD,WAAA;;AARF,KAWC,GAAE;EACD,UAAA;;AAZF,KAeC,GAAE;EACD,UAAA;;AAKF,QAAQ;EACP,qBAAA;;AAID,MAAM;EACL,uBAAA","file":"@layout_override.css"}
|
||||
@@ -31,6 +31,8 @@ form {
|
||||
table {
|
||||
th.center, td.center {
|
||||
text-align: center !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
th.width10 {
|
||||
|
||||
@@ -9,17 +9,21 @@ Tea.context(function () {
|
||||
return (Math.round(count / 1000 / 1000 * 100) / 100) + "M"
|
||||
}
|
||||
|
||||
this.board.trafficInBytes = teaweb.formatBytes(this.board.trafficInBytes)
|
||||
this.board.trafficOutBytes = teaweb.formatBytes(this.board.trafficOutBytes)
|
||||
this.board.countConnections = this.formatCount(this.board.countConnections)
|
||||
this.board.countRequests = this.formatCount(this.board.countRequests)
|
||||
this.board.countAttackRequests = this.formatCount(this.board.countAttackRequests)
|
||||
this.board.cpuUsage = Math.round(this.board.cpuUsage * 100 * 100) / 100
|
||||
this.board.memoryUsage = Math.round(this.board.memoryUsage * 100 * 100) / 100
|
||||
this.board.memoryTotalSize = Math.round(this.board.memoryTotalSize / 1024 / 1024 / 1024)
|
||||
this.board.load = Math.round(this.board.load * 100) / 100
|
||||
this.board.cacheDiskSize = teaweb.formatBytes(this.board.cacheDiskSize)
|
||||
this.board.cacheMemorySize = teaweb.formatBytes(this.board.cacheMemorySize)
|
||||
this.loadBoard = function () {
|
||||
this.board.trafficInBytes = teaweb.formatBytes(this.board.trafficInBytes)
|
||||
this.board.trafficOutBytes = teaweb.formatBytes(this.board.trafficOutBytes)
|
||||
this.board.countConnections = this.formatCount(this.board.countConnections)
|
||||
this.board.countRequests = this.formatCount(this.board.countRequests)
|
||||
this.board.countAttackRequests = this.formatCount(this.board.countAttackRequests)
|
||||
this.board.cpuUsage = Math.round(this.board.cpuUsage * 100 * 100) / 100
|
||||
this.board.memoryUsage = Math.round(this.board.memoryUsage * 100 * 100) / 100
|
||||
this.board.memoryTotalSize = Math.round(this.board.memoryTotalSize / 1024 / 1024 / 1024)
|
||||
this.board.load = Math.round(this.board.load * 100) / 100
|
||||
this.board.cacheDiskSize = teaweb.formatBytes(this.board.cacheDiskSize)
|
||||
this.board.cacheMemorySize = teaweb.formatBytes(this.board.cacheMemorySize)
|
||||
}
|
||||
this.loadBoard()
|
||||
|
||||
|
||||
/**
|
||||
* 流量统计
|
||||
@@ -32,6 +36,26 @@ Tea.context(function () {
|
||||
this.reloadTopDomainsChart()
|
||||
this.reloadCPUChart()
|
||||
})
|
||||
this.$delay(function() {
|
||||
this.refreshBoard()
|
||||
}, 30000)
|
||||
|
||||
this.refreshBoard = function() {
|
||||
this.$post("$")
|
||||
.params({
|
||||
clusterId: this.clusterId,
|
||||
nodeId: this.node.id
|
||||
})
|
||||
.success(function (resp) {
|
||||
this.board = resp.data.board
|
||||
this.loadBoard()
|
||||
})
|
||||
.done(function () {
|
||||
this.$delay(function () {
|
||||
this.refreshBoard()
|
||||
}, 60000)
|
||||
})
|
||||
}
|
||||
|
||||
this.selectTrafficTab = function (tab) {
|
||||
this.trafficTab = tab
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{$template "menu"}
|
||||
|
||||
<form class="ui form" action="/clusters/cluster" v-show="countAll > 0">
|
||||
<form class="ui form" action="/clusters/cluster/nodes" v-show="countAll > 0">
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field" v-if="regions.length > 0">
|
||||
@@ -35,7 +35,8 @@
|
||||
<input type="text" name="keyword" placeholder="关键词" v-model="keyword" style="width:10em"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<button class="ui button" type="submit">搜索</button>
|
||||
<button class="ui button" type="submit">搜索</button>
|
||||
<a :href="'/clusters/cluster/nodes?clusterId=' + clusterId" v-if="regionId >0 || groupId > 0 || installState > 0 || activeState > 0 || keyword.length > 0">[清除条件]</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -55,28 +56,24 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>节点名称</th>
|
||||
<th>所属区域</th>
|
||||
<th>所属分组</th>
|
||||
<th>IP</th>
|
||||
<th class="width10">DNS线路</th>
|
||||
<th class="width5 center">CPU</th>
|
||||
<th class="width5 center">内存</th>
|
||||
<!--<th>流量</th>
|
||||
<th>连接数</th>-->
|
||||
<th class="width5 center">CPU<sort-arrow name="cpuOrder"></sort-arrow></th>
|
||||
<th class="width5 center">内存<sort-arrow name="memoryOrder"></sort-arrow></th>
|
||||
<th class="center" style="width: 7em">下行流量<sort-arrow name="trafficOutOrder"></sort-arrow></th>
|
||||
<th class="two wide center">状态</th>
|
||||
<th class="two op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="node in nodes">
|
||||
<td>{{node.name}}</td>
|
||||
<td>
|
||||
<span v-if="node.region != null">{{node.region.name}}</span>
|
||||
<span v-else class="disabled">-</span>
|
||||
<td>{{node.name}}
|
||||
<div style="margin-top: 0.5em" v-if="node.region != null">
|
||||
<tiny-label class="basic">区域:{{node.region.name}}</tiny-label>
|
||||
</div>
|
||||
<div style="margin-top: 0.5em" v-if="node.group != null">
|
||||
<tiny-label class="basic">分组:{{node.group.name}}</tiny-label>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="node.group != null">{{node.group.name}}</span>
|
||||
<span v-else class="disabled">-</span>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="node.ipAddresses.length == 0" class="disabled">-</span>
|
||||
<div v-else class="address-box">
|
||||
@@ -104,6 +101,10 @@
|
||||
<span v-if="node.status.isActive" :class="{red:node.status.memUsage > 0.80}">{{node.status.memUsageText}}</span>
|
||||
<span v-else class="disabled">-</span>
|
||||
</td>
|
||||
<td class="center">
|
||||
<span v-if="node.status.isActive && node.status.trafficOutBytes > 0">{{teaweb.formatBytes(node.status.trafficOutBytes)}}<br/><span class="grey small">/分钟</span></span>
|
||||
<span v-else class="disabled">-</span>
|
||||
</td>
|
||||
<td class="center">
|
||||
<div v-if="!node.isUp">
|
||||
<span class="red">健康问题下线</span>
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
Tea.context(function () {
|
||||
this.deleteNode = function (nodeId) {
|
||||
teaweb.confirm("确定要删除这个节点吗?", function () {
|
||||
this.$post("/nodes/delete")
|
||||
.params({
|
||||
nodeId: nodeId
|
||||
})
|
||||
.refresh();
|
||||
})
|
||||
}
|
||||
this.teaweb = teaweb
|
||||
|
||||
this.upNode = function (nodeId) {
|
||||
teaweb.confirm("确定要手动上线此节点吗?", function () {
|
||||
this.$post("/clusters/cluster/node/up")
|
||||
.params({
|
||||
nodeId: nodeId
|
||||
})
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
this.deleteNode = function (nodeId) {
|
||||
teaweb.confirm("确定要删除这个节点吗?", function () {
|
||||
this.$post("/nodes/delete")
|
||||
.params({
|
||||
nodeId: nodeId
|
||||
})
|
||||
.refresh();
|
||||
})
|
||||
}
|
||||
|
||||
this.upNode = function (nodeId) {
|
||||
teaweb.confirm("确定要手动上线此节点吗?", function () {
|
||||
this.$post("/clusters/cluster/node/up")
|
||||
.params({
|
||||
nodeId: nodeId
|
||||
})
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user