mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-12-10 00:00:26 +08:00
实现基本的监控图表
This commit is contained in:
@@ -91,6 +91,10 @@ func (this *RPCClient) NodeIPAddressRPC() pb.NodeIPAddressServiceClient {
|
|||||||
return pb.NewNodeIPAddressServiceClient(this.pickConn())
|
return pb.NewNodeIPAddressServiceClient(this.pickConn())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *RPCClient) NodeValueRPC() pb.NodeValueServiceClient {
|
||||||
|
return pb.NewNodeValueServiceClient(this.pickConn())
|
||||||
|
}
|
||||||
|
|
||||||
func (this *RPCClient) ServerRPC() pb.ServerServiceClient {
|
func (this *RPCClient) ServerRPC() pb.ServerServiceClient {
|
||||||
return pb.NewServerServiceClient(this.pickConn())
|
return pb.NewServerServiceClient(this.pickConn())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/groups"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/groups"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/monitor"
|
||||||
clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
|
clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||||
"github.com/iwind/TeaGo"
|
"github.com/iwind/TeaGo"
|
||||||
@@ -37,6 +38,12 @@ func init() {
|
|||||||
Post("/node/start", new(node.StartAction)).
|
Post("/node/start", new(node.StartAction)).
|
||||||
Post("/node/stop", new(node.StopAction)).
|
Post("/node/stop", new(node.StopAction)).
|
||||||
Post("/node/up", new(node.UpAction)).
|
Post("/node/up", new(node.UpAction)).
|
||||||
|
Get("/node/monitor", new(monitor.IndexAction)).
|
||||||
|
Post("/node/monitor/cpu", new(monitor.CpuAction)).
|
||||||
|
Post("/node/monitor/memory", new(monitor.MemoryAction)).
|
||||||
|
Post("/node/monitor/load", new(monitor.LoadAction)).
|
||||||
|
Post("/node/monitor/trafficIn", new(monitor.TrafficInAction)).
|
||||||
|
Post("/node/monitor/trafficOut", new(monitor.TrafficOutAction)).
|
||||||
|
|
||||||
// 分组相关
|
// 分组相关
|
||||||
Get("/groups", new(groups.IndexAction)).
|
Get("/groups", new(groups.IndexAction)).
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package monitor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CpuAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CpuAction) RunPost(params struct {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
resp, err := this.RPC().NodeValueRPC().ListNodeValues(this.AdminContext(), &pb.ListNodeValuesRequest{
|
||||||
|
Role: "node",
|
||||||
|
NodeId: params.NodeId,
|
||||||
|
Item: nodeconfigs.NodeValueItemCPU,
|
||||||
|
Range: nodeconfigs.NodeValueRangeMinute,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
valuesMap := map[string]float32{} // YmdHi => usage
|
||||||
|
for _, v := range resp.NodeValues {
|
||||||
|
if len(v.ValueJSON) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
valueMap := maps.Map{}
|
||||||
|
err = json.Unmarshal(v.ValueJSON, &valueMap)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
valuesMap[timeutil.FormatTime("YmdHi", v.CreatedAt)] = valueMap.GetFloat32("usage") * 100
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过去一个小时
|
||||||
|
result := []maps.Map{}
|
||||||
|
for i := 60; i >= 1; i-- {
|
||||||
|
timestamp := time.Now().Unix() - int64(i)*60
|
||||||
|
minute := timeutil.FormatTime("YmdHi", timestamp)
|
||||||
|
total, ok := valuesMap[minute]
|
||||||
|
if ok {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": total,
|
||||||
|
"text": fmt.Sprintf("%.2f%%", total),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": 0,
|
||||||
|
"text": "0.0%",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["values"] = result
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package monitor
|
||||||
|
|
||||||
|
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
|
||||||
|
type IndexAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) Init() {
|
||||||
|
this.Nav("", "node", "monitor")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunGet(params struct {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
this.Data["nodeId"] = params.NodeId
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package monitor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LoadAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *LoadAction) RunPost(params struct {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
resp, err := this.RPC().NodeValueRPC().ListNodeValues(this.AdminContext(), &pb.ListNodeValuesRequest{
|
||||||
|
Role: "node",
|
||||||
|
NodeId: params.NodeId,
|
||||||
|
Item: nodeconfigs.NodeValueItemLoad,
|
||||||
|
Range: nodeconfigs.NodeValueRangeMinute,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
valuesMap := map[string]float32{} // YmdHi => load5m
|
||||||
|
for _, v := range resp.NodeValues {
|
||||||
|
if len(v.ValueJSON) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
valueMap := maps.Map{}
|
||||||
|
err = json.Unmarshal(v.ValueJSON, &valueMap)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
valuesMap[timeutil.FormatTime("YmdHi", v.CreatedAt)] = valueMap.GetFloat32("load5m")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过去一个小时
|
||||||
|
result := []maps.Map{}
|
||||||
|
for i := 60; i >= 1; i-- {
|
||||||
|
timestamp := time.Now().Unix() - int64(i)*60
|
||||||
|
minute := timeutil.FormatTime("YmdHi", timestamp)
|
||||||
|
total, ok := valuesMap[minute]
|
||||||
|
if ok {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": total,
|
||||||
|
"text": fmt.Sprintf("5分钟: %.2f", total),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": 0,
|
||||||
|
"text": "5分钟: 0.0",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["values"] = result
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package monitor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MemoryAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *MemoryAction) RunPost(params struct {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
resp, err := this.RPC().NodeValueRPC().ListNodeValues(this.AdminContext(), &pb.ListNodeValuesRequest{
|
||||||
|
Role: "node",
|
||||||
|
NodeId: params.NodeId,
|
||||||
|
Item: nodeconfigs.NodeValueItemMemory,
|
||||||
|
Range: nodeconfigs.NodeValueRangeMinute,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
valuesMap := map[string]float32{} // YmdHi => usage
|
||||||
|
for _, v := range resp.NodeValues {
|
||||||
|
if len(v.ValueJSON) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
valueMap := maps.Map{}
|
||||||
|
err = json.Unmarshal(v.ValueJSON, &valueMap)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
valuesMap[timeutil.FormatTime("YmdHi", v.CreatedAt)] = valueMap.GetFloat32("usage") * 100
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过去一个小时
|
||||||
|
result := []maps.Map{}
|
||||||
|
for i := 60; i >= 1; i-- {
|
||||||
|
timestamp := time.Now().Unix() - int64(i)*60
|
||||||
|
minute := timeutil.FormatTime("YmdHi", timestamp)
|
||||||
|
total, ok := valuesMap[minute]
|
||||||
|
if ok {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": total,
|
||||||
|
"text": fmt.Sprintf("%.2f%%", total),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": 0,
|
||||||
|
"text": "0.0%",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["values"] = result
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package monitor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TrafficInAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *TrafficInAction) RunPost(params struct {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
resp, err := this.RPC().NodeValueRPC().ListNodeValues(this.AdminContext(), &pb.ListNodeValuesRequest{
|
||||||
|
Role: "node",
|
||||||
|
NodeId: params.NodeId,
|
||||||
|
Item: nodeconfigs.NodeValueItemTrafficIn,
|
||||||
|
Range: nodeconfigs.NodeValueRangeMinute,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
valuesMap := map[string]int64{} // YmdHi => bytes
|
||||||
|
for _, v := range resp.NodeValues {
|
||||||
|
if len(v.ValueJSON) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
valueMap := maps.Map{}
|
||||||
|
err = json.Unmarshal(v.ValueJSON, &valueMap)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
valuesMap[timeutil.FormatTime("YmdHi", v.CreatedAt)] = valueMap.GetInt64("total")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过去一个小时
|
||||||
|
result := []maps.Map{}
|
||||||
|
for i := 60; i >= 1; i-- {
|
||||||
|
timestamp := time.Now().Unix() - int64(i)*60
|
||||||
|
minute := timeutil.FormatTime("YmdHi", timestamp)
|
||||||
|
total, ok := valuesMap[minute]
|
||||||
|
if ok {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": total,
|
||||||
|
"text": numberutils.FormatBytes(total),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": 0,
|
||||||
|
"text": numberutils.FormatBytes(0),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["values"] = result
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package monitor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TrafficOutAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *TrafficOutAction) RunPost(params struct {
|
||||||
|
NodeId int64
|
||||||
|
}) {
|
||||||
|
resp, err := this.RPC().NodeValueRPC().ListNodeValues(this.AdminContext(), &pb.ListNodeValuesRequest{
|
||||||
|
Role: "node",
|
||||||
|
NodeId: params.NodeId,
|
||||||
|
Item: nodeconfigs.NodeValueItemTrafficOut,
|
||||||
|
Range: nodeconfigs.NodeValueRangeMinute,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
valuesMap := map[string]int64{} // YmdHi => bytes
|
||||||
|
for _, v := range resp.NodeValues {
|
||||||
|
if len(v.ValueJSON) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
valueMap := maps.Map{}
|
||||||
|
err = json.Unmarshal(v.ValueJSON, &valueMap)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
valuesMap[timeutil.FormatTime("YmdHi", v.CreatedAt)] = valueMap.GetInt64("total")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过去一个小时
|
||||||
|
result := []maps.Map{}
|
||||||
|
for i := 60; i >= 1; i-- {
|
||||||
|
timestamp := time.Now().Unix() - int64(i)*60
|
||||||
|
minute := timeutil.FormatTime("YmdHi", timestamp)
|
||||||
|
total, ok := valuesMap[minute]
|
||||||
|
if ok {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": total,
|
||||||
|
"text": numberutils.FormatBytes(total),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"label": timeutil.FormatTime("H:i", timestamp),
|
||||||
|
"value": 0,
|
||||||
|
"text": numberutils.FormatBytes(0),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data["values"] = result
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -107,6 +107,7 @@ func (this *userMustAuth) BeforeAction(actionPtr actions.ActionWrapper, paramNam
|
|||||||
}
|
}
|
||||||
action.Data["teaShowOpenSourceInfo"] = config.ShowOpenSourceInfo
|
action.Data["teaShowOpenSourceInfo"] = config.ShowOpenSourceInfo
|
||||||
action.Data["teaIsSuper"] = false
|
action.Data["teaIsSuper"] = false
|
||||||
|
action.Data["teaIsPlus"] = teaconst.IsPlus
|
||||||
action.Data["teaDemoEnabled"] = teaconst.IsDemo
|
action.Data["teaDemoEnabled"] = teaconst.IsDemo
|
||||||
action.Data["teaShowFinance"] = configloaders.ShowFinance()
|
action.Data["teaShowFinance"] = configloaders.ShowFinance()
|
||||||
if !action.Data.Has("teaSubMenu") {
|
if !action.Data.Has("teaSubMenu") {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
<menu-item :href="'/clusters/cluster?clusterId=' + clusterId">节点列表</menu-item>
|
<menu-item :href="'/clusters/cluster?clusterId=' + clusterId">节点列表</menu-item>
|
||||||
<span class="item">|</span>
|
<span class="item">|</span>
|
||||||
<menu-item :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + nodeId" code="node">节点详情</menu-item>
|
<menu-item :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + nodeId" code="node">节点详情</menu-item>
|
||||||
<menu-item :href="'/clusters/cluster/node/logs?clusterId=' + clusterId + '&nodeId=' + nodeId" code="log">运行日志</menu-item>
|
<menu-item :href="'/clusters/cluster/node/monitor?clusterId=' + clusterId + '&nodeId=' + nodeId" code="monitor" v-if="teaIsPlus">监控图表</menu-item>
|
||||||
|
<menu-item :href="'/clusters/cluster/node/logs?clusterId=' + clusterId + '&nodeId=' + nodeId" code="log">运行日志</menu-item>
|
||||||
<menu-item :href="'/clusters/cluster/node/update?clusterId=' + clusterId + '&nodeId=' + nodeId" code="update">修改设置</menu-item>
|
<menu-item :href="'/clusters/cluster/node/update?clusterId=' + clusterId + '&nodeId=' + nodeId" code="update">修改设置</menu-item>
|
||||||
<menu-item :href="'/clusters/cluster/node/install?clusterId=' + clusterId + '&nodeId=' + nodeId" code="install">安装节点</menu-item>
|
<menu-item :href="'/clusters/cluster/node/install?clusterId=' + clusterId + '&nodeId=' + nodeId" code="install">安装节点</menu-item>
|
||||||
</second-menu>
|
</second-menu>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
.chart-box {
|
||||||
|
height: 20em;
|
||||||
|
}
|
||||||
|
/*# sourceMappingURL=index.css.map */
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA;EACC,YAAA","file":"index.css"}
|
||||||
22
web/views/@default/clusters/cluster/node/monitor/index.html
Normal file
22
web/views/@default/clusters/cluster/node/monitor/index.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "../node_menu"}
|
||||||
|
|
||||||
|
{$var "header"}
|
||||||
|
<!-- echart -->
|
||||||
|
<script type="text/javascript" src="/js/echarts/echarts.min.js"></script>
|
||||||
|
{$end}
|
||||||
|
|
||||||
|
<h4>上行流量</h4>
|
||||||
|
<div class="chart-box" id="traffic-in-chart"></div>
|
||||||
|
|
||||||
|
<h4>下行流量</h4>
|
||||||
|
<div class="chart-box" id="traffic-out-chart"></div>
|
||||||
|
|
||||||
|
<h4>CPU</h4>
|
||||||
|
<div class="chart-box" id="cpu-chart"></div>
|
||||||
|
|
||||||
|
<h4>内存</h4>
|
||||||
|
<div class="chart-box" id="memory-chart"></div>
|
||||||
|
|
||||||
|
<h4>负载</h4>
|
||||||
|
<div class="chart-box" id="load-chart"></div>
|
||||||
217
web/views/@default/clusters/cluster/node/monitor/index.js
Normal file
217
web/views/@default/clusters/cluster/node/monitor/index.js
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.$delay(function () {
|
||||||
|
this.loadTrafficInChart()
|
||||||
|
this.loadTrafficOutChart()
|
||||||
|
this.loadCPUChart()
|
||||||
|
this.loadMemoryChart()
|
||||||
|
this.loadLoadChart()
|
||||||
|
|
||||||
|
let that = this
|
||||||
|
window.addEventListener("resize", function () {
|
||||||
|
that.resizeChart("traffic-in-chart")
|
||||||
|
that.resizeChart("traffic-out-chart")
|
||||||
|
that.resizeChart("cpu-chart")
|
||||||
|
that.resizeChart("memory-chart")
|
||||||
|
that.resizeChart("load-chart")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.loadTrafficInChart = function () {
|
||||||
|
this.$post(".trafficIn")
|
||||||
|
.params({
|
||||||
|
nodeId: this.nodeId
|
||||||
|
})
|
||||||
|
.success(function (resp) {
|
||||||
|
let values = resp.data.values
|
||||||
|
let maxFunc = function () {
|
||||||
|
let max = values.map(function (v) {
|
||||||
|
return v.value
|
||||||
|
}).$max() / 1024 / 1024
|
||||||
|
if (max < 1) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (max < 10) {
|
||||||
|
return 10
|
||||||
|
}
|
||||||
|
if (max < 100) {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
let valueFunc = function (v) {
|
||||||
|
return v.value / 1024 / 1024
|
||||||
|
}
|
||||||
|
this.reloadChart("traffic-in-chart", "", values, "M", maxFunc, valueFunc)
|
||||||
|
})
|
||||||
|
.done(function () {
|
||||||
|
this.$delay(function () {
|
||||||
|
this.loadTrafficInChart()
|
||||||
|
}, 30000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadTrafficOutChart = function () {
|
||||||
|
this.$post(".trafficOut")
|
||||||
|
.params({
|
||||||
|
nodeId: this.nodeId
|
||||||
|
})
|
||||||
|
.success(function (resp) {
|
||||||
|
let values = resp.data.values
|
||||||
|
let maxFunc = function () {
|
||||||
|
let max = values.map(function (v) {
|
||||||
|
return v.value
|
||||||
|
}).$max() / 1024 / 1024
|
||||||
|
if (max < 1) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (max < 10) {
|
||||||
|
return 10
|
||||||
|
}
|
||||||
|
if (max < 100) {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
let valueFunc = function (v) {
|
||||||
|
return v.value / 1024 / 1024
|
||||||
|
}
|
||||||
|
this.reloadChart("traffic-out-chart", "", values, "M", maxFunc, valueFunc)
|
||||||
|
})
|
||||||
|
.done(function () {
|
||||||
|
this.$delay(function () {
|
||||||
|
this.loadTrafficOutChart()
|
||||||
|
}, 30000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadCPUChart = function () {
|
||||||
|
this.$post(".cpu")
|
||||||
|
.params({
|
||||||
|
nodeId: this.nodeId
|
||||||
|
})
|
||||||
|
.success(function (resp) {
|
||||||
|
let values = resp.data.values
|
||||||
|
let maxFunc = function () {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
let valueFunc = function (v) {
|
||||||
|
return v.value
|
||||||
|
}
|
||||||
|
this.reloadChart("cpu-chart", "", values, "%", maxFunc, valueFunc)
|
||||||
|
})
|
||||||
|
.done(function () {
|
||||||
|
this.$delay(function () {
|
||||||
|
this.loadCPUChart()
|
||||||
|
}, 30000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadMemoryChart = function () {
|
||||||
|
this.$post(".memory")
|
||||||
|
.params({
|
||||||
|
nodeId: this.nodeId
|
||||||
|
})
|
||||||
|
.success(function (resp) {
|
||||||
|
let values = resp.data.values
|
||||||
|
let maxFunc = function () {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
let valueFunc = function (v) {
|
||||||
|
return v.value
|
||||||
|
}
|
||||||
|
this.reloadChart("memory-chart", "", values, "%", maxFunc, valueFunc)
|
||||||
|
})
|
||||||
|
.done(function () {
|
||||||
|
this.$delay(function () {
|
||||||
|
this.loadMemoryChart()
|
||||||
|
}, 30000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadLoadChart = function () {
|
||||||
|
this.$post(".load")
|
||||||
|
.params({
|
||||||
|
nodeId: this.nodeId
|
||||||
|
})
|
||||||
|
.success(function (resp) {
|
||||||
|
let values = resp.data.values
|
||||||
|
let maxFunc = function () {
|
||||||
|
let max = values.map(function (v) {
|
||||||
|
return v.value
|
||||||
|
}).$max()
|
||||||
|
if (max < 10) {
|
||||||
|
return 10
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
let valueFunc = function (v) {
|
||||||
|
return v.value
|
||||||
|
}
|
||||||
|
this.reloadChart("load-chart", "5分钟", values, "", maxFunc, valueFunc)
|
||||||
|
})
|
||||||
|
.done(function () {
|
||||||
|
this.$delay(function () {
|
||||||
|
this.loadLoadChart()
|
||||||
|
}, 30000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.reloadChart = function (chartId, name, stats, unit, maxFunc, valueFunc) {
|
||||||
|
let chartBox = document.getElementById(chartId)
|
||||||
|
if (chartBox == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let chart = echarts.init(chartBox)
|
||||||
|
let option = {
|
||||||
|
xAxis: {
|
||||||
|
data: stats.map(function (stat) {
|
||||||
|
return stat.label
|
||||||
|
})
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
max: maxFunc(),
|
||||||
|
axisLabel: {
|
||||||
|
formatter: function (value) {
|
||||||
|
return value + unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
show: true,
|
||||||
|
trigger: "item",
|
||||||
|
formatter: function (args) {
|
||||||
|
return stats[args.dataIndex].label + ": " + stats[args.dataIndex].text
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: 50,
|
||||||
|
top: 10,
|
||||||
|
right: 20,
|
||||||
|
bottom: 20
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: name,
|
||||||
|
type: "line",
|
||||||
|
data: stats.map(valueFunc),
|
||||||
|
itemStyle: {
|
||||||
|
color: "#9DD3E8"
|
||||||
|
},
|
||||||
|
areaStyle: {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
animation: true
|
||||||
|
}
|
||||||
|
chart.setOption(option)
|
||||||
|
chart.resize()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resizeChart = function (chartId) {
|
||||||
|
let chartBox = document.getElementById(chartId)
|
||||||
|
if (chartBox == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let chart = echarts.init(chartBox)
|
||||||
|
chart.resize()
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
.chart-box {
|
||||||
|
height: 20em;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user