mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	实现基本的监控图表
This commit is contained in:
		@@ -91,6 +91,10 @@ func (this *RPCClient) NodeIPAddressRPC() pb.NodeIPAddressServiceClient {
 | 
			
		||||
	return pb.NewNodeIPAddressServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) NodeValueRPC() pb.NodeValueServiceClient {
 | 
			
		||||
	return pb.NewNodeValueServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) ServerRPC() pb.ServerServiceClient {
 | 
			
		||||
	return pb.NewServerServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"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/node"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/monitor"
 | 
			
		||||
	clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
@@ -37,6 +38,12 @@ func init() {
 | 
			
		||||
			Post("/node/start", new(node.StartAction)).
 | 
			
		||||
			Post("/node/stop", new(node.StopAction)).
 | 
			
		||||
			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)).
 | 
			
		||||
 
 | 
			
		||||
@@ -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["teaIsSuper"] = false
 | 
			
		||||
	action.Data["teaIsPlus"] = teaconst.IsPlus
 | 
			
		||||
	action.Data["teaDemoEnabled"] = teaconst.IsDemo
 | 
			
		||||
	action.Data["teaShowFinance"] = configloaders.ShowFinance()
 | 
			
		||||
	if !action.Data.Has("teaSubMenu") {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,8 @@
 | 
			
		||||
	<menu-item :href="'/clusters/cluster?clusterId=' + clusterId">节点列表</menu-item>
 | 
			
		||||
	<span class="item">|</span>
 | 
			
		||||
	<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/install?clusterId=' + clusterId + '&nodeId=' + nodeId" code="install">安装节点</menu-item>
 | 
			
		||||
</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