parent
c422565cfe
commit
81b6fa6760
14 changed files with 915 additions and 3 deletions
@ -0,0 +1,62 @@ |
||||
|
||||
package org.springblade.common.constant; |
||||
|
||||
/** |
||||
* 通用常量 |
||||
* |
||||
* @author Chill |
||||
*/ |
||||
public interface MonitorConstant { |
||||
|
||||
String EQUIP = "equip"; |
||||
|
||||
/** |
||||
* 监控类型-服务 |
||||
*/ |
||||
String SERVICE = "service"; |
||||
|
||||
String RESULT = "result"; |
||||
|
||||
/** |
||||
* 状态0:未运行 |
||||
*/ |
||||
Integer STATUS_0 = 0; |
||||
|
||||
/** |
||||
* 状态1:正常运行 |
||||
*/ |
||||
Integer STATUS_1 = 1; |
||||
|
||||
/** |
||||
* 状态2:状态异常 |
||||
*/ |
||||
Integer STATUS_2 = 2; |
||||
|
||||
/** |
||||
* 状态3:通信异常 |
||||
*/ |
||||
Integer STATUS_3 = 3; |
||||
|
||||
/** |
||||
* 状态4:状态静默 |
||||
*/ |
||||
Integer STATUS_4 = 4; |
||||
|
||||
/** |
||||
* 监控类型-中间件 |
||||
*/ |
||||
String MIDDLEWARE = "middleware"; |
||||
|
||||
/** |
||||
* 网关 |
||||
*/ |
||||
String GATEWAY = "gateway"; |
||||
|
||||
/** |
||||
* mqtt |
||||
*/ |
||||
String MQTT = "mqtt"; |
||||
|
||||
String WEB = "web"; |
||||
|
||||
} |
||||
@ -0,0 +1,84 @@ |
||||
package org.springblade.common.utils; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.google.common.base.Joiner; |
||||
import lombok.RequiredArgsConstructor; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.web.client.RestTemplate; |
||||
import org.springframework.web.util.UriComponentsBuilder; |
||||
|
||||
import java.net.URI; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* 天气相关接口 |
||||
* |
||||
* @Description |
||||
* @Author ytl |
||||
* @Date 2022/11/7 0007 12:03 |
||||
*/ |
||||
|
||||
@Component |
||||
@RequiredArgsConstructor |
||||
public class HttpUtil { |
||||
private final RestTemplate restTemplate; |
||||
|
||||
public String doGet(String url, JSONObject params) { |
||||
URI uri = getUriByUrl(url,params); |
||||
String responseEntity = restTemplate.getForEntity(uri, String.class).getBody(); |
||||
return responseEntity; |
||||
} |
||||
|
||||
/** |
||||
* 通过URL获取URI |
||||
* |
||||
* @param url url |
||||
* @param params 请求参数 |
||||
* @return {@code URI} |
||||
*/ |
||||
private URI getUriByUrl(String url, JSONObject params) { |
||||
String query = "query"; |
||||
if (!params.isEmpty()) { |
||||
// 针对未处理特殊字符参数进行转义处理
|
||||
if (params.containsKey(query)) { |
||||
String replaceQuery = params.getString(query) |
||||
.replace("=", "%3D").replace(" ", "%20") |
||||
.replace("{", "%7B").replace("}", "%7D") |
||||
.replace("\"", "%22").replace("/", "%2F") |
||||
.replace("|", "%7C").replace("+", "%2B") |
||||
.replace("[", "%5B").replace("]", "%5D") |
||||
.replace("<", "%3C").replace(">", "%3E") |
||||
.replace("\n", "%20"); |
||||
params.put(query, replaceQuery); |
||||
} |
||||
url = expandUrl(url, params); |
||||
} |
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url); |
||||
if (params.containsKey(query)) { |
||||
return builder.build(true).toUri(); |
||||
} else { |
||||
return builder.build().encode().toUri(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* URL拼接 |
||||
* |
||||
* @param url 请求URL |
||||
* @param jsonObject JSON对象 |
||||
* @return 拼接之后的URL |
||||
*/ |
||||
private String expandUrl(String url, JSONObject jsonObject) { |
||||
HashMap<String, Object> paramMap = new HashMap<>(16); |
||||
StringBuilder stringBuilder = new StringBuilder(url); |
||||
stringBuilder.append("?"); |
||||
|
||||
Set<String> keys = jsonObject.keySet(); |
||||
keys.forEach(key -> paramMap.put(key, jsonObject.getString(key))); |
||||
String joinStr = Joiner.on("&").withKeyValueSeparator("=").join(paramMap); |
||||
return stringBuilder.append(joinStr).toString(); |
||||
} |
||||
} |
||||
@ -0,0 +1,134 @@ |
||||
package org.springblade.common.utils; |
||||
|
||||
import javax.management.MBeanServer; |
||||
import javax.management.MalformedObjectNameException; |
||||
import javax.management.ObjectName; |
||||
import javax.management.Query; |
||||
import java.lang.management.ManagementFactory; |
||||
import java.net.*; |
||||
import java.util.Enumeration; |
||||
import java.util.Set; |
||||
|
||||
public class IpUtil { |
||||
|
||||
/** |
||||
* 获取本机IP地址 |
||||
* |
||||
* @return |
||||
* @throws SocketException |
||||
*/ |
||||
public static String getIpAddress() throws SocketException { |
||||
String ipString = null; |
||||
Inet4Address inet4Address = getInet4Address(); |
||||
if (inet4Address != null) { |
||||
ipString = inet4Address.getHostAddress(); |
||||
} |
||||
return ipString; |
||||
} |
||||
|
||||
/** |
||||
* 获取tomcat容器的http端口 |
||||
* |
||||
* @return |
||||
* @throws MalformedObjectNameException |
||||
*/ |
||||
public static String getTomcatHttpPort() throws MalformedObjectNameException { |
||||
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer(); |
||||
Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"), |
||||
Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"))); |
||||
String port = objectNames.iterator().next().getKeyProperty("port"); |
||||
return port; |
||||
} |
||||
|
||||
/** |
||||
* 获取网络前缀长度, |
||||
* 如果长度为8,则表示掩码是255.0.0.0, |
||||
* 如果长度为16,则表示掩码是255.255.0.0, |
||||
* 如果长度为24,则表示掩码是255.255.255.0, |
||||
* |
||||
* @return |
||||
* @throws UnknownHostException |
||||
* @throws SocketException |
||||
*/ |
||||
public static int getNetworkPrefixLength() throws UnknownHostException, SocketException { |
||||
|
||||
int networkPrefixLength = 0; |
||||
Inet4Address inet4Address = getInet4Address(); |
||||
if (inet4Address != null) { |
||||
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(inet4Address); |
||||
for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) { |
||||
if (address.getAddress() instanceof Inet4Address) { |
||||
networkPrefixLength = address.getNetworkPrefixLength(); |
||||
} |
||||
|
||||
} |
||||
} |
||||
return networkPrefixLength; |
||||
} |
||||
|
||||
/** |
||||
* 获取网络掩码255.0.0.0,255.0.0.0,255.0.0.0, |
||||
* |
||||
* @return |
||||
* @throws UnknownHostException |
||||
* @throws SocketException |
||||
*/ |
||||
public static String getSubnet() throws UnknownHostException, SocketException { |
||||
String subnet = null; |
||||
int prefix = getNetworkPrefixLength(); |
||||
if (prefix > 0) { |
||||
if (prefix == 8) { |
||||
subnet = "255.0.0.0"; |
||||
} else if (prefix == 16) { |
||||
subnet = "255.255.0.0"; |
||||
} else if (prefix == 24) { |
||||
subnet = "255.255.255.0"; |
||||
} else if (prefix == 32) { |
||||
subnet = "255.255.255.255"; |
||||
} |
||||
} |
||||
return subnet; |
||||
} |
||||
|
||||
private static Inet4Address getInet4Address() throws SocketException { |
||||
Inet4Address inet4Address = null; |
||||
Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces(); |
||||
InetAddress ip = null; |
||||
while (allNetInterfaces.hasMoreElements()) { |
||||
NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement(); |
||||
// 用于排除回送接口,非虚拟网卡,未在使用中的网络接口.
|
||||
if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) { |
||||
continue; |
||||
} else { |
||||
Enumeration<InetAddress> addresses = netInterface.getInetAddresses(); |
||||
while (addresses.hasMoreElements()) { |
||||
ip = addresses.nextElement(); |
||||
if (ip != null && ip instanceof Inet4Address) { |
||||
inet4Address = (Inet4Address) ip; |
||||
break; |
||||
} |
||||
} |
||||
if (inet4Address != null) { |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
return inet4Address; |
||||
} |
||||
|
||||
public static boolean isIPReachable(String ip) { |
||||
try { |
||||
return InetAddress.getByName(ip).isReachable(5000); // 超时时间为5秒
|
||||
} catch (Exception e) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public static void main(String[] args) throws SocketException, UnknownHostException { |
||||
System.out.println(getIpAddress()); |
||||
System.out.println(getNetworkPrefixLength()); |
||||
System.out.println(getSubnet()); |
||||
} |
||||
|
||||
|
||||
} |
||||
@ -0,0 +1,27 @@ |
||||
package org.springblade.common.utils; |
||||
|
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory; |
||||
import org.springframework.web.client.RestTemplate; |
||||
|
||||
/** |
||||
* spring restTemplate配置类 |
||||
* @Description |
||||
* @Author ytl |
||||
* @Date 2022/11/7 0007 12:18 |
||||
*/ |
||||
@Configuration |
||||
public class SpringRestTemplate { |
||||
@Bean |
||||
public static RestTemplate restTemplate() { |
||||
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); |
||||
requestFactory.setConnectTimeout(5000); |
||||
requestFactory.setReadTimeout(5000); |
||||
requestFactory.setOutputStreaming(false); |
||||
|
||||
RestTemplate restTemplate = new RestTemplate(); |
||||
restTemplate.setRequestFactory(requestFactory); |
||||
return restTemplate; |
||||
} |
||||
} |
||||
@ -0,0 +1,44 @@ |
||||
package org.springblade.modules.monitor.controller; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import org.springblade.core.tool.api.R; |
||||
import org.springblade.modules.monitor.service.IConfigMonitorService; |
||||
import org.springblade.modules.monitor.vo.ConfigMonitorVO; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import java.util.List; |
||||
|
||||
@RestController |
||||
@AllArgsConstructor |
||||
@RequestMapping("/monitor") |
||||
public class MonitorController { |
||||
private final IConfigMonitorService configMonitorService; |
||||
|
||||
/** |
||||
* 获取所有监控设备 |
||||
*/ |
||||
@GetMapping("/tree") |
||||
public R<List<ConfigMonitorVO>> tree(){ |
||||
List<ConfigMonitorVO> list = configMonitorService.tree(); |
||||
return R.data(list); |
||||
} |
||||
|
||||
/** |
||||
* 判断设备是否正常 |
||||
*/ |
||||
@GetMapping("/findList") |
||||
public void ifFestival(){ |
||||
configMonitorService.updateMonitorInfo(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 定时排查监控沈北状态 |
||||
*/ |
||||
@GetMapping("/monitoringEquip") |
||||
public void monitoringEquip(){ |
||||
configMonitorService.monitoringEquip(); |
||||
} |
||||
} |
||||
@ -0,0 +1,102 @@ |
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package org.springblade.modules.monitor.entity; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType; |
||||
import com.baomidou.mybatisplus.annotation.TableId; |
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; |
||||
import io.swagger.annotations.ApiModel; |
||||
import io.swagger.annotations.ApiModelProperty; |
||||
import lombok.Data; |
||||
import org.springblade.core.mp.base.BaseEntity; |
||||
|
||||
/** |
||||
* 服务器监控基础配置表 实体类 |
||||
* |
||||
* @author BladeX |
||||
* @since 2022-02-12 |
||||
*/ |
||||
@Data |
||||
@TableName("t_config_monitor") |
||||
@ApiModel(value = "ConfigMonitor对象", description = "服务器监控基础配置表 ") |
||||
public class ConfigMonitor extends BaseEntity { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 主键 |
||||
*/ |
||||
@ApiModelProperty(value = "主键") |
||||
@TableId(value = "id", type = IdType.AUTO) |
||||
private Long id; |
||||
|
||||
/** |
||||
* 父级id |
||||
*/ |
||||
@ApiModelProperty(value = "父级id") |
||||
private Long parentId; |
||||
|
||||
/** |
||||
* 类型 |
||||
*/ |
||||
@ApiModelProperty(value = "类型") |
||||
private String type; |
||||
/** |
||||
* ip |
||||
*/ |
||||
@ApiModelProperty(value = "ip") |
||||
private String ip; |
||||
|
||||
/** |
||||
* 监控类型 |
||||
*/ |
||||
@ApiModelProperty(value = "监控类型") |
||||
private String monitorType; |
||||
|
||||
/** |
||||
* 计算公式 |
||||
*/ |
||||
@ApiModelProperty(value = "计算公式") |
||||
private String formula; |
||||
|
||||
/** |
||||
* 计算结果 |
||||
*/ |
||||
@ApiModelProperty(value = "计算结果") |
||||
private String result; |
||||
|
||||
/** |
||||
* 设备编码 |
||||
*/ |
||||
@ApiModelProperty(value = "设备编码") |
||||
private String equipCode; |
||||
|
||||
|
||||
/** |
||||
* 设备类型 |
||||
*/ |
||||
@ApiModelProperty(value = "设备类型") |
||||
private String classCode; |
||||
|
||||
@JsonSerialize( |
||||
using = ToStringSerializer.class |
||||
) |
||||
@ApiModelProperty("创建部门") |
||||
private Long createDept; |
||||
} |
||||
@ -0,0 +1,42 @@ |
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package org.springblade.modules.monitor.mapper; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import org.springblade.modules.monitor.entity.ConfigMonitor; |
||||
import org.springblade.modules.monitor.vo.ConfigMonitorVO; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 服务器监控基础配置表 Mapper 接口 |
||||
* |
||||
* @author BladeX |
||||
* @since 2022-02-12 |
||||
*/ |
||||
public interface ConfigMonitorMapper extends BaseMapper<ConfigMonitor> { |
||||
|
||||
/** |
||||
* 获取树形节点 |
||||
* |
||||
* @return |
||||
*/ |
||||
List<ConfigMonitorVO> tree(); |
||||
|
||||
Integer findMqttEquipCount(String updateTime); |
||||
|
||||
} |
||||
@ -0,0 +1,65 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
<mapper namespace="org.springblade.modules.monitor.mapper.ConfigMonitorMapper"> |
||||
|
||||
<!-- 通用查询映射结果 --> |
||||
<resultMap id="commonResultMap" type="org.springblade.modules.monitor.entity.ConfigMonitor"> |
||||
<id column="id" property="id"/> |
||||
<result column="parent_id" property="parentId"/> |
||||
<result column="type" property="type"/> |
||||
<result column="ip" property="ip"/> |
||||
<result column="monitor_type" property="monitorType"/> |
||||
<result column="formula" property="formula"/> |
||||
<result column="result" property="result"/> |
||||
<result column="create_time" property="createTime"/> |
||||
<result column="create_user" property="createUser"/> |
||||
<result column="create_dept" property="createDept"/> |
||||
<result column="update_time" property="updateTime"/> |
||||
<result column="update_user" property="updateUser"/> |
||||
<result column="status" property="status"/> |
||||
<result column="is_deleted" property="isDeleted"/> |
||||
</resultMap> |
||||
|
||||
<resultMap id="treeNodeResultMap" type="org.springblade.core.tool.node.TreeNode"> |
||||
<id column="id" property="id"/> |
||||
<result column="parent_id" property="parentId"/> |
||||
<result column="title" property="title"/> |
||||
<result column="value" property="value"/> |
||||
<result column="key" property="key"/> |
||||
<result column="has_children" property="hasChildren"/> |
||||
</resultMap> |
||||
|
||||
<select id="tree" resultMap="treeNodeResultMap" > |
||||
SELECT |
||||
a.id, |
||||
a.parent_id, |
||||
a.type AS title, |
||||
a.status AS "value", |
||||
a.id AS "key", |
||||
( |
||||
SELECT |
||||
CASE WHEN count(1) > 0 THEN 1 ELSE 0 END |
||||
FROM |
||||
t_config_monitor |
||||
WHERE |
||||
parent_id = a.id and is_deleted = 0 |
||||
) AS "has_children" |
||||
FROM |
||||
t_config_monitor a |
||||
WHERE |
||||
a.is_deleted = 0 |
||||
order by a.status |
||||
</select> |
||||
|
||||
<select id="findMqttEquipCount" resultType="java.lang.Integer" > |
||||
SELECT |
||||
count( 1 ) |
||||
FROM |
||||
`t_config_monitor` |
||||
WHERE |
||||
class_code IN ( '0200', '0300', '0600', '0700', '0701', '0702' ) |
||||
AND update_time > #{updateTime} |
||||
</select> |
||||
|
||||
|
||||
</mapper> |
||||
@ -0,0 +1,43 @@ |
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package org.springblade.modules.monitor.service; |
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService; |
||||
import org.springblade.modules.monitor.entity.ConfigMonitor; |
||||
import org.springblade.modules.monitor.vo.ConfigMonitorVO; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 服务器监控基础配置表 服务类 |
||||
* |
||||
* @author BladeX |
||||
* @since 2022-02-12 |
||||
*/ |
||||
public interface IConfigMonitorService extends IService<ConfigMonitor> { |
||||
|
||||
public void updateMonitorInfo(); |
||||
|
||||
void monitoringEquip(); |
||||
|
||||
/** |
||||
* 树形结构 |
||||
* |
||||
* @return |
||||
*/ |
||||
List<ConfigMonitorVO> tree(); |
||||
} |
||||
@ -0,0 +1,217 @@ |
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package org.springblade.modules.monitor.service.impl; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.apache.commons.lang.StringUtils; |
||||
import org.apache.commons.lang.time.DateFormatUtils; |
||||
import org.apache.commons.lang.time.DateUtils; |
||||
import org.springblade.common.constant.MonitorConstant; |
||||
import org.springblade.common.utils.HttpUtil; |
||||
import org.springblade.common.utils.IpUtil; |
||||
import org.springblade.core.mp.base.BaseEntity; |
||||
import org.springblade.core.tool.node.ForestNodeMerger; |
||||
import org.springblade.core.tool.utils.StringUtil; |
||||
import org.springblade.modules.monitor.entity.ConfigMonitor; |
||||
import org.springblade.modules.monitor.mapper.ConfigMonitorMapper; |
||||
import org.springblade.modules.monitor.service.IConfigMonitorService; |
||||
import org.springblade.modules.monitor.vo.ConfigMonitorVO; |
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 服务器监控基础配置表 服务实现类 |
||||
* |
||||
* @author BladeX |
||||
* @since 2022-02-12 |
||||
*/ |
||||
@Service |
||||
@Slf4j |
||||
@RequiredArgsConstructor |
||||
public class ConfigMonitorServiceImpl extends ServiceImpl<ConfigMonitorMapper, ConfigMonitor> implements IConfigMonitorService { |
||||
|
||||
|
||||
@Value("${monitor.url}") |
||||
private String monitorUrl; |
||||
|
||||
private final HttpUtil httpUtil; |
||||
|
||||
@Override |
||||
public void updateMonitorInfo() { |
||||
try { |
||||
LambdaQueryWrapper<ConfigMonitor> queryWrapper = null; |
||||
queryWrapper = new LambdaQueryWrapper<>(); |
||||
queryWrapper.eq(BaseEntity::getIsDeleted,"0"); |
||||
List<ConfigMonitor> list = baseMapper.selectList(queryWrapper); |
||||
if(CollectionUtils.isNotEmpty(list)){ |
||||
for(ConfigMonitor monitor : list){ |
||||
if(StringUtil.isNotBlank(monitor.getIp())&&StringUtil.isNotBlank(monitor.getFormula())){ |
||||
JSONObject params = new JSONObject(); |
||||
params.put("query",monitor.getFormula()); |
||||
String s = httpUtil.doGet(monitorUrl, params); |
||||
String[] strs = s.split("\""); |
||||
String result = strs[strs.length-2]; |
||||
monitor.setResult(result); |
||||
baseMapper.updateById(monitor); |
||||
log.info("调用api结果:"+s); |
||||
log.info("最后获取结果:"+result); |
||||
} |
||||
} |
||||
} |
||||
} catch (Exception e) { |
||||
log.error("获取服务器监控信息报错:" + e.getMessage()); |
||||
throw new RuntimeException(e); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void monitoringEquip() { |
||||
//查询所有设备
|
||||
Date nowDate = new Date(); |
||||
Date time = DateUtils.addMinutes(nowDate,-30); |
||||
LambdaQueryWrapper<ConfigMonitor> queryWrapper = new LambdaQueryWrapper<>(); |
||||
queryWrapper.eq(ConfigMonitor::getType, MonitorConstant.EQUIP); |
||||
queryWrapper.eq(BaseEntity::getIsDeleted,0); |
||||
List<ConfigMonitor> list = baseMapper.selectList(queryWrapper); |
||||
//按照父级id分组
|
||||
Map<Long,List<ConfigMonitor>> map = list.stream().collect(Collectors.groupingBy(ConfigMonitor::getParentId)); |
||||
for(Map.Entry<Long,List<ConfigMonitor>> entry : map.entrySet()){ |
||||
Long parentId = entry.getKey(); |
||||
List<ConfigMonitor> monitorList = entry.getValue(); |
||||
//获取更新时间间隔大于30分钟的数据
|
||||
List<ConfigMonitor> breakList = monitorList.stream().filter(item->{ |
||||
return item.getUpdateTime().compareTo(time) < 0; |
||||
}).collect(Collectors.toList()); |
||||
//如果所有设备都坏了,直接排查父级问题;否则修改设备状态为异常
|
||||
//modbus设备排查服务、网关;mqtt设备排查服务、mqtt服务、dtu;bacnet设备是通过广播直连,如果全部设备都有问题,直接排查网络问题;
|
||||
if(breakList.size() == monitorList.size()){ |
||||
List<Long> parentIdList = new ArrayList<>(); |
||||
parentIdList = getParentIdList(parentIdList,parentId); |
||||
Collections.reverse(parentIdList); |
||||
boolean flag = true; |
||||
for(Long id : parentIdList){ |
||||
//通过标识位来判断当前是否应该静默
|
||||
if(flag){ |
||||
LambdaQueryWrapper<ConfigMonitor> wrapper = new LambdaQueryWrapper<>(); |
||||
wrapper.eq(ConfigMonitor::getId,id); |
||||
wrapper.eq(BaseEntity::getIsDeleted,0); |
||||
ConfigMonitor configMonitor = baseMapper.selectOne(wrapper); |
||||
//服务排查
|
||||
if(configMonitor.getType().equals(MonitorConstant.SERVICE) && configMonitor.getResult().equals(MonitorConstant.RESULT)){ |
||||
flag = false; |
||||
configMonitor.setStatus(MonitorConstant.STATUS_2); |
||||
configMonitor.setUpdateTime(nowDate); |
||||
baseMapper.updateById(configMonitor); |
||||
parentId = id; |
||||
continue; |
||||
} |
||||
//mqtt服务排查
|
||||
if(configMonitor.getType().equals(MonitorConstant.MIDDLEWARE) && configMonitor.getMonitorType().equals(MonitorConstant.MQTT)){ |
||||
//通过查询所有mqtt相关设备来判断mqtt服务是否正常
|
||||
int count = baseMapper.findMqttEquipCount(DateFormatUtils.format(time,"yyyy-MM-dd HH:mm:ss")); |
||||
//如果count=0说明所有mqtt相关设备都没取到数,可证明mqtt出现问题
|
||||
if(count == 0){ |
||||
flag = false; |
||||
parentId = id; |
||||
configMonitor.setStatus(MonitorConstant.STATUS_2); |
||||
configMonitor.setUpdateTime(nowDate); |
||||
baseMapper.updateById(configMonitor); |
||||
continue; |
||||
} |
||||
} |
||||
//网关排查 --适用于modbus 空调面板 lora网关;mqtt dtu;http 空开照明 通讯模块;
|
||||
if(configMonitor.getType().equals(MonitorConstant.MIDDLEWARE) && configMonitor.getMonitorType().equals(MonitorConstant.GATEWAY) && StringUtils.isNotEmpty(configMonitor.getIp())){ |
||||
//ping网关ip,如果能ping通,则证明是网关本身有问题,如果ping不通,说明通信有问题
|
||||
boolean isNormal = IpUtil.isIPReachable(configMonitor.getIp()); |
||||
if(isNormal){ |
||||
configMonitor.setStatus(MonitorConstant.STATUS_2); |
||||
}else{ |
||||
configMonitor.setStatus(MonitorConstant.STATUS_3); |
||||
} |
||||
configMonitor.setUpdateTime(nowDate); |
||||
baseMapper.updateById(configMonitor); |
||||
} |
||||
}else{ |
||||
//如果是静默,根据parentId将所有子节点状态改为静默
|
||||
LambdaUpdateWrapper<ConfigMonitor> updateWrapper = new LambdaUpdateWrapper<>(); |
||||
updateWrapper.eq(ConfigMonitor::getParentId,parentId); |
||||
ConfigMonitor configMonitor = new ConfigMonitor(); |
||||
configMonitor.setStatus(MonitorConstant.STATUS_4); |
||||
configMonitor.setUpdateTime(nowDate); |
||||
baseMapper.update(configMonitor,updateWrapper); |
||||
parentId = id; |
||||
} |
||||
} |
||||
//将所有设备状态改为静默
|
||||
breakList.forEach(item ->{ |
||||
item.setStatus(MonitorConstant.STATUS_4); |
||||
item.setUpdateTime(nowDate); |
||||
baseMapper.updateById(item); |
||||
}); |
||||
}else{ |
||||
for(ConfigMonitor configMonitor : breakList){ |
||||
configMonitor.setStatus(MonitorConstant.STATUS_2); |
||||
baseMapper.updateById(configMonitor); |
||||
} |
||||
//将父级id设备状态更新为正常
|
||||
LambdaQueryWrapper<ConfigMonitor> wrapper = new LambdaQueryWrapper<>(); |
||||
wrapper.eq(ConfigMonitor::getId,parentId); |
||||
wrapper.eq(BaseEntity::getIsDeleted,0); |
||||
ConfigMonitor configMonitor = baseMapper.selectOne(wrapper); |
||||
configMonitor.setStatus(MonitorConstant.STATUS_1); |
||||
baseMapper.updateById(configMonitor); |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
@Override |
||||
public List<ConfigMonitorVO> tree() { |
||||
return ForestNodeMerger.merge(baseMapper.tree()); |
||||
} |
||||
|
||||
public List<Long> getParentIdList(List<Long> parentIdList,Long parentId){ |
||||
parentIdList.add(parentId); |
||||
if(parentId != 0){ |
||||
LambdaQueryWrapper<ConfigMonitor> queryWrapper = new LambdaQueryWrapper<>(); |
||||
queryWrapper.eq(ConfigMonitor::getId,parentId); |
||||
queryWrapper.eq(BaseEntity::getIsDeleted,0); |
||||
ConfigMonitor configMonitor = baseMapper.selectOne(queryWrapper); |
||||
parentId = configMonitor.getParentId(); |
||||
//服务器不需要排查,所以只需要到服务层面就可以
|
||||
if(configMonitor.getType().equals(MonitorConstant.SERVICE)){ |
||||
return parentIdList; |
||||
} |
||||
getParentIdList(parentIdList,parentId); |
||||
} |
||||
return parentIdList; |
||||
} |
||||
|
||||
|
||||
|
||||
} |
||||
@ -0,0 +1,25 @@ |
||||
package org.springblade.modules.monitor.task; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import org.springblade.modules.monitor.service.IConfigMonitorService; |
||||
import org.springframework.scheduling.annotation.Scheduled; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
@AllArgsConstructor |
||||
public class MonitorTaskJob { |
||||
private final IConfigMonitorService configMonitorService; |
||||
|
||||
@Scheduled(cron ="0 0 0 1/1 * ? ") |
||||
public void updateMonitorInfo(){ |
||||
configMonitorService.updateMonitorInfo(); |
||||
} |
||||
|
||||
|
||||
@Scheduled(cron ="0 0/5 * * * ? ") |
||||
public void monitoringEquip(){ |
||||
configMonitorService.monitoringEquip(); |
||||
} |
||||
|
||||
|
||||
} |
||||
@ -0,0 +1,64 @@ |
||||
|
||||
package org.springblade.modules.monitor.vo; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude; |
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; |
||||
import io.swagger.annotations.ApiModel; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import org.springblade.core.tool.node.INode; |
||||
import org.springblade.modules.monitor.entity.ConfigMonitor; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 视图实体类 |
||||
* |
||||
* @author Chill |
||||
*/ |
||||
@Data |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@ApiModel(value = "ConfigMonitorVO对象", description = "ConfigMonitorVO对象") |
||||
public class ConfigMonitorVO extends ConfigMonitor implements INode<ConfigMonitorVO> { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 主键ID |
||||
*/ |
||||
@JsonSerialize(using = ToStringSerializer.class) |
||||
private Long id; |
||||
|
||||
/** |
||||
* 父节点ID |
||||
*/ |
||||
@JsonSerialize(using = ToStringSerializer.class) |
||||
private Long parentId; |
||||
|
||||
/** |
||||
* 子孙节点 |
||||
*/ |
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY) |
||||
private List<ConfigMonitorVO> children; |
||||
|
||||
/** |
||||
* 是否有子孙节点 |
||||
*/ |
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY) |
||||
private Boolean hasChildren; |
||||
|
||||
@Override |
||||
public List<ConfigMonitorVO> getChildren() { |
||||
if (this.children == null) { |
||||
this.children = new ArrayList<>(); |
||||
} |
||||
return this.children; |
||||
} |
||||
|
||||
/** |
||||
* 上级机构 |
||||
*/ |
||||
private String parentName; |
||||
|
||||
} |
||||
Loading…
Reference in new issue