监控报警通知改为联系人

This commit is contained in:
bwcx_jzy 2019-08-11 15:34:11 +08:00
parent 59ec277566
commit 4173afb687
7 changed files with 146 additions and 168 deletions

View File

@ -11,6 +11,7 @@
5. 新增在线修改配置并可及时重启
6. 新增WebSSH 管理功能
7. 【Server】用户新增邮箱和钉钉群webhook 属性
8. 【Server】监控报警通知改为联系人
### 解决BUG、优化功能

View File

@ -1,7 +1,6 @@
package cn.keepbx.jpom.controller.monitor;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Entity;
@ -13,14 +12,13 @@ import cn.keepbx.jpom.common.BaseServerController;
import cn.keepbx.jpom.common.interceptor.UrlPermission;
import cn.keepbx.jpom.model.BaseEnum;
import cn.keepbx.jpom.model.Role;
import cn.keepbx.jpom.model.data.MailAccountModel;
import cn.keepbx.jpom.model.data.MonitorModel;
import cn.keepbx.jpom.model.data.NodeModel;
import cn.keepbx.jpom.model.data.UserModel;
import cn.keepbx.jpom.model.log.UserOperateLogV1;
import cn.keepbx.jpom.service.dblog.DbMonitorNotifyLogService;
import cn.keepbx.jpom.service.monitor.MonitorMailConfigService;
import cn.keepbx.jpom.service.monitor.MonitorService;
import cn.keepbx.jpom.service.user.UserService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.MediaType;
@ -33,7 +31,6 @@ import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* 监控列表
@ -49,10 +46,10 @@ public class MonitorListController extends BaseServerController {
private MonitorService monitorService;
@Resource
private MonitorMailConfigService monitorMailConfigService;
private DbMonitorNotifyLogService dbMonitorNotifyLogService;
@Resource
private DbMonitorNotifyLogService dbMonitorNotifyLogService;
private UserService userService;
/**
* 展示监控页面
@ -75,11 +72,21 @@ public class MonitorListController extends BaseServerController {
//监控周期
JSONArray cycleArray = BaseEnum.toJSONArray(MonitorModel.Cycle.class);
setAttribute("cycleArray", cycleArray);
//通知方式
JSONArray notifyTypeArray = BaseEnum.toJSONArray(MonitorModel.NotifyType.class);
setAttribute("notifyTypeArray", notifyTypeArray);
List<NodeModel> nodeModels = nodeService.listAndProject();
setAttribute("nodeModels", nodeModels);
//
List<UserModel> list = userService.list(false);
JSONArray jsonArray = new JSONArray();
list.forEach(userModel -> {
JSONObject jsonObject = new JSONObject();
jsonObject.put("title", userModel.getName());
jsonObject.put("value", userModel.getId());
if (StrUtil.isEmpty(userModel.getEmail()) && StrUtil.isEmpty(userModel.getDingDing())) {
jsonObject.put("disabled", true);
}
jsonArray.add(jsonObject);
});
setAttribute("userLists", jsonArray);
return "monitor/edit";
}
@ -109,51 +116,6 @@ public class MonitorListController extends BaseServerController {
return JsonMessage.getString(200, "删除成功");
}
private String checkNotifyData(String notify, List<MonitorModel.Notify> notifies) {
JSONArray notifyArray = JSONArray.parseArray(notify);
if (notify == null || notifyArray.isEmpty()) {
return JsonMessage.getString(400, "请至少选择一种通知方式");
}
for (int i = 0; i < notifyArray.size(); i++) {
JSONObject jsonObject = notifyArray.getJSONObject(i);
int style = jsonObject.getIntValue("style");
MonitorModel.NotifyType notifyType = BaseEnum.getEnum(MonitorModel.NotifyType.class, style);
Objects.requireNonNull(notifyType);
//
String value = jsonObject.getString("value");
if (StrUtil.isBlank(value)) {
return JsonMessage.getString(405, "请填写通知信息");
}
switch (notifyType) {
case mail:
// 检查配置
MailAccountModel config = monitorMailConfigService.getConfig();
if (config == null) {
return JsonMessage.getString(400, "还没有配置邮箱信息,请选配置邮箱信息");
}
//
String[] emails = StrUtil.split(value, StrUtil.COMMA);
if (emails == null || emails.length <= 0) {
return JsonMessage.getString(400, "请输入邮箱");
}
for (String email : emails) {
if (!Validator.isEmail(email)) {
return JsonMessage.getString(400, "请输入正确的邮箱:" + email);
}
}
break;
case dingding:
if (!Validator.isUrl(value)) {
return JsonMessage.getString(400, "钉钉通知地址不正确");
}
break;
default:
break;
}
notifies.add(new MonitorModel.Notify(style, value));
}
return null;
}
/**
* 增加或修改监控
@ -163,14 +125,15 @@ public class MonitorListController extends BaseServerController {
@UrlPermission(value = Role.ServerManager, optType = UserOperateLogV1.OptType.EditMonitor)
public String updateMonitor(String id,
@ValidatorConfig(@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "监控名称不能为空")) String name,
String notify) {
String notifyUser) {
int cycle = getParameterInt("cycle", MonitorModel.Cycle.five.getCode());
String status = getParameter("status");
String autoRestart = getParameter("autoRestart");
List<MonitorModel.Notify> notifies = new ArrayList<>();
String error = checkNotifyData(notify, notifies);
if (error != null) {
return error;
JSONArray jsonArray = JSONArray.parseArray(notifyUser);
List<String> notifyUsers = jsonArray.toJavaList(String.class);
if (notifyUsers == null || notifyUsers.isEmpty()) {
return JsonMessage.getString(405, "请选择报警联系人");
}
String projects = getParameter("projects");
JSONArray projectsArray = JSONArray.parseArray(projects);
@ -192,7 +155,7 @@ public class MonitorListController extends BaseServerController {
monitorModel.setCycle(cycle);
monitorModel.setProjects(nodeProjects);
monitorModel.setStatus(start);
monitorModel.setNotify(notifies);
monitorModel.setNotifyUser(notifyUsers);
monitorModel.setName(name);
if (StrUtil.isEmpty(id)) {

View File

@ -18,13 +18,9 @@ public class MonitorModel extends BaseModel {
*/
private List<NodeProject> projects;
/**
* 通知方式
* [{
* style: 通知方式
* value电话或邮箱等
* }]
* 报警联系人
*/
private List<Notify> notify;
private List<String> notifyUser;
/**
* 异常后是否自动重启
*/
@ -66,14 +62,15 @@ public class MonitorModel extends BaseModel {
this.projects = projects;
}
public List<Notify> getNotify() {
return notify;
public List<String> getNotifyUser() {
return notifyUser;
}
public void setNotify(List<Notify> notify) {
this.notify = notify;
public void setNotifyUser(List<String> notifyUser) {
this.notifyUser = notifyUser;
}
public boolean isAutoRestart() {
return autoRestart;
}
@ -148,24 +145,6 @@ public class MonitorModel extends BaseModel {
}
}
/**
* 前端使用
*
* @param style 样式
* @return
*/
public String getNotifyTypeValue(int style) {
List<Notify> notify = getNotify();
if (notify == null) {
return null;
}
for (Notify notify1 : notify) {
if (notify1.getStyle() == style) {
return notify1.getValue();
}
}
return null;
}
public boolean checkNodeProject(String nodeId, String projectId) {
List<NodeProject> projects = getProjects();
@ -226,8 +205,8 @@ public class MonitorModel extends BaseModel {
public Notify() {
}
public Notify(int style, String value) {
this.style = style;
public Notify(NotifyType style, String value) {
this.style = style.getCode();
this.value = value;
}

View File

@ -94,6 +94,16 @@ public class UserService extends BaseOperService<UserModel> {
*/
@Override
public List<UserModel> list() {
return list(true);
}
/**
* 是否返回系统管理员信息
*
* @param system 系统管理员
* @return list
*/
public List<UserModel> list(boolean system) {
JSONObject jsonObject = getJSONObject(ServerConfigBean.USER);
if (jsonObject == null) {
return null;
@ -104,7 +114,7 @@ public class UserService extends BaseOperService<UserModel> {
JSONObject value = (JSONObject) entry.getValue();
UserModel userModel = value.toJavaObject(UserModel.class);
// 不显示系统管理员信息
if (userModel.isSystemUser()) {
if (system && userModel.isSystemUser()) {
continue;
}
userModel.setPassword(null);

View File

@ -20,10 +20,12 @@ import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -40,6 +42,30 @@ public class SshHandler extends BaseHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
SshModel sshItem = (SshModel) session.getAttributes().get("sshItem");
Map<String, String[]> parameterMap = (Map<String, String[]>) session.getAttributes().get("parameterMap");
String[] tails = parameterMap.get("tail");
//
String tail = null;
if (tails != null && tails.length > 0 && !StrUtil.isEmptyOrUndefined(tails[0])) {
tail = tails[0];
List<String> fileDirs = sshItem.getFileDirs();
if (fileDirs == null) {
sendBinary(session, "没有配置路径");
return;
}
File file = FileUtil.file(tail);
boolean find = false;
for (String fileDir : fileDirs) {
if (FileUtil.isSub(FileUtil.file(fileDir), file)) {
find = true;
break;
}
}
if (!find) {
sendBinary(session, "非法路径");
return;
}
}
Session openSession = JschUtil.openSession(sshItem.getHost(), sshItem.getPort(), sshItem.getUser(), sshItem.getPassword());
Channel channel = JschUtil.createChannel(openSession, ChannelType.SHELL);
InputStream inputStream = channel.getInputStream();
@ -56,13 +82,10 @@ public class SshHandler extends BaseHandler {
HANDLER_ITEM_CONCURRENT_HASH_MAP.put(session.getId(), handlerItem);
//
Thread.sleep(1000);
Map<String, String[]> parameterMap = (Map<String, String[]>) session.getAttributes().get("parameterMap");
String[] tails = parameterMap.get("tail");
if (tails == null || tails.length <= 0 || StrUtil.isEmptyOrUndefined(tails[0])) {
if (tail == null) {
this.call(session, StrUtil.CR);
} else {
// 查看文件
String tail = tails[0];
tail = FileUtil.normalize(tail);
this.call(session, StrUtil.format("tail -f {}", tail));
this.call(session, StrUtil.CR);

View File

@ -19,10 +19,12 @@ import cn.keepbx.jpom.common.forward.NodeForward;
import cn.keepbx.jpom.common.forward.NodeUrl;
import cn.keepbx.jpom.model.data.MonitorModel;
import cn.keepbx.jpom.model.data.NodeModel;
import cn.keepbx.jpom.model.data.UserModel;
import cn.keepbx.jpom.model.log.MonitorNotifyLog;
import cn.keepbx.jpom.service.dblog.DbMonitorNotifyLogService;
import cn.keepbx.jpom.service.monitor.MonitorService;
import cn.keepbx.jpom.service.node.NodeService;
import cn.keepbx.jpom.service.user.UserService;
import cn.keepbx.util.CronUtils;
import com.alibaba.fastjson.JSONObject;
@ -90,8 +92,8 @@ public class Monitor implements Task {
return;
}
//
List<MonitorModel.Notify> notifies = monitorModel.getNotify();
if (notifies == null || notifies.isEmpty()) {
List<String> notifyUser = monitorModel.getNotifyUser();
if (notifyUser == null || notifyUser.isEmpty()) {
return;
}
this.checkNode(monitorModel);
@ -183,7 +185,7 @@ public class Monitor implements Task {
monitorNotifyLog.setProjectId(id);
monitorNotifyLog.setMonitorId(monitorModel.getId());
//
List<MonitorModel.Notify> notify = monitorModel.getNotify();
List<String> notify = monitorModel.getNotifyUser();
this.notifyMsg(notify, monitorNotifyLog);
});
}
@ -214,20 +216,51 @@ public class Monitor implements Task {
return entity1.isStatus();
}
private void notifyMsg(final List<MonitorModel.Notify> notify, final MonitorNotifyLog monitorNotifyLog) {
private void notifyMsg(final List<String> notify, final MonitorNotifyLog monitorNotifyLog) {
// 报警状态
MonitorService monitorService = SpringUtil.getBean(MonitorService.class);
monitorService.setAlarm(monitorNotifyLog.getMonitorId(), !monitorNotifyLog.isStatus());
UserService userService = SpringUtil.getBean(UserService.class);
// 发送通知
if (monitorNotifyLog.getTitle() != null) {
notify.forEach(notify1 -> {
notify.forEach(notifyUser -> {
UserModel item = userService.getItem(notifyUser);
boolean success = false;
if (item != null) {
// 邮箱
String email = item.getEmail();
if (StrUtil.isNotEmpty(email)) {
monitorNotifyLog.setLogId(IdUtil.fastSimpleUUID());
MonitorModel.Notify notify1 = new MonitorModel.Notify(MonitorModel.NotifyType.mail, email);
monitorNotifyLog.setNotifyStyle(notify1.getStyle());
monitorNotifyLog.setNotifyObject(notify1.getValue());
//
dbMonitorNotifyLogService.insert(monitorNotifyLog);
send(notify1, monitorNotifyLog.getLogId(), monitorNotifyLog.getTitle(), monitorNotifyLog.getContent());
success = true;
}
// dingding
String dingDing = item.getDingDing();
if (StrUtil.isNotEmpty(dingDing)) {
monitorNotifyLog.setLogId(IdUtil.fastSimpleUUID());
MonitorModel.Notify notify1 = new MonitorModel.Notify(MonitorModel.NotifyType.dingding, email);
monitorNotifyLog.setNotifyStyle(notify1.getStyle());
monitorNotifyLog.setNotifyObject(notify1.getValue());
//
dbMonitorNotifyLogService.insert(monitorNotifyLog);
send(notify1, monitorNotifyLog.getLogId(), monitorNotifyLog.getTitle(), monitorNotifyLog.getContent());
success = true;
}
}
if (success) {
return;
}
monitorNotifyLog.setLogId(IdUtil.fastSimpleUUID());
monitorNotifyLog.setNotifyStyle(notify1.getStyle());
monitorNotifyLog.setNotifyObject(notify1.getValue());
//
monitorNotifyLog.setNotifyObject("报警联系人异常");
monitorNotifyLog.setNotifyStyle(MonitorModel.NotifyType.mail.getCode());
monitorNotifyLog.setNotifyStatus(false);
monitorNotifyLog.setNotifyError("报警联系人异常:" + (item == null ? "联系人不存在" : ""));
dbMonitorNotifyLogService.insert(monitorNotifyLog);
send(notify1, monitorNotifyLog.getLogId(), monitorNotifyLog.getTitle(), monitorNotifyLog.getContent());
});
}
}
@ -244,6 +277,4 @@ public class Monitor implements Task {
}
});
}
}

View File

@ -23,8 +23,8 @@
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">异常后自动重启</label>
<div class="layui-input-block">
<label class="layui-form-label">自动重启</label>
<div class="layui-input-block" title="尝试自动重启">
<input type="checkbox" name="autoRestart" lay-skin="switch" lay-text="是|否"
th:checked="${model?.autoRestart}">
</div>
@ -38,27 +38,7 @@
th:checked="${model?.cycle==item.code}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">通知方式</label>
<div class="layui-input-block">
<div style="display: flex;margin: 5px" th:each="item : ${notifyTypeArray}"
th:with="nowData=${model?.getNotifyTypeValue(item.code)}">
<input type="checkbox" th:name="'notify_'+${item.code}" th:value="${item.code}"
th:title="${item.desc}"
th:checked="${nowData}"
lay-filter="monitorNotify">
<th:blck th:switch="${item.code}">
<input th:case="0" type="text" required th:id="'notifyValue_'+${item.code}" class="layui-input"
th:name="'value_'+${item.code}" th:style="${nowData}?'':'display: none'"
th:value="${nowData}" placeholder="请输入通知的webhook地址">
<input th:case="1" type="text" required th:id="'notifyValue_'+${item.code}" class="layui-input"
th:name="'value_'+${item.code}" th:style="${nowData}?'':'display: none'"
th:value="${nowData}" placeholder="请输入通知的邮箱">
</th:blck>
</div>
</div>
</div>
<div class=" layui-form-item">
<label class="layui-form-label">监控项目</label>
<div class="layui-input-block">
@ -84,7 +64,12 @@
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">报警联系人</label>
<div class="layui-input-block" id="notifyUser">
</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item" style="padding-left: 20%;margin-top: 20px;">
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="submitMonitor"
@ -96,16 +81,24 @@
</form>
</div>
</body>
<script type="text/javascript">
<script type="text/javascript" th:inline="javascript">
var userLists = [[${userLists}]];
var transfer;
var checkUser = [[${model?.notifyUser}]];
function loadSuccess() {
//通知方式的点击
form.on('checkbox(monitorNotify)', function (data) {
var id = "#notifyValue_" + data.value;
if (data.elem.checked) {
$(id).css("display", "block").attr('lay-verify', 'required');
} else {
$(id).css("display", "none").removeAttr('lay-verify');
}
layui.use('transfer', function () {
transfer = layui.transfer;
//渲染
transfer.render({
elem: '#notifyUser',
data: userLists,
value: checkUser,
title: ['待选择用户', '已选择用户'],
id: 'notifyUser'
});
});
// 提交信息
@ -120,12 +113,16 @@
layer.msg("请至少选择一个项目");
return false;
}
var notify = getNotifyType(sendData);
if (!notify || notify.length <= 0) {
layer.msg("请至少选择一个通知方式");
var notifyUser = transfer.getData('notifyUser');
if (!notifyUser || notifyUser.length <= 0) {
layer.msg("请至少选择一个通知");
return false;
}
sendData.notify = JSON.stringify(notify);
var notifyUsers = [];
for (var i = 0; i < notifyUser.length; i++) {
notifyUsers.push(notifyUser[i].value);
}
sendData.notifyUser = JSON.stringify(notifyUsers);
loadingAjax({
url: data.form.action,
data: sendData,
@ -177,32 +174,6 @@
data.projects = JSON.stringify(projects);
return projects;
}
function getNotifyType(data) {
var notify = [];
for (var key in data) {
if (startWith(key, "notify_")) {
var val = data[key];
var val_key = "value_" + val;
var value = data[val_key];
var item = {
style: val,
value: value
}
notify.push(item);
delete data[val_key];
delete data[key];
}
}
return notify;
}
}
function startWith(str, suffix) {
if (typeof str == 'string') {
return str.slice(0, suffix.length) == suffix;
}
return false;
}
</script>
</html>