实现一些阈值设置细节

This commit is contained in:
刘祥超
2021-05-05 19:51:13 +08:00
parent e6970abcb8
commit c350fceef3
13 changed files with 258 additions and 61 deletions

View File

@@ -5,6 +5,7 @@ import (
"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" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/monitor"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/thresholds"
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"
@@ -45,6 +46,7 @@ func init() {
Post("/node/monitor/trafficIn", new(monitor.TrafficInAction)). Post("/node/monitor/trafficIn", new(monitor.TrafficInAction)).
Post("/node/monitor/trafficOut", new(monitor.TrafficOutAction)). Post("/node/monitor/trafficOut", new(monitor.TrafficOutAction)).
Post("/node/monitor/connections", new(monitor.ConnectionsAction)). Post("/node/monitor/connections", new(monitor.ConnectionsAction)).
Get("/node/thresholds", new(thresholds.IndexAction)).
// 分组相关 // 分组相关
Get("/groups", new(groups.IndexAction)). Get("/groups", new(groups.IndexAction)).

View File

@@ -0,0 +1,54 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package thresholds
import (
"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"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "node", "threshold")
}
func (this *IndexAction) RunGet(params struct {
ClusterId int64
NodeId int64
}) {
this.Data["nodeId"] = params.NodeId
// 列出所有阈值
thresholdsResp, err := this.RPC().NodeThresholdRPC().FindAllEnabledNodeThresholds(this.AdminContext(), &pb.FindAllEnabledNodeThresholdsRequest{
Role: "node",
NodeClusterId: params.ClusterId,
NodeId: params.NodeId,
})
if err != nil {
this.ErrorPage(err)
return
}
thresholdMaps := []maps.Map{}
for _, threshold := range thresholdsResp.NodeThresholds {
thresholdMaps = append(thresholdMaps, maps.Map{
"id": threshold.Id,
"itemName": nodeconfigs.FindNodeValueItemName(threshold.Item),
"paramName": nodeconfigs.FindNodeValueItemParamName(threshold.Item, threshold.Param),
"operatorName": nodeconfigs.FindNodeValueOperatorName(threshold.Operator),
"value": nodeconfigs.UnmarshalNodeValue(threshold.ValueJSON),
"sumMethodName": nodeconfigs.FindNodeValueSumMethodName(threshold.SumMethod),
"duration": threshold.Duration,
"durationUnitName": nodeconfigs.FindNodeValueDurationUnitName(threshold.DurationUnit),
"isOn": threshold.IsOn,
})
}
this.Data["thresholds"] = thresholdMaps
this.Show()
}

View File

@@ -20,8 +20,10 @@ func (this *CreatePopupAction) Init() {
func (this *CreatePopupAction) RunGet(params struct { func (this *CreatePopupAction) RunGet(params struct {
ClusterId int64 ClusterId int64
NodeId int64
}) { }) {
this.Data["clusterId"] = params.ClusterId this.Data["clusterId"] = params.ClusterId
this.Data["nodeId"] = params.NodeId
this.Data["items"] = nodeconfigs.FindAllNodeValueItemDefinitions() this.Data["items"] = nodeconfigs.FindAllNodeValueItemDefinitions()
this.Data["operators"] = nodeconfigs.FindAllNodeValueOperatorDefinitions() this.Data["operators"] = nodeconfigs.FindAllNodeValueOperatorDefinitions()
@@ -29,16 +31,17 @@ func (this *CreatePopupAction) RunGet(params struct {
} }
func (this *CreatePopupAction) RunPost(params struct { func (this *CreatePopupAction) RunPost(params struct {
ClusterId int64 ClusterId int64
NodeId int64 NodeId int64
Item string Item string
Param string Param string
SumMethod string SumMethod string
Operator string Operator string
Value string Value string
Duration int32 Duration int32
DurationUnit string DurationUnit string
Message string Message string
NotifyDuration int32
Must *actions.Must Must *actions.Must
CSRF *actionutils.CSRF CSRF *actionutils.CSRF
@@ -53,16 +56,18 @@ func (this *CreatePopupAction) RunPost(params struct {
return return
} }
resp, err := this.RPC().NodeThresholdRPC().CreateNodeThreshold(this.AdminContext(), &pb.CreateNodeThresholdRequest{ resp, err := this.RPC().NodeThresholdRPC().CreateNodeThreshold(this.AdminContext(), &pb.CreateNodeThresholdRequest{
NodeClusterId: params.ClusterId, Role: "node",
NodeId: params.NodeId, NodeClusterId: params.ClusterId,
Item: params.Item, NodeId: params.NodeId,
Param: params.Param, Item: params.Item,
Operator: params.Operator, Param: params.Param,
ValueJSON: valueJSON, Operator: params.Operator,
Message: params.Message, ValueJSON: valueJSON,
Duration: params.Duration, Message: params.Message,
DurationUnit: params.DurationUnit, Duration: params.Duration,
SumMethod: params.SumMethod, DurationUnit: params.DurationUnit,
SumMethod: params.SumMethod,
NotifyDuration: params.NotifyDuration,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -23,6 +23,7 @@ func (this *IndexAction) RunGet(params struct {
}) { }) {
// 列出所有阈值 // 列出所有阈值
thresholdsResp, err := this.RPC().NodeThresholdRPC().FindAllEnabledNodeThresholds(this.AdminContext(), &pb.FindAllEnabledNodeThresholdsRequest{ thresholdsResp, err := this.RPC().NodeThresholdRPC().FindAllEnabledNodeThresholds(this.AdminContext(), &pb.FindAllEnabledNodeThresholdsRequest{
Role: "node",
NodeClusterId: params.ClusterId, NodeClusterId: params.ClusterId,
NodeId: 0, NodeId: 0,
}) })
@@ -33,16 +34,25 @@ func (this *IndexAction) RunGet(params struct {
thresholdMaps := []maps.Map{} thresholdMaps := []maps.Map{}
for _, threshold := range thresholdsResp.NodeThresholds { for _, threshold := range thresholdsResp.NodeThresholds {
var nodeMap maps.Map = nil
if threshold.Node != nil {
nodeMap = maps.Map{
"id": threshold.Node.Id,
"name": threshold.Node.Name,
}
}
thresholdMaps = append(thresholdMaps, maps.Map{ thresholdMaps = append(thresholdMaps, maps.Map{
"id": threshold.Id, "id": threshold.Id,
"itemName": nodeconfigs.FindNodeValueItemName(threshold.Item), "itemName": nodeconfigs.FindNodeValueItemName(threshold.Item),
"paramName": nodeconfigs.FindNodeValueItemParamName(threshold.Item, threshold.Param), "paramName": nodeconfigs.FindNodeValueItemParamName(threshold.Item, threshold.Param),
"operatorName": nodeconfigs.FindNodeValueOperatorName(threshold.Operator), "operatorName": nodeconfigs.FindNodeValueOperatorName(threshold.Operator),
"value": string(threshold.ValueJSON), "value": nodeconfigs.UnmarshalNodeValue(threshold.ValueJSON),
"sumMethodName": nodeconfigs.FindNodeValueSumMethodName(threshold.SumMethod), "sumMethodName": nodeconfigs.FindNodeValueSumMethodName(threshold.SumMethod),
"duration": threshold.Duration, "duration": threshold.Duration,
"durationUnitName": nodeconfigs.FindNodeValueDurationUnitName(threshold.DurationUnit), "durationUnitName": nodeconfigs.FindNodeValueDurationUnitName(threshold.DurationUnit),
"isOn": threshold.IsOn, "isOn": threshold.IsOn,
"node": nodeMap,
}) })
} }
this.Data["thresholds"] = thresholdMaps this.Data["thresholds"] = thresholdMaps

View File

@@ -46,31 +46,33 @@ func (this *UpdatePopupAction) RunGet(params struct {
} }
this.Data["threshold"] = maps.Map{ this.Data["threshold"] = maps.Map{
"id": threshold.Id, "id": threshold.Id,
"item": threshold.Item, "item": threshold.Item,
"param": threshold.Param, "param": threshold.Param,
"message": threshold.Message, "message": threshold.Message,
"value": nodeconfigs.UnmarshalNodeValue(threshold.ValueJSON), "notifyDuration": threshold.NotifyDuration,
"operator": threshold.Operator, "value": nodeconfigs.UnmarshalNodeValue(threshold.ValueJSON),
"duration": threshold.Duration, "operator": threshold.Operator,
"durationUnit": threshold.DurationUnit, "duration": threshold.Duration,
"isOn": threshold.IsOn, "durationUnit": threshold.DurationUnit,
"isOn": threshold.IsOn,
} }
this.Show() this.Show()
} }
func (this *UpdatePopupAction) RunPost(params struct { func (this *UpdatePopupAction) RunPost(params struct {
ThresholdId int64 ThresholdId int64
Item string Item string
Param string Param string
SumMethod string SumMethod string
Operator string Operator string
Value string Value string
Duration int32 Duration int32
DurationUnit string DurationUnit string
Message string Message string
IsOn bool NotifyDuration int32
IsOn bool
Must *actions.Must Must *actions.Must
CSRF *actionutils.CSRF CSRF *actionutils.CSRF
@@ -89,6 +91,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
Operator: params.Operator, Operator: params.Operator,
ValueJSON: valueJSON, ValueJSON: valueJSON,
Message: params.Message, Message: params.Message,
NotifyDuration: params.NotifyDuration,
Duration: params.Duration, Duration: params.Duration,
DurationUnit: params.DurationUnit, DurationUnit: params.DurationUnit,
SumMethod: params.SumMethod, SumMethod: params.SumMethod,

View File

@@ -197,6 +197,7 @@ func (this *ClusterHelper) checkThresholds(clusterId int64) (bool, error) {
return false, err return false, err
} }
resp, err := rpcClient.NodeThresholdRPC().CountAllEnabledNodeThresholds(rpcClient.Context(0), &pb.CountAllEnabledNodeThresholdsRequest{ resp, err := rpcClient.NodeThresholdRPC().CountAllEnabledNodeThresholds(rpcClient.Context(0), &pb.CountAllEnabledNodeThresholdsRequest{
Role: "node",
NodeClusterId: clusterId, NodeClusterId: clusterId,
}) })
if err != nil { if err != nil {

View File

@@ -3,6 +3,7 @@
<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/monitor?clusterId=' + clusterId + '&nodeId=' + nodeId" code="monitor" v-if="teaIsPlus">监控图表</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/thresholds?clusterId=' + clusterId + '&nodeId=' + nodeId" code="threshold" 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/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>

View File

@@ -6,10 +6,10 @@
<script type="text/javascript" src="/js/echarts/echarts.min.js"></script> <script type="text/javascript" src="/js/echarts/echarts.min.js"></script>
{$end} {$end}
<h4>上行流量</h4> <h4>上行流量(字节)</h4>
<div class="chart-box" id="traffic-in-chart"></div> <div class="chart-box" id="traffic-in-chart"></div>
<h4>下行流量</h4> <h4>下行流量(字节)</h4>
<div class="chart-box" id="traffic-out-chart"></div> <div class="chart-box" id="traffic-out-chart"></div>
<h4>连接数</h4> <h4>连接数</h4>

View File

@@ -0,0 +1,37 @@
{$layout}
{$template "../node_menu"}
<div style="margin-top: -1em">
<second-menu>
<menu-item @click.prevent="createThreshold">添加阈值</menu-item>
</second-menu>
</div>
<p class="comment" v-if="thresholds.length == 0">暂时还没有设置阈值。</p>
<table class="ui table selectable celled" v-if="thresholds.length > 0">
<thead>
<tr>
<th>监控项</th>
<th>参数</th>
<th>操作符</th>
<th>对比值</th>
<th>统计时间段</th>
<th class="two wide">状态</th>
<th class="two op">操作</th>
</tr>
</thead>
<tr v-for="threshold in thresholds">
<td>{{threshold.itemName}}</td>
<td>{{threshold.paramName}}</td>
<td>{{threshold.operatorName}}</td>
<td>{{threshold.value}}</td>
<td>{{threshold.duration}}{{threshold.durationUnitName}}</td>
<td>
<label-on :v-is-on="threshold.isOn"></label-on>
</td>
<td>
<a href="" @click.prevent="updateThreshold(threshold.id)">修改</a> &nbsp;
<a href="" @click.prevent="deleteThreshold(threshold.id)">删除</a>
</td>
</tr>
</table>

View File

@@ -0,0 +1,41 @@
Tea.context(function () {
this.createThreshold = function () {
teaweb.popup(Tea.url("/clusters/cluster/settings/thresholds/createPopup", {
clusterId: this.clusterId,
nodeId: this.nodeId
}), {
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
})
}
this.updateThreshold = function (thresholdId) {
teaweb.popup(Tea.url("/clusters/cluster/settings/thresholds/updatePopup", {
thresholdId: thresholdId
}), {
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
})
}
this.deleteThreshold = function (thresholdId) {
let that = this
teaweb.confirm("确定要删除这个阈值吗?", function () {
that.$post(".delete")
.params({
thresholdId: thresholdId
})
.success(function () {
teaweb.success("删除成功", function () {
teaweb.reload()
})
})
})
}
})

View File

@@ -4,6 +4,7 @@
<form class="ui form" data-tea-action="$" data-tea-success="success"> <form class="ui form" data-tea-action="$" data-tea-success="success">
<csrf-token></csrf-token> <csrf-token></csrf-token>
<input type="hidden" name="clusterId" :value="clusterId" /> <input type="hidden" name="clusterId" :value="clusterId" />
<input type="hidden" name="nodeId" :value="nodeId"/>
<input type="hidden" name="sumMethod" value="avg"/> <input type="hidden" name="sumMethod" value="avg"/>
<table class="ui table definition selectable"> <table class="ui table definition selectable">
@@ -55,12 +56,31 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>消息</td> <td colspan="2"><more-options-indicator></more-options-indicator></td>
<td>
<textarea rows="2" maxlength="100" name="message"></textarea>
<p class="comment">触发阈值时的消息提示。</p>
</td>
</tr> </tr>
<tbody v-show="moreOptionsVisible">
<tr>
<td>消息</td>
<td>
<textarea rows="2" maxlength="100" name="message"></textarea>
<p class="comment">触发阈值时的消息提示。</p>
</td>
</tr>
<tr>
<td>消息通知间隔</td>
<td>
<div class="ui fields inline">
<div class="ui field">
<input type="text" name="notifyDuration" value="10" style="width: 5em"/>
</div>
<div class="ui field">
分钟
</div>
</div>
<p class="comment">在此间隔内将不会重复发送跟此阈值相关的消息。</p>
</td>
</tr>
</tbody>
</table> </table>
<submit-btn></submit-btn> <submit-btn></submit-btn>

View File

@@ -7,7 +7,7 @@
</first-menu> </first-menu>
<p class="comment" v-if="thresholds.length == 0">暂时还没有设置阈值。</p> <p class="comment" v-if="thresholds.length == 0">暂时还没有设置阈值。</p>
<table class="ui table selectable" v-if="thresholds.length > 0"> <table class="ui table selectable celled" v-if="thresholds.length > 0">
<thead> <thead>
<tr> <tr>
<th>监控项</th> <th>监控项</th>
@@ -20,10 +20,14 @@
</tr> </tr>
</thead> </thead>
<tr v-for="threshold in thresholds"> <tr v-for="threshold in thresholds">
<td>{{threshold.itemName}}</td> <td>{{threshold.itemName}}
<div v-if="threshold.node != null" style="margin-top: 0.3em">
<a :href="'/clusters/cluster/node/thresholds?clusterId=' + clusterId + '&nodeId=' + threshold.node.id" class="ui label basic tiny" title="节点专属阈值设置"><span class="small">节点:{{threshold.node.name}}</span></a>
</div>
</td>
<td>{{threshold.paramName}}</td> <td>{{threshold.paramName}}</td>
<td>{{threshold.operatorName}}</td> <td>{{threshold.operatorName}}</td>
<td>{{threshold.itemName}}</td> <td>{{threshold.value}}</td>
<td>{{threshold.duration}}{{threshold.durationUnitName}}</td> <td>{{threshold.duration}}{{threshold.durationUnitName}}</td>
<td> <td>
<label-on :v-is-on="threshold.isOn"></label-on> <label-on :v-is-on="threshold.isOn"></label-on>

View File

@@ -55,18 +55,37 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>消息</td> <td colspan="2"><more-options-indicator></more-options-indicator></td>
<td>
<textarea rows="2" maxlength="100" name="message" v-model="threshold.message"></textarea>
<p class="comment">触发阈值时的消息提示。</p>
</td>
</tr>
<tr>
<td>是否启用</td>
<td>
<checkbox name="isOn" value="1" v-model="threshold.isOn"></checkbox>
</td>
</tr> </tr>
<tbody v-show="moreOptionsVisible">
<tr>
<td>消息</td>
<td>
<textarea rows="2" maxlength="100" name="message" v-model="threshold.message"></textarea>
<p class="comment">触发阈值时的消息提示。</p>
</td>
</tr>
<tr>
<td>消息通知间隔</td>
<td>
<div class="ui fields inline">
<div class="ui field">
<input type="text" name="notifyDuration" v-model="threshold.notifyDuration" value="10" style="width: 5em"/>
</div>
<div class="ui field">
分钟
</div>
</div>
<p class="comment">在此间隔内将不会重复发送跟此阈值相关的消息。</p>
</td>
</tr>
<tr>
<td>是否启用</td>
<td>
<checkbox name="isOn" value="1" v-model="threshold.isOn"></checkbox>
</td>
</tr>
</tbody>
</table> </table>
<submit-btn></submit-btn> <submit-btn></submit-btn>