Compare commits
24 Commits
feature#ke
...
bugfix#ora
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e6bf1618a | ||
|
|
4f13875e01 | ||
|
|
c79f66dd9f | ||
|
|
835df039e8 | ||
|
|
f23ea9ffd5 | ||
|
|
7994d7ef15 | ||
|
|
323e5f8981 | ||
|
|
e1916b937e | ||
|
|
2ecf40e873 | ||
|
|
63ea0a87f7 | ||
|
|
a3f4e42034 | ||
|
|
018db2a14f | ||
|
|
f238a1d4ea | ||
|
|
709d51d4d5 | ||
|
|
ce528808c7 | ||
|
|
51266aab87 | ||
|
|
e99dd2e870 | ||
|
|
95c36fd9a3 | ||
|
|
2553c6f61e | ||
|
|
cc92f82472 | ||
|
|
8dd2c1e47f | ||
|
|
6a9d65ba5d | ||
|
|
3c48b4c71f | ||
|
|
636303021f |
6
.gitignore
vendored
@@ -37,4 +37,10 @@ nbdist/
|
|||||||
### VS Code ###
|
### VS Code ###
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules
|
||||||
|
.docusaurus
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
# debug env
|
||||||
application-dev.yml
|
application-dev.yml
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
[](https://www.bilibili.com/video/BV1Vi4y1f7i8)
|
[](https://www.bilibili.com/video/BV1DY4y1i7ts)
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
|
|
||||||
##### 安装TDengine
|
##### 安装TDengine
|
||||||
1. docker安装TDengine
|
1. docker安装TDengine
|
||||||
`docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/tcp -p 6030-6049:6030-6049/udp --name tdengine tdengine/tdengine:2.4.0.12`
|
`docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp --name tdengine tdengine/tdengine:2.4.0.12`
|
||||||
2. 创建名称为hertzbeat的数据库
|
2. 创建名称为hertzbeat的数据库
|
||||||
|
|
||||||
详细步骤参考 [依赖服务TDengine安装初始化](https://hertzbeat.com/docs/start/tdengine-init)
|
详细步骤参考 [依赖服务TDengine安装初始化](https://hertzbeat.com/docs/start/tdengine-init)
|
||||||
@@ -93,6 +93,7 @@
|
|||||||
1. 下载您系统环境对应的安装包 [GITEE Release](https://gitee.com/dromara/hertzbeat/releases) [GITHUB Release](https://github.com/dromara/hertzbeat/releases)
|
1. 下载您系统环境对应的安装包 [GITEE Release](https://gitee.com/dromara/hertzbeat/releases) [GITHUB Release](https://github.com/dromara/hertzbeat/releases)
|
||||||
2. 配置HertzBeat的配置文件 hertzbeat/config/application.yml
|
2. 配置HertzBeat的配置文件 hertzbeat/config/application.yml
|
||||||
3. 部署启动 `$ ./startup.sh `
|
3. 部署启动 `$ ./startup.sh `
|
||||||
|
4. 浏览器访问 localhost:1157 即可开始,默认账号密码 admin/admin
|
||||||
|
|
||||||
详细步骤参考 [通过安装包安装HertzBeat](https://hertzbeat.com/docs/start/package-deploy)
|
详细步骤参考 [通过安装包安装HertzBeat](https://hertzbeat.com/docs/start/package-deploy)
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public class CalculateAlarm {
|
|||||||
} else {
|
} else {
|
||||||
// 其他异常
|
// 其他异常
|
||||||
alertBuilder.target(CommonConstants.AVAILABLE)
|
alertBuilder.target(CommonConstants.AVAILABLE)
|
||||||
.content("监控紧急可用性告警: " + metricsData.getCode().name());
|
.content("监控可用性告警: " + metricsData.getCode().name() + " : " + metricsData.getMsg());
|
||||||
triggeredMonitorStateAlertMap.put(monitorId, metricsData.getCode());
|
triggeredMonitorStateAlertMap.put(monitorId, metricsData.getCode());
|
||||||
dataQueue.addAlertData(alertBuilder.build());
|
dataQueue.addAlertData(alertBuilder.build());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,11 +30,12 @@ import java.util.List;
|
|||||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 告警管理API
|
* Alarm Management API 告警管理API
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2021/12/9 10:32
|
* @date 2021/12/9 10:32
|
||||||
*/
|
*/
|
||||||
@Api(tags = "告警批量管理API")
|
@Api(tags = "en: Alarm batch management API, zh:告警批量管理API")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(path = "/alerts", produces = {APPLICATION_JSON_VALUE})
|
@RequestMapping(path = "/alerts", produces = {APPLICATION_JSON_VALUE})
|
||||||
public class AlertsController {
|
public class AlertsController {
|
||||||
@@ -43,23 +44,23 @@ public class AlertsController {
|
|||||||
private AlertService alertService;
|
private AlertService alertService;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@ApiOperation(value = "查询告警列表", notes = "根据查询过滤项获取告警信息列表")
|
@ApiOperation(value = "Get a list of alarm information based on query filter items", notes = "根据查询过滤项获取告警信息列表")
|
||||||
public ResponseEntity<Message<Page<Alert>>> getAlerts(
|
public ResponseEntity<Message<Page<Alert>>> getAlerts(
|
||||||
@ApiParam(value = "告警ID", example = "6565466456") @RequestParam(required = false) List<Long> ids,
|
@ApiParam(value = "en: Alarm ID List,zh: 告警IDS", example = "6565466456") @RequestParam(required = false) List<Long> ids,
|
||||||
@ApiParam(value = "告警监控对象ID", example = "6565463543") @RequestParam(required = false) Long monitorId,
|
@ApiParam(value = "en: Alarm monitor object ID,zh: 告警监控对象ID", example = "6565463543") @RequestParam(required = false) Long monitorId,
|
||||||
@ApiParam(value = "告警级别", example = "6565463543") @RequestParam(required = false) Byte priority,
|
@ApiParam(value = "en: Alarm level,zh: 告警级别", example = "6565463543") @RequestParam(required = false) Byte priority,
|
||||||
@ApiParam(value = "告警状态", example = "6565463543") @RequestParam(required = false) Byte status,
|
@ApiParam(value = "en: Alarm Status,zh: 告警状态", example = "6565463543") @RequestParam(required = false) Byte status,
|
||||||
@ApiParam(value = "告警内容模糊查询", example = "linux") @RequestParam(required = false) String content,
|
@ApiParam(value = "en: Alarm content fuzzy query,zh:告警内容模糊查询", example = "linux") @RequestParam(required = false) String content,
|
||||||
@ApiParam(value = "排序字段,默认id", example = "name") @RequestParam(defaultValue = "id") String sort,
|
@ApiParam(value = "en: Sort field, default id,zh: 排序字段,默认id", example = "name") @RequestParam(defaultValue = "id") String sort,
|
||||||
@ApiParam(value = "排序方式,asc:升序,desc:降序", example = "desc") @RequestParam(defaultValue = "desc") String order,
|
@ApiParam(value = "en: Sort Type,zh: 排序方式,asc:升序,desc:降序", example = "desc") @RequestParam(defaultValue = "desc") String order,
|
||||||
@ApiParam(value = "列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
|
@ApiParam(value = "en: List current page,zh: 列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
|
||||||
@ApiParam(value = "列表分页数量", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
|
@ApiParam(value = "en: Number of list pagination,zh: 列表分页数量", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
|
||||||
|
|
||||||
Specification<Alert> specification = (root, query, criteriaBuilder) -> {
|
Specification<Alert> specification = (root, query, criteriaBuilder) -> {
|
||||||
List<Predicate> andList = new ArrayList<>();
|
List<Predicate> andList = new ArrayList<>();
|
||||||
|
|
||||||
if (ids != null && !ids.isEmpty()) {
|
if (ids != null && !ids.isEmpty()) {
|
||||||
CriteriaBuilder.In<Long> inPredicate= criteriaBuilder.in(root.get("id"));
|
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id"));
|
||||||
for (long id : ids) {
|
for (long id : ids) {
|
||||||
inPredicate.value(id);
|
inPredicate.value(id);
|
||||||
}
|
}
|
||||||
@@ -92,10 +93,9 @@ public class AlertsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
@ApiOperation(value = "批量删除告警", notes = "根据告警ID列表批量删除告警")
|
@ApiOperation(value = "Delete alarms in batches", notes = "根据告警ID列表批量删除告警")
|
||||||
public ResponseEntity<Message<Void>> deleteAlertDefines(
|
public ResponseEntity<Message<Void>> deleteAlertDefines(
|
||||||
@ApiParam(value = "告警IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
|
@ApiParam(value = "en:Alarm List ID,zh: 告警IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids) {
|
||||||
) {
|
|
||||||
if (ids != null && !ids.isEmpty()) {
|
if (ids != null && !ids.isEmpty()) {
|
||||||
alertService.deleteAlerts(new HashSet<>(ids));
|
alertService.deleteAlerts(new HashSet<>(ids));
|
||||||
}
|
}
|
||||||
@@ -104,10 +104,10 @@ public class AlertsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping(path = "/status/{status}")
|
@PutMapping(path = "/status/{status}")
|
||||||
@ApiOperation(value = "批量修改告警状态", notes = "批量修改告警状态,设置已读未读")
|
@ApiOperation(value = "Batch modify alarm status, set read and unread", notes = "批量修改告警状态,设置已读未读")
|
||||||
public ResponseEntity<Message<Void>> applyAlertDefinesStatus(
|
public ResponseEntity<Message<Void>> applyAlertDefinesStatus(
|
||||||
@ApiParam(value = "告警状态值", example = "0") @PathVariable Byte status,
|
@ApiParam(value = "en:Alarm status value,zh: 告警状态值", example = "0") @PathVariable Byte status,
|
||||||
@ApiParam(value = "告警IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids) {
|
@ApiParam(value = "en:Alarm List IDS,zh: 告警IDS", example = "6565463543") @RequestParam(required = false) List<Long> ids) {
|
||||||
if (ids != null && status != null && !ids.isEmpty()) {
|
if (ids != null && status != null && !ids.isEmpty()) {
|
||||||
alertService.editAlertStatus(status, ids);
|
alertService.editAlertStatus(status, ids);
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ public class AlertsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/summary")
|
@GetMapping(path = "/summary")
|
||||||
@ApiOperation(value = "获取告警统计信息", notes = "获取告警统计信息")
|
@ApiOperation(value = "Get alarm statistics", notes = "获取告警统计信息")
|
||||||
public ResponseEntity<Message<AlertSummary>> getAlertsSummary() {
|
public ResponseEntity<Message<AlertSummary>> getAlertsSummary() {
|
||||||
AlertSummary alertSummary = alertService.getAlertsSummary();
|
AlertSummary alertSummary = alertService.getAlertsSummary();
|
||||||
Message<AlertSummary> message = new Message<>(alertSummary);
|
Message<AlertSummary> message = new Message<>(alertSummary);
|
||||||
|
|||||||
@@ -12,20 +12,23 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alert 数据库操作
|
* Alert Database Operations Alert数据库表操作
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2021/12/9 10:03
|
* @date 2021/12/9 10:03
|
||||||
*/
|
*/
|
||||||
public interface AlertDao extends JpaRepository<Alert, Long>, JpaSpecificationExecutor<Alert> {
|
public interface AlertDao extends JpaRepository<Alert, Long>, JpaSpecificationExecutor<Alert> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据ID列表删除告警
|
* Delete alerts based on ID list 根据ID列表删除告警
|
||||||
* @param alertIds 告警ID列表
|
*
|
||||||
|
* @param alertIds Alert ID List 告警ID列表
|
||||||
*/
|
*/
|
||||||
void deleteAlertsByIdIn(Set<Long> alertIds);
|
void deleteAlertsByIdIn(Set<Long> alertIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据告警ID-状态值 更新告警状态
|
* 根据告警ID-状态值 更新告警状态
|
||||||
|
*
|
||||||
* @param status 状态值
|
* @param status 状态值
|
||||||
* @param ids 告警ID列表
|
* @param ids 告警ID列表
|
||||||
*/
|
*/
|
||||||
@@ -34,8 +37,10 @@ public interface AlertDao extends JpaRepository<Alert, Long>, JpaSpecificationEx
|
|||||||
void updateAlertsStatus(@Param(value = "status") Byte status, @Param(value = "ids") List<Long> ids);
|
void updateAlertsStatus(@Param(value = "status") Byte status, @Param(value = "ids") List<Long> ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Query the number of unhandled alarms of each alarm severity
|
||||||
* 查询各个告警级别的未处理告警数量
|
* 查询各个告警级别的未处理告警数量
|
||||||
* @return 告警数量
|
*
|
||||||
|
* @return Number of alerts 告警数量
|
||||||
*/
|
*/
|
||||||
@Query("select new com.usthe.alert.dto.AlertPriorityNum(mo.priority, count(mo.id)) from Alert mo where mo.status = 0 group by mo.priority")
|
@Query("select new com.usthe.alert.dto.AlertPriorityNum(mo.priority, count(mo.id)) from Alert mo where mo.status = 0 group by mo.priority")
|
||||||
List<AlertPriorityNum> findAlertPriorityNum();
|
List<AlertPriorityNum> findAlertPriorityNum();
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监控级别告警数量
|
* Number of monitoring level alarms 监控级别告警数量
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2022/3/6 19:52
|
* @date 2022/3/6 19:52
|
||||||
*/
|
*/
|
||||||
@@ -12,7 +13,13 @@ import lombok.Data;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class AlertPriorityNum {
|
public class AlertPriorityNum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alarm level 告警级别
|
||||||
|
*/
|
||||||
private byte priority;
|
private byte priority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* count 数量
|
||||||
|
*/
|
||||||
private long num;
|
private long num;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,31 +9,43 @@ import lombok.NoArgsConstructor;
|
|||||||
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
|
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 告警统计信息
|
* Alarm Statistics Information 告警统计信息
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2022/3/6 19:25
|
* @date 2022/3/6 19:25
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ApiModel(description = "告警统计信息")
|
@ApiModel(description = "en:Alarm Statistics Information,zh: 告警统计信息")
|
||||||
public class AlertSummary {
|
public class AlertSummary {
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警总数量(包括已处理未处理告警)", example = "134", accessMode = READ_ONLY, position = 0)
|
@ApiModelProperty(value = "Total number of alerts (including processed and unprocessed alerts)",
|
||||||
|
notes = "告警总数量(包括已处理未处理告警)",
|
||||||
|
example = "134", accessMode = READ_ONLY, position = 0)
|
||||||
private long total;
|
private long total;
|
||||||
|
|
||||||
@ApiModelProperty(value = "已处理告警数量", example = "34", accessMode = READ_ONLY, position = 1)
|
@ApiModelProperty(value = "Number of alerts handled",
|
||||||
|
notes = "已处理告警数量",
|
||||||
|
example = "34", accessMode = READ_ONLY, position = 1)
|
||||||
private long dealNum;
|
private long dealNum;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警处理率", example = "39.34", accessMode = READ_ONLY, position = 2)
|
@ApiModelProperty(value = "Alarm handling rate",
|
||||||
|
notes = "告警处理率",
|
||||||
|
example = "39.34", accessMode = READ_ONLY, position = 2)
|
||||||
private float rate;
|
private float rate;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警级别为警告告警的告警数量(指未处理告警)", example = "43", accessMode = READ_ONLY, position = 3)
|
@ApiModelProperty(value = "Number of alarms whose alarm severity is warning alarms (referring to unhandled alarms)",
|
||||||
|
notes = "告警级别为警告告警的告警数量(指未处理告警)",
|
||||||
|
example = "43", accessMode = READ_ONLY, position = 3)
|
||||||
private long priorityWarningNum;
|
private long priorityWarningNum;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警级别为严重告警的告警数量(指未处理告警)", example = "56", accessMode = READ_ONLY, position = 4)
|
@ApiModelProperty(value = "Number of alarms whose alarm severity is critical alarms (referring to unhandled alarms)",
|
||||||
|
notes = "告警级别为严重告警的告警数量(指未处理告警)",
|
||||||
|
example = "56", accessMode = READ_ONLY, position = 4)
|
||||||
private long priorityCriticalNum;
|
private long priorityCriticalNum;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警级别为紧急告警的告警数量(指未处理告警)", example = "23", accessMode = READ_ONLY, position = 5)
|
@ApiModelProperty(value = "Number of alarms whose alarm severity is urgent alarms (referring to unhandled alarms)",
|
||||||
|
notes = "告警级别为紧急告警的告警数量(指未处理告警)", example = "23", accessMode = READ_ONLY, position = 5)
|
||||||
private long priorityEmergencyNum;
|
private long priorityEmergencyNum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,43 +10,54 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Alarm information management interface
|
||||||
* 告警信息管理接口
|
* 告警信息管理接口
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2021/12/9 10:06
|
* @date 2021/12/9 10:06
|
||||||
*/
|
*/
|
||||||
public interface AlertService {
|
public interface AlertService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增告警
|
* Add alarm record
|
||||||
* @param alert 告警实体
|
* 新增告警记录
|
||||||
* @throws RuntimeException 新增过程异常抛出
|
*
|
||||||
|
* @param alert Alert entity 告警实体
|
||||||
|
* @throws RuntimeException Add process exception throw 新增过程异常抛出
|
||||||
*/
|
*/
|
||||||
void addAlert(Alert alert) throws RuntimeException;
|
void addAlert(Alert alert) throws RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Dynamic conditional query
|
||||||
* 动态条件查询
|
* 动态条件查询
|
||||||
* @param specification 查询条件
|
*
|
||||||
* @param pageRequest 分页参数
|
* @param specification Query conditions 查询条件
|
||||||
* @return 查询结果
|
* @param pageRequest pagination parameters 分页参数
|
||||||
|
* @return search result 查询结果
|
||||||
*/
|
*/
|
||||||
Page<Alert> getAlerts(Specification<Alert> specification, PageRequest pageRequest);
|
Page<Alert> getAlerts(Specification<Alert> specification, PageRequest pageRequest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Delete alarms in batches according to the alarm ID list
|
||||||
* 根据告警ID列表批量删除告警
|
* 根据告警ID列表批量删除告警
|
||||||
* @param ids 告警IDs
|
*
|
||||||
|
* @param ids Alarm ID List 告警IDS
|
||||||
*/
|
*/
|
||||||
void deleteAlerts(HashSet<Long> ids);
|
void deleteAlerts(HashSet<Long> ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Update the alarm status according to the alarm ID-status value
|
||||||
* 根据告警ID-状态值 更新告警状态
|
* 根据告警ID-状态值 更新告警状态
|
||||||
* @param status 待修改为的告警状态
|
*
|
||||||
* @param ids 待修改的告警IDs
|
* @param status Alarm status to be modified 待修改为的告警状态
|
||||||
|
* @param ids Alarm ID List to be modified 待修改的告警ID集合
|
||||||
*/
|
*/
|
||||||
void editAlertStatus(Byte status, List<Long> ids);
|
void editAlertStatus(Byte status, List<Long> ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取告警统计信息
|
* Get alarm statistics information 获取告警统计信息
|
||||||
* @return 告警统计
|
*
|
||||||
|
* @return Alarm statistics information 告警统计
|
||||||
*/
|
*/
|
||||||
AlertSummary getAlertsSummary();
|
AlertSummary getAlertsSummary();
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 告警信息服务实现
|
* Realization of Alarm Information Service 告警信息服务实现
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2021/12/10 15:39
|
* @date 2021/12/10 15:39
|
||||||
*/
|
*/
|
||||||
@@ -55,18 +56,24 @@ public class AlertServiceImpl implements AlertService {
|
|||||||
@Override
|
@Override
|
||||||
public AlertSummary getAlertsSummary() {
|
public AlertSummary getAlertsSummary() {
|
||||||
AlertSummary alertSummary = new AlertSummary();
|
AlertSummary alertSummary = new AlertSummary();
|
||||||
|
//Statistics on the alarm information in the alarm state
|
||||||
|
//统计正在告警状态下的告警信息
|
||||||
List<AlertPriorityNum> priorityNums = alertDao.findAlertPriorityNum();
|
List<AlertPriorityNum> priorityNums = alertDao.findAlertPriorityNum();
|
||||||
if (priorityNums != null) {
|
if (priorityNums != null) {
|
||||||
for (AlertPriorityNum priorityNum : priorityNums) {
|
for (AlertPriorityNum priorityNum : priorityNums) {
|
||||||
switch (priorityNum.getPriority()) {
|
switch (priorityNum.getPriority()) {
|
||||||
case CommonConstants
|
case CommonConstants
|
||||||
.ALERT_PRIORITY_CODE_WARNING:
|
.ALERT_PRIORITY_CODE_WARNING:
|
||||||
alertSummary.setPriorityWarningNum(priorityNum.getNum());break;
|
alertSummary.setPriorityWarningNum(priorityNum.getNum());
|
||||||
|
break;
|
||||||
case CommonConstants.ALERT_PRIORITY_CODE_CRITICAL:
|
case CommonConstants.ALERT_PRIORITY_CODE_CRITICAL:
|
||||||
alertSummary.setPriorityCriticalNum(priorityNum.getNum());break;
|
alertSummary.setPriorityCriticalNum(priorityNum.getNum());
|
||||||
|
break;
|
||||||
case CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY:
|
case CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY:
|
||||||
alertSummary.setPriorityEmergencyNum(priorityNum.getNum());break;
|
alertSummary.setPriorityEmergencyNum(priorityNum.getNum());
|
||||||
default: break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,11 @@
|
|||||||
<artifactId>ojdbc8</artifactId>
|
<artifactId>ojdbc8</artifactId>
|
||||||
<version>21.5.0.0</version>
|
<version>21.5.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oracle.database.nls</groupId>
|
||||||
|
<artifactId>orai18n</artifactId>
|
||||||
|
<version>21.5.0.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -108,8 +108,8 @@ public class CommonHttpClient {
|
|||||||
.setConnectTimeout(CONNECT_TIMEOUT)
|
.setConnectTimeout(CONNECT_TIMEOUT)
|
||||||
// 数据传输最大响应间隔时间
|
// 数据传输最大响应间隔时间
|
||||||
.setSocketTimeout(SOCKET_TIMEOUT)
|
.setSocketTimeout(SOCKET_TIMEOUT)
|
||||||
// 遇到301 302不自动重定向跳转
|
// 遇到301 302自动重定向跳转
|
||||||
.setRedirectsEnabled(false)
|
.setRedirectsEnabled(true)
|
||||||
.build();
|
.build();
|
||||||
// 连接池
|
// 连接池
|
||||||
connectionManager = new PoolingHttpClientConnectionManager(registry);
|
connectionManager = new PoolingHttpClientConnectionManager(registry);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.google.gson.JsonParser;
|
|||||||
import com.usthe.collector.collect.AbstractCollect;
|
import com.usthe.collector.collect.AbstractCollect;
|
||||||
import com.usthe.collector.collect.common.http.CommonHttpClient;
|
import com.usthe.collector.collect.common.http.CommonHttpClient;
|
||||||
import com.usthe.collector.dispatch.DispatchConstants;
|
import com.usthe.collector.dispatch.DispatchConstants;
|
||||||
|
import com.usthe.collector.util.CollectUtil;
|
||||||
import com.usthe.collector.util.CollectorConstants;
|
import com.usthe.collector.util.CollectorConstants;
|
||||||
import com.usthe.collector.util.JsonPathParser;
|
import com.usthe.collector.util.JsonPathParser;
|
||||||
import com.usthe.common.entity.job.Metrics;
|
import com.usthe.common.entity.job.Metrics;
|
||||||
@@ -100,7 +101,7 @@ public class HttpCollectImpl extends AbstractCollect {
|
|||||||
String parseType = metrics.getHttp().getParseType();
|
String parseType = metrics.getHttp().getParseType();
|
||||||
try {
|
try {
|
||||||
if (DispatchConstants.PARSE_DEFAULT.equals(parseType)) {
|
if (DispatchConstants.PARSE_DEFAULT.equals(parseType)) {
|
||||||
parseResponseByDefault(resp, metrics.getAliasFields(), builder, responseTime);
|
parseResponseByDefault(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||||
} else if (DispatchConstants.PARSE_JSON_PATH.equals(parseType)) {
|
} else if (DispatchConstants.PARSE_JSON_PATH.equals(parseType)) {
|
||||||
parseResponseByJsonPath(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
parseResponseByJsonPath(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||||
} else if (DispatchConstants.PARSE_PROMETHEUS.equals(parseType)) {
|
} else if (DispatchConstants.PARSE_PROMETHEUS.equals(parseType)) {
|
||||||
@@ -108,11 +109,11 @@ public class HttpCollectImpl extends AbstractCollect {
|
|||||||
} else if (DispatchConstants.PARSE_XML_PATH.equals(parseType)) {
|
} else if (DispatchConstants.PARSE_XML_PATH.equals(parseType)) {
|
||||||
parseResponseByXmlPath(resp, metrics.getAliasFields(), metrics.getHttp(), builder);
|
parseResponseByXmlPath(resp, metrics.getAliasFields(), metrics.getHttp(), builder);
|
||||||
} else if (DispatchConstants.PARSE_WEBSITE.equals(parseType)){
|
} else if (DispatchConstants.PARSE_WEBSITE.equals(parseType)){
|
||||||
parseResponseByWebsite(resp, metrics.getAliasFields(), builder, responseTime);
|
parseResponseByWebsite(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||||
} else if (DispatchConstants.PARSE_SITE_MAP.equals(parseType)) {
|
} else if (DispatchConstants.PARSE_SITE_MAP.equals(parseType)) {
|
||||||
parseResponseBySiteMap(resp, metrics.getAliasFields(), builder);
|
parseResponseBySiteMap(resp, metrics.getAliasFields(), builder);
|
||||||
} else {
|
} else {
|
||||||
parseResponseByDefault(resp, metrics.getAliasFields(), builder, responseTime);
|
parseResponseByDefault(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.info("parse error: {}.", e.getMessage(), e);
|
log.info("parse error: {}.", e.getMessage(), e);
|
||||||
@@ -169,13 +170,16 @@ public class HttpCollectImpl extends AbstractCollect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseResponseByWebsite(String resp, List<String> aliasFields,
|
private void parseResponseByWebsite(String resp, List<String> aliasFields, HttpProtocol http,
|
||||||
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
||||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||||
// todo resp 网站关键字监测
|
// 网站关键词数量监测
|
||||||
|
int keywordNum = CollectUtil.countMatchKeyword(resp, http.getKeyword());
|
||||||
for (String alias : aliasFields) {
|
for (String alias : aliasFields) {
|
||||||
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
||||||
valueRowBuilder.addColumns(responseTime.toString());
|
valueRowBuilder.addColumns(responseTime.toString());
|
||||||
|
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
|
||||||
|
valueRowBuilder.addColumns(Integer.toString(keywordNum));
|
||||||
} else {
|
} else {
|
||||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||||
}
|
}
|
||||||
@@ -277,6 +281,7 @@ public class HttpCollectImpl extends AbstractCollect {
|
|||||||
private void parseResponseByJsonPath(String resp, List<String> aliasFields, HttpProtocol http,
|
private void parseResponseByJsonPath(String resp, List<String> aliasFields, HttpProtocol http,
|
||||||
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
||||||
List<Map<String, Object>> results = JsonPathParser.parseContentWithJsonPath(resp, http.getParseScript());
|
List<Map<String, Object>> results = JsonPathParser.parseContentWithJsonPath(resp, http.getParseScript());
|
||||||
|
int keywordNum = CollectUtil.countMatchKeyword(resp, http.getKeyword());
|
||||||
for (Map<String, Object> stringMap : results) {
|
for (Map<String, Object> stringMap : results) {
|
||||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||||
for (String alias : aliasFields) {
|
for (String alias : aliasFields) {
|
||||||
@@ -286,6 +291,8 @@ public class HttpCollectImpl extends AbstractCollect {
|
|||||||
} else {
|
} else {
|
||||||
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
||||||
valueRowBuilder.addColumns(responseTime.toString());
|
valueRowBuilder.addColumns(responseTime.toString());
|
||||||
|
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
|
||||||
|
valueRowBuilder.addColumns(Integer.toString(keywordNum));
|
||||||
} else {
|
} else {
|
||||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||||
}
|
}
|
||||||
@@ -300,9 +307,10 @@ public class HttpCollectImpl extends AbstractCollect {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseResponseByDefault(String resp, List<String> aliasFields,
|
private void parseResponseByDefault(String resp, List<String> aliasFields, HttpProtocol http,
|
||||||
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
||||||
JsonElement element = JsonParser.parseString(resp);
|
JsonElement element = JsonParser.parseString(resp);
|
||||||
|
int keywordNum = CollectUtil.countMatchKeyword(resp, http.getKeyword());
|
||||||
if (element.isJsonArray()) {
|
if (element.isJsonArray()) {
|
||||||
JsonArray array = element.getAsJsonArray();
|
JsonArray array = element.getAsJsonArray();
|
||||||
for (JsonElement jsonElement : array) {
|
for (JsonElement jsonElement : array) {
|
||||||
@@ -317,6 +325,8 @@ public class HttpCollectImpl extends AbstractCollect {
|
|||||||
} else {
|
} else {
|
||||||
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
||||||
valueRowBuilder.addColumns(responseTime.toString());
|
valueRowBuilder.addColumns(responseTime.toString());
|
||||||
|
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
|
||||||
|
valueRowBuilder.addColumns(Integer.toString(keywordNum));
|
||||||
} else {
|
} else {
|
||||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,9 +105,13 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
|||||||
.setId(timerJob.getJob().getMonitorId())
|
.setId(timerJob.getJob().getMonitorId())
|
||||||
.setApp(timerJob.getJob().getApp())
|
.setApp(timerJob.getJob().getApp())
|
||||||
.setMetrics(metricsTime.getMetrics().getName())
|
.setMetrics(metricsTime.getMetrics().getName())
|
||||||
|
.setPriority(metricsTime.getMetrics().getPriority())
|
||||||
.setTime(System.currentTimeMillis())
|
.setTime(System.currentTimeMillis())
|
||||||
.setCode(CollectRep.Code.TIMEOUT).setMsg("collect timeout").build();
|
.setCode(CollectRep.Code.TIMEOUT).setMsg("collect timeout").build();
|
||||||
|
log.error("[Collect Timeout]: \n{}", metricsData);
|
||||||
|
if (metricsData.getPriority() == 0) {
|
||||||
dispatchCollectData(metricsTime.timeout, metricsTime.getMetrics(), metricsData);
|
dispatchCollectData(metricsTime.timeout, metricsTime.getMetrics(), metricsData);
|
||||||
|
}
|
||||||
metricsTimeoutMonitorMap.remove(entry.getKey());
|
metricsTimeoutMonitorMap.remove(entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,8 +169,8 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
|||||||
metricsSet.forEach(metricItem -> {
|
metricsSet.forEach(metricItem -> {
|
||||||
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
|
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
|
||||||
jobRequestQueue.addJob(metricsCollect);
|
jobRequestQueue.addJob(metricsCollect);
|
||||||
metricsTimeoutMonitorMap.put(job.getId() + "-" + metrics.getName(),
|
metricsTimeoutMonitorMap.put(job.getId() + "-" + metricItem.getName(),
|
||||||
new MetricsTime(System.currentTimeMillis(), metrics, timeout));
|
new MetricsTime(System.currentTimeMillis(), metricItem, timeout));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 当前执行级别的指标组列表未全执行完成,
|
// 当前执行级别的指标组列表未全执行完成,
|
||||||
@@ -185,8 +189,8 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
|||||||
metricsSet.forEach(metricItem -> {
|
metricsSet.forEach(metricItem -> {
|
||||||
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
|
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
|
||||||
jobRequestQueue.addJob(metricsCollect);
|
jobRequestQueue.addJob(metricsCollect);
|
||||||
metricsTimeoutMonitorMap.put(job.getId() + "-" + metrics.getName(),
|
metricsTimeoutMonitorMap.put(job.getId() + "-" + metricItem.getName(),
|
||||||
new MetricsTime(System.currentTimeMillis(), metrics, timeout));
|
new MetricsTime(System.currentTimeMillis(), metricItem, timeout));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 当前执行级别的指标组列表未全执行完成,
|
// 当前执行级别的指标组列表未全执行完成,
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Data
|
@Data
|
||||||
public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
||||||
|
/**
|
||||||
|
* 调度告警阈值时间 100ms
|
||||||
|
*/
|
||||||
|
private static final long WARN_DISPATCH_TIME = 100;
|
||||||
/**
|
/**
|
||||||
* 监控ID
|
* 监控ID
|
||||||
*/
|
*/
|
||||||
@@ -243,6 +247,10 @@ public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
|||||||
value = aliasFieldValueMap.get(realField);
|
value = aliasFieldValueMap.get(realField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 处理可能带单位的指标数值 比如 34%, 34Mb,并将数值小数点限制到4位
|
||||||
|
if (CommonConstants.TYPE_NUMBER == field.getType()) {
|
||||||
|
value = CommonUtil.parseDoubleStr(value, field.getUnit());
|
||||||
|
}
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = CommonConstants.NULL_VALUE;
|
value = CommonConstants.NULL_VALUE;
|
||||||
}
|
}
|
||||||
@@ -267,11 +275,15 @@ public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
|
|||||||
private CollectRep.MetricsData validateResponse(CollectRep.MetricsData.Builder builder) {
|
private CollectRep.MetricsData validateResponse(CollectRep.MetricsData.Builder builder) {
|
||||||
long endTime = System.currentTimeMillis();
|
long endTime = System.currentTimeMillis();
|
||||||
builder.setTime(endTime);
|
builder.setTime(endTime);
|
||||||
log.debug("[Collect]: newTime: {}, startTime: {}, spendTime: {}.", newTime, startTime, endTime - startTime);
|
long runningTime = endTime - startTime;
|
||||||
|
long allTime = endTime - newTime;
|
||||||
|
if (startTime - newTime >= WARN_DISPATCH_TIME) {
|
||||||
|
log.warn("[Collector Dispatch Warn, Dispatch Use {}ms.", startTime - newTime);
|
||||||
|
}
|
||||||
if (builder.getCode() != CollectRep.Code.SUCCESS) {
|
if (builder.getCode() != CollectRep.Code.SUCCESS) {
|
||||||
log.info("[Collect Fail] Reason: {}", builder.getMsg());
|
log.info("[Collect Failed, Run {}ms, All {}ms] Reason: {}", runningTime, allTime, builder.getMsg());
|
||||||
} else {
|
} else {
|
||||||
log.info("[Collect Success].");
|
log.info("[Collect Success, Run {}ms, All {}ms].", runningTime, allTime);
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class WheelTimerTask implements TimerTask {
|
|||||||
if (key != null && key.startsWith("^_^") && key.endsWith("^_^")) {
|
if (key != null && key.startsWith("^_^") && key.endsWith("^_^")) {
|
||||||
key = key.replaceAll("\\^_\\^", "");
|
key = key.replaceAll("\\^_\\^", "");
|
||||||
Configmap param = configmap.get(key);
|
Configmap param = configmap.get(key);
|
||||||
if (param.getType() == (byte) 3) {
|
if (param != null && param.getType() == (byte) 3) {
|
||||||
String jsonValue = (String) param.getValue();
|
String jsonValue = (String) param.getValue();
|
||||||
Map<String, String> map = GsonUtil.fromJson(jsonValue, Map.class);
|
Map<String, String> map = GsonUtil.fromJson(jsonValue, Map.class);
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.usthe.collector.util;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 采集器工具类
|
||||||
|
* @author tom
|
||||||
|
* @date 2022/4/6 09:35
|
||||||
|
*/
|
||||||
|
public class CollectUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关键字匹配计数
|
||||||
|
* @param content 内容
|
||||||
|
* @param keyword 关键字
|
||||||
|
* @return 匹配次数
|
||||||
|
*/
|
||||||
|
public static int countMatchKeyword(String content, String keyword) {
|
||||||
|
if (content == null || "".equals(content) || keyword == null || "".equals(keyword.trim())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Pattern pattern = Pattern.compile(keyword);
|
||||||
|
Matcher matcher = pattern.matcher(content);
|
||||||
|
int count = 0;
|
||||||
|
while (matcher.find()) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,8 @@ public interface CollectorConstants {
|
|||||||
|
|
||||||
String RESPONSE_TIME = "responseTime";
|
String RESPONSE_TIME = "responseTime";
|
||||||
|
|
||||||
|
String KEYWORD = "keyword";
|
||||||
|
|
||||||
String STATUS_CODE = "statusCode";
|
String STATUS_CODE = "statusCode";
|
||||||
|
|
||||||
String ERROR_MSG = "errorMsg";
|
String ERROR_MSG = "errorMsg";
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.apache.commons.net.telnet.TelnetClient;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.ConnectException;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ class TelnetCollectImplTest {
|
|||||||
telnetClient = new TelnetClient("vt200");
|
telnetClient = new TelnetClient("vt200");
|
||||||
telnetClient.setConnectTimeout(5000);
|
telnetClient.setConnectTimeout(5000);
|
||||||
TelnetClient finalTelnetClient = telnetClient;
|
TelnetClient finalTelnetClient = telnetClient;
|
||||||
assertDoesNotThrow(() -> finalTelnetClient.connect("baidu.com",80));
|
assertThrows(ConnectException.class,() -> finalTelnetClient.connect("127.0.0.1",0));
|
||||||
telnetClient.disconnect();
|
telnetClient.disconnect();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
|
|||||||
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
|
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 告警记录
|
* Alarm record entity 告警记录实体
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2021/12/9 15:37
|
* @date 2021/12/9 15:37
|
||||||
*/
|
*/
|
||||||
@@ -33,52 +34,68 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
|
|||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ApiModel(description = "告警记录实体")
|
@ApiModel(description = "en: Alarm record entity zh: 告警记录实体")
|
||||||
public class Alert {
|
public class Alert {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@ApiModelProperty(value = "告警记录实体主键索引ID", example = "87584674384", accessMode = READ_ONLY, position = 0)
|
@ApiModelProperty(value = "Alarm record entity primary key index ID",
|
||||||
|
notes = "告警记录实体主键索引ID",
|
||||||
|
example = "87584674384", accessMode = READ_ONLY, position = 0)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警目标对象: 监控可用性-available 指标-app.metrics.field",
|
@ApiModelProperty(value = "Alert target object: monitor availability-available metrics-app.metrics.field",
|
||||||
|
notes = "告警目标对象: 监控可用性-available 指标-app.metrics.field",
|
||||||
example = "1", accessMode = READ_WRITE, position = 1)
|
example = "1", accessMode = READ_WRITE, position = 1)
|
||||||
@Length(max = 255)
|
@Length(max = 255)
|
||||||
private String target;
|
private String target;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警对象关联的监控ID", example = "87432674336", accessMode = READ_WRITE, position = 2)
|
@ApiModelProperty(value = "Monitoring ID associated with the alarm object",
|
||||||
|
notes = "告警对象关联的监控ID",
|
||||||
|
example = "87432674336", accessMode = READ_WRITE, position = 2)
|
||||||
private Long monitorId;
|
private Long monitorId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警对象关联的监控名称", example = "Linux_192.132.23.1",
|
@ApiModelProperty(value = "Monitoring name associated with the alarm object",
|
||||||
accessMode = READ_WRITE, position = 3)
|
notes = "告警对象关联的监控名称",
|
||||||
|
example = "Linux_192.132.23.1", accessMode = READ_WRITE, position = 3)
|
||||||
private String monitorName;
|
private String monitorName;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警关联的告警定义ID", example = "8743267443543", accessMode = READ_WRITE, position = 4)
|
@ApiModelProperty(value = "Alarm definition ID associated with the alarm",
|
||||||
|
notes = "告警关联的告警定义ID",
|
||||||
|
example = "8743267443543", accessMode = READ_WRITE, position = 4)
|
||||||
private Long alertDefineId;
|
private Long alertDefineId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警级别 0:高-emergency-紧急告警-红色 1:中-critical-严重告警-橙色 2:低-warning-警告告警-黄色",
|
@ApiModelProperty(value = "Alarm level 0: high-emergency-critical alarm-red 1: medium-critical-critical alarm-orange 2: low-warning-warning alarm-yellow",
|
||||||
|
notes = "告警级别 0:高-emergency-紧急告警-红色 1:中-critical-严重告警-橙色 2:低-warning-警告告警-黄色",
|
||||||
example = "1", accessMode = READ_WRITE, position = 5)
|
example = "1", accessMode = READ_WRITE, position = 5)
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@Max(2)
|
@Max(2)
|
||||||
private byte priority;
|
private byte priority;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警通知实际内容", example = "linux_192.134.32.1: 534543534 cpu usage high",
|
@ApiModelProperty(value = "The actual content of the alarm notification",
|
||||||
|
notes = "告警通知实际内容",
|
||||||
|
example = "linux_192.134.32.1: 534543534 cpu usage high",
|
||||||
accessMode = READ_WRITE, position = 6)
|
accessMode = READ_WRITE, position = 6)
|
||||||
@Length(max = 1024)
|
@Length(max = 1024)
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警状态: 0-正常告警(待处理) 1-阈值触发但未达到告警次数 2-恢复告警 3-已处理",
|
@ApiModelProperty(value = "Alarm status: 0-normal alarm (to be processed) 1-threshold triggered but not reached the number of alarms 2-recovered alarm 3-processed",
|
||||||
|
notes = "告警状态: 0-正常告警(待处理) 1-阈值触发但未达到告警次数 2-恢复告警 3-已处理",
|
||||||
example = "1", accessMode = READ_WRITE, position = 7)
|
example = "1", accessMode = READ_WRITE, position = 7)
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@Max(2)
|
@Max(2)
|
||||||
private byte status;
|
private byte status;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警阈值触发次数", example = "3", accessMode = READ_WRITE, position = 8)
|
@ApiModelProperty(value = "Alarm threshold trigger times",
|
||||||
|
notes = "告警阈值触发次数",
|
||||||
|
example = "3", accessMode = READ_WRITE, position = 8)
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@Max(10)
|
@Max(10)
|
||||||
private int times;
|
private int times;
|
||||||
|
|
||||||
@ApiModelProperty(value = "告警触发时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 9)
|
@ApiModelProperty(value = "Alarm trigger time (timestamp in milliseconds)",
|
||||||
|
notes = "告警触发时间(毫秒时间戳)",
|
||||||
|
example = "1612198922000", accessMode = READ_ONLY, position = 9)
|
||||||
@Column(insertable = false, updatable = false)
|
@Column(insertable = false, updatable = false)
|
||||||
private LocalDateTime gmtCreate;
|
private LocalDateTime gmtCreate;
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ public class HttpProtocol {
|
|||||||
* http请求携带的请求体
|
* http请求携带的请求体
|
||||||
*/
|
*/
|
||||||
private String payload;
|
private String payload;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 认证信息
|
* 认证信息
|
||||||
*/
|
*/
|
||||||
@@ -66,6 +65,10 @@ public class HttpProtocol {
|
|||||||
* 数据解析脚本 当解析方式为 jsonPath or xmlPath时存在
|
* 数据解析脚本 当解析方式为 jsonPath or xmlPath时存在
|
||||||
*/
|
*/
|
||||||
private String parseScript;
|
private String parseScript;
|
||||||
|
/**
|
||||||
|
* 内容关键字
|
||||||
|
*/
|
||||||
|
private String keyword;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 认证信息
|
* 认证信息
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
|
|||||||
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
|
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Message notification recipient entity
|
||||||
* 消息通知接收人实体
|
* 消息通知接收人实体
|
||||||
|
*
|
||||||
* @author tomsun28
|
* @author tomsun28
|
||||||
* @date 2021/11/13 22:19
|
* @date 2021/11/13 22:19
|
||||||
*/
|
*/
|
||||||
@@ -33,56 +35,80 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
|
|||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ApiModel(description = "消息通知接收人实体")
|
@ApiModel(description = "en: Message notification recipient entity,zh:消息通知接收人实体")
|
||||||
public class NoticeReceiver {
|
public class NoticeReceiver {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@ApiModelProperty(value = "接收人实体主键索引ID", example = "87584674384", accessMode = READ_ONLY, position = 0)
|
@ApiModelProperty(value = "Recipient entity primary key index ID",
|
||||||
|
notes = "接收人实体主键索引ID",
|
||||||
|
example = "87584674384", accessMode = READ_ONLY, position = 0)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@ApiModelProperty(value = "接收人名称", example = "tom", accessMode = READ_WRITE, position = 1)
|
@ApiModelProperty(value = "Recipient name",
|
||||||
|
notes = "接收人名称",
|
||||||
|
example = "tom", accessMode = READ_WRITE, position = 1)
|
||||||
@Length(max = 100)
|
@Length(max = 100)
|
||||||
@NotNull
|
@NotNull
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@ApiModelProperty(value = "通知信息方式: 0-手机短信 1-邮箱 2-webhook 3-微信公众号 4-企业微信机器人 5-钉钉机器人 6-飞书机器人", accessMode = READ_WRITE, position = 2)
|
@ApiModelProperty(value = "Notification information method: 0-SMS 1-Email 2-webhook 3-WeChat Official Account 4-Enterprise WeChat Robot 5-DingTalk Robot 6-FeiShu Robot",
|
||||||
|
notes = "通知信息方式: 0-手机短信 1-邮箱 2-webhook 3-微信公众号 4-企业微信机器人 5-钉钉机器人 6-飞书机器人",
|
||||||
|
accessMode = READ_WRITE, position = 2)
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@Max(8)
|
@Max(8)
|
||||||
@NotNull
|
@NotNull
|
||||||
private Byte type;
|
private Byte type;
|
||||||
|
|
||||||
@ApiModelProperty(value = "手机号, 通知方式为手机短信时有效", example = "18923435643", accessMode = READ_WRITE, position = 3)
|
@ApiModelProperty(value = "Mobile number: Valid when the notification method is SMS",
|
||||||
|
notes = "手机号 : 通知方式为手机短信时有效",
|
||||||
|
example = "18923435643", accessMode = READ_WRITE, position = 3)
|
||||||
@Length(max = 100)
|
@Length(max = 100)
|
||||||
private String phone;
|
private String phone;
|
||||||
|
|
||||||
@ApiModelProperty(value = "邮箱账号, 通知方式为邮箱时有效", example = "tom@qq.com", accessMode = READ_WRITE, position = 4)
|
@ApiModelProperty(value = "Email account: Valid when the notification method is email",
|
||||||
|
notes = "邮箱账号 : 通知方式为邮箱时有效",
|
||||||
|
example = "tom@qq.com", accessMode = READ_WRITE, position = 4)
|
||||||
@Length(max = 100)
|
@Length(max = 100)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@ApiModelProperty(value = "URL地址, 通知方式为webhook有效", example = "https://www.tancloud.cn", accessMode = READ_WRITE, position = 5)
|
@ApiModelProperty(value = "URL address: The notification method is valid for webhook",
|
||||||
|
notes = "URL地址 : 通知方式为webhook有效",
|
||||||
|
example = "https://www.tancloud.cn", accessMode = READ_WRITE, position = 5)
|
||||||
@Length(max = 300)
|
@Length(max = 300)
|
||||||
private String hookUrl;
|
private String hookUrl;
|
||||||
|
|
||||||
@ApiModelProperty(value = "openId, 通知方式为微信公众号或企业微信机器人有效", example = "343432", accessMode = READ_WRITE, position = 6)
|
@ApiModelProperty(value = "openId : The notification method is valid for WeChat official account or enterprise WeChat robot",
|
||||||
|
notes = "openId : 通知方式为微信公众号或企业微信机器人有效",
|
||||||
|
example = "343432", accessMode = READ_WRITE, position = 6)
|
||||||
@Length(max = 300)
|
@Length(max = 300)
|
||||||
private String wechatId;
|
private String wechatId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "访问token, 通知方式为钉钉机器人有效", example = "34823984635647", accessMode = READ_WRITE, position = 7)
|
@ApiModelProperty(value = "Access token : The notification method is valid for DingTalk robot",
|
||||||
|
notes = "访问token : 通知方式为钉钉机器人有效",
|
||||||
|
example = "34823984635647", accessMode = READ_WRITE, position = 7)
|
||||||
@Length(max = 300)
|
@Length(max = 300)
|
||||||
private String accessToken;
|
private String accessToken;
|
||||||
|
|
||||||
@ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 7)
|
@ApiModelProperty(value = "The creator of this record",
|
||||||
|
notes = "此条记录创建者",
|
||||||
|
example = "tom", accessMode = READ_ONLY, position = 7)
|
||||||
private String creator;
|
private String creator;
|
||||||
|
|
||||||
@ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 8)
|
@ApiModelProperty(value = "This record was last modified by",
|
||||||
|
notes = "此条记录最新修改者",
|
||||||
|
example = "tom", accessMode = READ_ONLY, position = 8)
|
||||||
private String modifier;
|
private String modifier;
|
||||||
|
|
||||||
@ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 9)
|
@ApiModelProperty(value = "Record creation time (millisecond timestamp)",
|
||||||
|
notes = "记录创建时间(毫秒时间戳)",
|
||||||
|
example = "1612198922000", accessMode = READ_ONLY, position = 9)
|
||||||
@Column(insertable = false, updatable = false)
|
@Column(insertable = false, updatable = false)
|
||||||
private LocalDateTime gmtCreate;
|
private LocalDateTime gmtCreate;
|
||||||
|
|
||||||
@ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 10)
|
@ApiModelProperty(value = "Record the latest modification time (timestamp in milliseconds)",
|
||||||
|
notes = "记录最新修改时间(毫秒时间戳)",
|
||||||
|
example = "1612198444000", accessMode = READ_ONLY, position = 10)
|
||||||
@Column(insertable = false, updatable = false)
|
@Column(insertable = false, updatable = false)
|
||||||
private LocalDateTime gmtUpdate;
|
private LocalDateTime gmtUpdate;
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
|
|||||||
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
|
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Notification strategy entity
|
||||||
* 通知策略
|
* 通知策略
|
||||||
|
*
|
||||||
* @author tomsun28
|
* @author tomsun28
|
||||||
* @date 2021/11/13 22:19
|
* @date 2021/11/13 22:19
|
||||||
*/
|
*/
|
||||||
@@ -31,45 +33,65 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
|
|||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ApiModel(description = "通知策略实体")
|
@ApiModel(description = "en: Notify Policy Entity,zh: 通知策略实体")
|
||||||
public class NoticeRule {
|
public class NoticeRule {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@ApiModelProperty(value = "通知策略实体主键索引ID", example = "87584674384", accessMode = READ_ONLY, position = 0)
|
@ApiModelProperty(value = "Notification Policy Entity Primary Key Index ID",
|
||||||
|
notes = "通知策略实体主键索引ID",
|
||||||
|
example = "87584674384", accessMode = READ_ONLY, position = 0)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@ApiModelProperty(value = "策略名称", example = "dispatch-1", accessMode = READ_WRITE, position = 1)
|
@ApiModelProperty(value = "Policy name",
|
||||||
|
notes = "策略名称",
|
||||||
|
example = "dispatch-1", accessMode = READ_WRITE, position = 1)
|
||||||
@Length(max = 100)
|
@Length(max = 100)
|
||||||
@NotNull
|
@NotNull
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@ApiModelProperty(value = "接收人ID", example = "4324324", accessMode = READ_WRITE, position = 2)
|
@ApiModelProperty(value = "Recipient ID",
|
||||||
|
notes = "接收人ID",
|
||||||
|
example = "4324324", accessMode = READ_WRITE, position = 2)
|
||||||
@NotNull
|
@NotNull
|
||||||
private Long receiverId;
|
private Long receiverId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "接收人标识", example = "tom", accessMode = READ_WRITE, position = 3)
|
@ApiModelProperty(value = "Recipient identification",
|
||||||
|
notes = "接收人标识",
|
||||||
|
example = "tom", accessMode = READ_WRITE, position = 3)
|
||||||
@Length(max = 100)
|
@Length(max = 100)
|
||||||
@NotNull
|
@NotNull
|
||||||
private String receiverName;
|
private String receiverName;
|
||||||
|
|
||||||
@ApiModelProperty(value = "是否启用此策略", example = "true", accessMode = READ_WRITE, position = 4)
|
@ApiModelProperty(value = "Whether to enable this policy",
|
||||||
|
notes = "是否启用此策略",
|
||||||
|
example = "true", accessMode = READ_WRITE, position = 4)
|
||||||
private boolean enable = true;
|
private boolean enable = true;
|
||||||
|
|
||||||
@ApiModelProperty(value = "是否转发所有", example = "false", accessMode = READ_WRITE, position = 5)
|
@ApiModelProperty(value = "Whether to forward all",
|
||||||
|
notes = "是否转发所有",
|
||||||
|
example = "false", accessMode = READ_WRITE, position = 5)
|
||||||
private boolean filterAll = true;
|
private boolean filterAll = true;
|
||||||
|
|
||||||
@ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 7)
|
@ApiModelProperty(value = "The creator of this record",
|
||||||
|
notes = "此条记录创建者",
|
||||||
|
example = "tom", accessMode = READ_ONLY, position = 7)
|
||||||
private String creator;
|
private String creator;
|
||||||
|
|
||||||
@ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 8)
|
@ApiModelProperty(value = "This record was last modified by",
|
||||||
|
notes = "此条记录最新修改者",
|
||||||
|
example = "tom", accessMode = READ_ONLY, position = 8)
|
||||||
private String modifier;
|
private String modifier;
|
||||||
|
|
||||||
@ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 9)
|
@ApiModelProperty(value = "This record creation time (millisecond timestamp)",
|
||||||
|
notes = "记录创建时间(毫秒时间戳)",
|
||||||
|
example = "1612198922000", accessMode = READ_ONLY, position = 9)
|
||||||
@Column(insertable = false, updatable = false)
|
@Column(insertable = false, updatable = false)
|
||||||
private LocalDateTime gmtCreate;
|
private LocalDateTime gmtCreate;
|
||||||
|
|
||||||
@ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 10)
|
@ApiModelProperty(value = "Record the latest modification time (timestamp in milliseconds)",
|
||||||
|
notes = "记录最新修改时间(毫秒时间戳)",
|
||||||
|
example = "1612198444000", accessMode = READ_ONLY, position = 10)
|
||||||
@Column(insertable = false, updatable = false)
|
@Column(insertable = false, updatable = false)
|
||||||
private LocalDateTime gmtUpdate;
|
private LocalDateTime gmtUpdate;
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,12 @@ public class ParamDefine {
|
|||||||
@ApiModelProperty(value = "当type为key-value时有效,表示value的别名描述", example = "Value", accessMode = READ_WRITE, position = 10)
|
@ApiModelProperty(value = "当type为key-value时有效,表示value的别名描述", example = "Value", accessMode = READ_WRITE, position = 10)
|
||||||
private String valueAlias;
|
private String valueAlias;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是高级隐藏参数 true-是 false-否
|
||||||
|
*/
|
||||||
|
@ApiModelProperty(value = "是否是高级隐藏参数 true-是 false-否", example = "true", accessMode = READ_WRITE, position = 11)
|
||||||
|
private boolean hide = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 此条记录创建者
|
* 此条记录创建者
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.usthe.common.util;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -15,7 +17,7 @@ public class CommonUtil {
|
|||||||
|
|
||||||
private static final Pattern EMAIL_PATTERN = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
|
private static final Pattern EMAIL_PATTERN = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
|
||||||
|
|
||||||
private static final Pattern PHONE_PATTERN = Pattern.compile("^(((13[0-9])|(15[0-9])|(18[0-9])|(17[0-9]))+\\d{8})?$");
|
private static final Pattern PHONE_PATTERN = Pattern.compile("^(((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(19[0-9])|(18[0-9])|(17[0-9]))+\\d{8})?$");
|
||||||
|
|
||||||
private static final int PHONE_LENGTH = 11;
|
private static final int PHONE_LENGTH = 11;
|
||||||
|
|
||||||
@@ -36,6 +38,30 @@ public class CommonUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串str,此字符串可能带单位,转换为double数字类型
|
||||||
|
* 将数值小数点限制到4位
|
||||||
|
* @param str string
|
||||||
|
* @param unit 字符串单位
|
||||||
|
* @return string格式的 double 数字 小数点最大到4位
|
||||||
|
*/
|
||||||
|
public static String parseDoubleStr(String str, String unit) {
|
||||||
|
if (str == null || "".equals(str)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (unit != null && str.endsWith(unit)) {
|
||||||
|
str = str.substring(0, str.length() - unit.length());
|
||||||
|
}
|
||||||
|
BigDecimal bigDecimal = new BigDecimal(str);
|
||||||
|
double value = bigDecimal.setScale(4, RoundingMode.HALF_UP).doubleValue();
|
||||||
|
return String.valueOf(value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug(e.getMessage(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 邮箱格式校验
|
* 邮箱格式校验
|
||||||
* @param email 邮箱
|
* @param email 邮箱
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.usthe.common.util;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tom
|
||||||
|
* @date 2022/4/7 17:18
|
||||||
|
*/
|
||||||
|
class CommonUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testParseDoubleStr() {
|
||||||
|
assertEquals("9.3454",CommonUtil.parseDoubleStr("9.345435345", null));
|
||||||
|
assertEquals("9.3454",CommonUtil.parseDoubleStr("9.345435345%", "%"));
|
||||||
|
assertEquals("10.0",CommonUtil.parseDoubleStr("10%", "%"));
|
||||||
|
assertEquals("588.0",CommonUtil.parseDoubleStr("588Mb", "Mb"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validateEmail() {
|
||||||
|
assertTrue(CommonUtil.validateEmail("tom@usthe.com"));
|
||||||
|
assertTrue(CommonUtil.validateEmail("demo@qq.com"));
|
||||||
|
assertFalse(CommonUtil.validateEmail("tom.usthe.com"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validatePhoneNum() {
|
||||||
|
assertTrue(CommonUtil.validatePhoneNum("19234554432"));
|
||||||
|
assertTrue(CommonUtil.validatePhoneNum("13234554432"));
|
||||||
|
assertTrue(CommonUtil.validatePhoneNum("14234554432"));
|
||||||
|
assertTrue(CommonUtil.validatePhoneNum("16234554432"));
|
||||||
|
assertFalse(CommonUtil.validatePhoneNum("12234554432"));
|
||||||
|
assertFalse(CommonUtil.validatePhoneNum("11234554432"));
|
||||||
|
assertFalse(CommonUtil.validatePhoneNum("35234554432"));
|
||||||
|
assertFalse(CommonUtil.validatePhoneNum("46234554432"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
92
home/blog/2022-04-08-hertzbeat-v1.0-beta.7.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
---
|
||||||
|
title: HertzBeat入GVP啦,并 v1.0.beta.7 发布,易用友好的云监控系统
|
||||||
|
author: tom
|
||||||
|
author_title: tom
|
||||||
|
author_url: https://github.com/tomsun28
|
||||||
|
author_image_url: https://avatars.githubusercontent.com/u/24788200?s=400&v=4
|
||||||
|
tags: [opensource]
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
HertzBeat赫兹跳动 是一个由Dromara孵化的支持网站,API,PING,端口,数据库,全站,操作系统等监控类型,支持阈值告警,告警通知(邮箱,webhook,钉钉,企业微信,飞书机器人),拥有易用友好的可视化操作界面的开源监控告警项目。
|
||||||
|
|
||||||
|
很高兴Hertzbeat被评定为GVP - Gitee最有价值开源项目!
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
老哥们帮忙在Gitee STAR起来,冲!https://gitee.com/dromara/hertzbeat
|
||||||
|
|
||||||
|
官网:hertzbeat.com | tancloud.cn
|
||||||
|
|
||||||
|
然后来说说最新的版本,这个版本看这么多feature,其实简单来说主要是这几个
|
||||||
|
|
||||||
|
支持了ORACLE数据库的监控,包括ORACLE的基本信息,表空间,连接数,TPS,QPS等指标
|
||||||
|
|
||||||
|
支持了LINUX的CPU利用率,内存利用率,磁盘占用相关指标,使LINUX监控贴合实际业务
|
||||||
|
|
||||||
|
还有前端参数支持了KEY-VALUE,以后我们就可以在页面上配置HTTP Headers等类似参数了,还有就是参数配置那优化改版,把非常用告警参数隐藏起来了,稍微好看些,然后支持了windows下bat启动脚本,更多的就是稳定性的提升和一些其它的小修复小需求啦!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
版本特性:
|
||||||
|
|
||||||
|
1. feature 支持oracle数据库监控类型-xgf 由 @gf-8 贡献 thanks
|
||||||
|
2. feature oracle监控支持tablespace,连接数,qps,tps等指标
|
||||||
|
3. feature linux监控支持设置超时时间 (#49)
|
||||||
|
4. feature 检测网站SSL证书是否过期 (#50) 由 @weihongbin 提出 thanks
|
||||||
|
5. feature 页面配置参数支持KEY-VALUE数组(#57)
|
||||||
|
6. feature API和网站监控支持页面配置Headers和Params (#58)(#59)
|
||||||
|
7. feature API和网站监控支持页面配置 basic auth, digest auth (#60)
|
||||||
|
8. feature http 端口跟随SSL是否启用变更443或80 (#61)
|
||||||
|
9. feature 修改默认超时时间3000毫秒为6000毫秒 (#55)
|
||||||
|
10. feature:make tdengine optional, not required (#62)
|
||||||
|
11. feature:support win bat service (#65)
|
||||||
|
12. feature:support hide advanced params define (#68)
|
||||||
|
13. feature:enable auto redirect when 301 302 http code (#69)
|
||||||
|
14. feature:only collect available metrics when detect (#70)
|
||||||
|
15. feature:[website api]monitor support keyword match (#72)
|
||||||
|
16. feature:support linux cpu usage,memory usage,disk free (#76)
|
||||||
|
|
||||||
|
BUG修复
|
||||||
|
1. 添加sqlserver关联文档,fix connection指标入库tdengine失败 (#41)
|
||||||
|
2. 使用docker部署TDengine,开放tcp访问端口!16 由 @老姜bei 贡献 thanks
|
||||||
|
3. 补充sureness配置文档 避免误配导致权限异常
|
||||||
|
4. bugfix:monitors always timeout alert (#67)
|
||||||
|
5. code format and optimization 由 @学习代码的小白 贡献 thanks
|
||||||
|
6. bugfix: remove oracle field - database_type due 11g not support 由 @syongaaa 贡献 thanks
|
||||||
|
7. bugfix:fix linux interface metrics no instance (#75)
|
||||||
|
|
||||||
|
欢迎在线试用 https://console.tancloud.cn.
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
> [HertzBeat赫兹跳动](https://github.com/dromara/hertzbeat) 是一个支持网站,API,PING,端口,数据库,操作系统等监控类型,拥有易用友好的可视化操作界面的开源监控告警项目。
|
||||||
|
> 我们也提供了对应的 **[SAAS版本监控云](https://console.tancloud.cn)**,中小团队和个人无需再为了监控自己的网站资源,而去部署一套繁琐的监控系统,**[登录即可免费开始](https://console.tancloud.cn)**。
|
||||||
|
> HertzBeat 支持[自定义监控](https://hertzbeat.com/docs/advanced/extend-point) ,只用通过配置YML文件我们就可以自定义需要的监控类型和指标,来满足常见的个性化需求。
|
||||||
|
> HertzBeat 模块化,`manager, collector, scheduler, warehouse, alerter` 各个模块解耦合,方便理解与定制开发。
|
||||||
|
> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模版,邮件钉钉微信飞书等及时通知送达
|
||||||
|
> 欢迎登录 HertzBeat 的 [云环境TanCloud](https://console.tancloud.cn) 试用发现更多。
|
||||||
|
> 我们正在快速迭代中,欢迎参与加入一起共建项目开源生态。
|
||||||
|
|
||||||
|
> `HertzBeat`的多类型支持,易扩展,低耦合,希望能帮助开发者和中小团队快速搭建自有监控系统。
|
||||||
|
|
||||||
|
老铁们可以通过演示视频来直观了解功能: https://www.bilibili.com/video/BV1DY4y1i7ts
|
||||||
|
|
||||||
|
欢迎在线试用 [https://console.tancloud.cn](https://gitee.com/link?target=https%3A%2F%2Fconsole.tancloud.cn)
|
||||||
|
|
||||||
|
优化后的参数输入界面:
|
||||||
|

|
||||||
|
|
||||||
|
Linux新增指标:
|
||||||
|

|
||||||
|
|
||||||
|
ORACLE监控:
|
||||||
|
哦豁!oracle环境不在了,之前没有截图,先脑补一张!
|
||||||
|
|
||||||
|
**仓库地址**
|
||||||
|
|
||||||
|
[Github](https://github.com/dromara/hertzbeat) https://github.com/dromara/hertzbeat
|
||||||
|
[Gitee](https://gitee.com/dromara/hertzbeat) https://gitee.com/dromara/hertzbeat
|
||||||
|
|
||||||
|
看到这里不妨给个Star支持下哦,灰常感谢,弯腰!!
|
||||||
@@ -38,6 +38,7 @@ sidebar_label: Linux操作系统
|
|||||||
| interrupt | 个数 | CPU中断数量 |
|
| interrupt | 个数 | CPU中断数量 |
|
||||||
| load | 无 | CPU最近1/5/15分钟的平均负载 |
|
| load | 无 | CPU最近1/5/15分钟的平均负载 |
|
||||||
| context_switch | 个数 | 当前上下文切换数量 |
|
| context_switch | 个数 | 当前上下文切换数量 |
|
||||||
|
| usage | % | CPU使用率 |
|
||||||
|
|
||||||
|
|
||||||
#### 指标集合:memory
|
#### 指标集合:memory
|
||||||
@@ -49,6 +50,7 @@ sidebar_label: Linux操作系统
|
|||||||
| free | Mb | 空闲内存容量 |
|
| free | Mb | 空闲内存容量 |
|
||||||
| buff_cache | Mb | 缓存占用内存 |
|
| buff_cache | Mb | 缓存占用内存 |
|
||||||
| available | Mb | 剩余可用内存容 |
|
| available | Mb | 剩余可用内存容 |
|
||||||
|
| usage | % | 内存使用率 |
|
||||||
|
|
||||||
#### 指标集合:disk
|
#### 指标集合:disk
|
||||||
|
|
||||||
@@ -68,3 +70,12 @@ sidebar_label: Linux操作系统
|
|||||||
| receive_bytes | byte | 入站数据流量(bytes) |
|
| receive_bytes | byte | 入站数据流量(bytes) |
|
||||||
| transmit_bytes | byte | 出站数据流量(bytes) |
|
| transmit_bytes | byte | 出站数据流量(bytes) |
|
||||||
|
|
||||||
|
#### 指标集合:disk_free
|
||||||
|
|
||||||
|
| 指标名称 | 指标单位 | 指标帮助描述 |
|
||||||
|
| ----------- | ----------- | ----------- |
|
||||||
|
| filesystem | 无 | 文件系统的名称 |
|
||||||
|
| used | Mb | 已使用磁盘大小 |
|
||||||
|
| available | Mb | 可用磁盘大小 |
|
||||||
|
| usage | % | 使用率 |
|
||||||
|
| mounted | 无 | 挂载点目录 |
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ sidebar_label: 赞助
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
感谢[吉实信息(构建全新的微波+光交易网络)](https://www.flarespeed.com)赞助服务器采集节点
|
感谢[吉实信息(构建全新的微波+光交易网络)](https://www.flarespeed.com) 赞助服务器采集节点
|
||||||
|
感谢[天上云计算(全新智慧上云)](https://www.tsyvps.com/aff/BZBEGYLX) 赞助服务器采集节点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ TDengine是一款国产的开源物联网时序型数据库,我们使用其替
|
|||||||
```
|
```
|
||||||
2. Docker安装TDengine
|
2. Docker安装TDengine
|
||||||
```
|
```
|
||||||
$ docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp -v /opt/taosdata:/var/lib/taos --name tdengine tdengine/tdengine:2.4.0.12
|
$ docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp -v /opt/taosdata:/var/lib/taos --name tdengine -e TZ=Asia/Shanghai tdengine/tdengine:2.4.0.12
|
||||||
526aa188da767ae94b244226a2b2eec2b5f17dd8eff594533d9ec0cd0f3a1ccd
|
526aa188da767ae94b244226a2b2eec2b5f17dd8eff594533d9ec0cd0f3a1ccd
|
||||||
```
|
```
|
||||||
`-v /opt/taosdata:/var/lib/taos` 为tdengine数据目录本地持久化挂载,需将`/opt/taosdata`替换为实际本地存在的目录
|
`-v /opt/taosdata:/var/lib/taos` 为tdengine数据目录本地持久化挂载,需将`/opt/taosdata`替换为实际本地存在的目录
|
||||||
|
`-e TZ="Asia/Shanghai"` 为tdengine设置时区,这里可选设置对应的时区
|
||||||
使用```$ docker ps```查看数据库是否启动成功
|
使用```$ docker ps```查看数据库是否启动成功
|
||||||
|
|
||||||
### 创建数据库实例
|
### 创建数据库实例
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ const repoUrl = `https://github.com/dromara/${projectName}`
|
|||||||
const cdnUrl = 'https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/'
|
const cdnUrl = 'https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
title: 'TANCLOUD探云',
|
title: 'HertzBeat',
|
||||||
tagline: '易用友好的高性能监控云',
|
tagline: '易用友好的云监控系统',
|
||||||
url: 'https://hertzbeat.com',
|
url: 'https://hertzbeat.com',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
onBrokenLinks: 'throw',
|
onBrokenLinks: 'throw',
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ function Home() {
|
|||||||
<h1 className="hero__title">
|
<h1 className="hero__title">
|
||||||
<img style={{width: '500px', marginTop: '100px'}} src={cdnTransfer('img/hertzbeat-brand.svg')} alt={'#'}/>
|
<img style={{width: '500px', marginTop: '100px'}} src={cdnTransfer('img/hertzbeat-brand.svg')} alt={'#'}/>
|
||||||
</h1>
|
</h1>
|
||||||
<p className="hero__subtitle"><Translate>易用友好的监控告警系统</Translate></p>
|
<p className="hero__subtitle"><Translate>易用友好的云监控系统</Translate></p>
|
||||||
<div className={styles.social}>
|
<div className={styles.social}>
|
||||||
<a href="https://console.tancloud.cn"><img src={cdnTransfer('img/badge/web-monitor.svg')} alt={''}/></a>
|
<a href="https://console.tancloud.cn"><img src={cdnTransfer('img/badge/web-monitor.svg')} alt={''}/></a>
|
||||||
<a href="https://console.tancloud.cn"><img src={cdnTransfer('img/badge/ping-connect.svg')} alt={''}/></a>
|
<a href="https://console.tancloud.cn"><img src={cdnTransfer('img/badge/ping-connect.svg')} alt={''}/></a>
|
||||||
|
|||||||
4
home/static/img/hertzbeat-brand-white.svg
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
4
home/static/img/tancloud-brand-white.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="199" height="53" viewBox="0 0 199 53" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M60.0112 15.3828V36H57.3208V15.3828H60.0112ZM66.6382 15.3828V17.6201H50.708V15.3828H66.6382ZM76.1963 17.2095L69.3711 36H66.5815L74.4404 15.3828H76.2388L76.1963 17.2095ZM81.917 36L75.0776 17.2095L75.0352 15.3828H76.8335L84.7207 36H81.917ZM81.563 28.3677V30.605H69.98V28.3677H81.563ZM103.341 15.3828V36H100.594L90.2148 20.0981V36H87.4819V15.3828H90.2148L100.637 31.3271V15.3828H103.341ZM120.631 29.4438H123.35C123.208 30.7466 122.835 31.9124 122.231 32.9414C121.627 33.9704 120.772 34.7869 119.668 35.3911C118.563 35.9858 117.185 36.2832 115.533 36.2832C114.325 36.2832 113.225 36.0566 112.234 35.6035C111.252 35.1504 110.407 34.5085 109.699 33.6777C108.991 32.8376 108.444 31.8322 108.057 30.6616C107.679 29.4816 107.49 28.1694 107.49 26.7251V24.6719C107.49 23.2275 107.679 21.9201 108.057 20.7495C108.444 19.5695 108.996 18.5594 109.713 17.7192C110.44 16.8791 111.313 16.2324 112.333 15.7793C113.353 15.3262 114.5 15.0996 115.774 15.0996C117.332 15.0996 118.648 15.3923 119.725 15.9775C120.801 16.5628 121.636 17.3747 122.231 18.4131C122.835 19.4421 123.208 20.6362 123.35 21.9956H120.631C120.499 21.0327 120.253 20.2067 119.895 19.5176C119.536 18.819 119.026 18.2809 118.365 17.9033C117.704 17.5257 116.841 17.3369 115.774 17.3369C114.858 17.3369 114.051 17.5116 113.353 17.8608C112.663 18.2101 112.083 18.7057 111.611 19.3477C111.148 19.9896 110.799 20.759 110.563 21.6558C110.327 22.5526 110.209 23.5485 110.209 24.6436V26.7251C110.209 27.7352 110.313 28.6839 110.521 29.5713C110.738 30.4587 111.063 31.2375 111.498 31.9077C111.932 32.578 112.484 33.1066 113.154 33.4937C113.825 33.8713 114.618 34.0601 115.533 34.0601C116.694 34.0601 117.619 33.876 118.309 33.5078C118.998 33.1396 119.517 32.611 119.866 31.9219C120.225 31.2327 120.48 30.4067 120.631 29.4438ZM139.577 33.7769V36H129.269V33.7769H139.577ZM129.807 15.3828V36H127.074V15.3828H129.807ZM157.646 25.04V26.3428C157.646 27.891 157.452 29.2786 157.065 30.5059C156.678 31.7331 156.121 32.7762 155.394 33.6353C154.667 34.4943 153.794 35.1504 152.774 35.6035C151.764 36.0566 150.632 36.2832 149.376 36.2832C148.158 36.2832 147.04 36.0566 146.02 35.6035C145.01 35.1504 144.132 34.4943 143.386 33.6353C142.65 32.7762 142.079 31.7331 141.673 30.5059C141.267 29.2786 141.064 27.891 141.064 26.3428V25.04C141.064 23.4919 141.262 22.1089 141.659 20.8911C142.065 19.6639 142.636 18.6208 143.372 17.7617C144.108 16.8932 144.982 16.2324 145.992 15.7793C147.011 15.3262 148.13 15.0996 149.348 15.0996C150.603 15.0996 151.736 15.3262 152.746 15.7793C153.766 16.2324 154.639 16.8932 155.366 17.7617C156.102 18.6208 156.664 19.6639 157.051 20.8911C157.447 22.1089 157.646 23.4919 157.646 25.04ZM154.941 26.3428V25.0117C154.941 23.7845 154.813 22.6989 154.559 21.7549C154.313 20.8109 153.95 20.0179 153.468 19.376C152.987 18.734 152.397 18.2479 151.698 17.9175C151.009 17.5871 150.226 17.4219 149.348 17.4219C148.498 17.4219 147.729 17.5871 147.04 17.9175C146.36 18.2479 145.775 18.734 145.284 19.376C144.802 20.0179 144.429 20.8109 144.165 21.7549C143.901 22.6989 143.769 23.7845 143.769 25.0117V26.3428C143.769 27.5794 143.901 28.6745 144.165 29.6279C144.429 30.5719 144.807 31.3696 145.298 32.021C145.798 32.6629 146.388 33.1491 147.068 33.4795C147.757 33.8099 148.526 33.9751 149.376 33.9751C150.263 33.9751 151.052 33.8099 151.741 33.4795C152.43 33.1491 153.01 32.6629 153.482 32.021C153.964 31.3696 154.327 30.5719 154.573 29.6279C154.818 28.6745 154.941 27.5794 154.941 26.3428ZM173.533 15.3828H176.252V29.3306C176.252 30.8787 175.907 32.1673 175.218 33.1963C174.529 34.2253 173.613 34.9993 172.471 35.5186C171.338 36.0283 170.106 36.2832 168.775 36.2832C167.378 36.2832 166.113 36.0283 164.98 35.5186C163.857 34.9993 162.965 34.2253 162.304 33.1963C161.653 32.1673 161.327 30.8787 161.327 29.3306V15.3828H164.032V29.3306C164.032 30.4067 164.23 31.2941 164.626 31.9927C165.023 32.6912 165.575 33.2104 166.283 33.5503C167.001 33.8901 167.831 34.0601 168.775 34.0601C169.729 34.0601 170.56 33.8901 171.268 33.5503C171.985 33.2104 172.542 32.6912 172.938 31.9927C173.335 31.2941 173.533 30.4067 173.533 29.3306V15.3828ZM186.122 36H181.817L181.845 33.7769H186.122C187.594 33.7769 188.821 33.4701 189.803 32.8564C190.785 32.2334 191.521 31.3649 192.012 30.251C192.513 29.1276 192.763 27.8154 192.763 26.3145V25.0542C192.763 23.8742 192.621 22.8263 192.338 21.9106C192.055 20.9855 191.639 20.2067 191.092 19.5742C190.544 18.9323 189.874 18.4461 189.081 18.1157C188.298 17.7853 187.396 17.6201 186.376 17.6201H181.732V15.3828H186.376C187.726 15.3828 188.958 15.6094 190.072 16.0625C191.186 16.5062 192.144 17.1528 192.947 18.0024C193.759 18.8426 194.382 19.8621 194.816 21.061C195.25 22.2505 195.467 23.591 195.467 25.0825V26.3145C195.467 27.806 195.25 29.1512 194.816 30.3501C194.382 31.5396 193.754 32.5544 192.933 33.3945C192.121 34.2347 191.139 34.8813 189.987 35.3345C188.845 35.7782 187.556 36 186.122 36ZM183.275 15.3828V36H180.542V15.3828H183.275Z" fill="white"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.001 0C10.748 0 0 10.745 0 24.001C0 33.826 5.90999 42.271 14.369 45.982C14.301 44.308 14.357 42.293 14.784 40.47C15.246 38.522 17.106 27.5 17.106 27.5C17.106 27.5 17.106 25.861 17.106 23.595C17.106 20.039 19.434 21.819 22 21.819L25.5 23C32 23 42.5 23 42.5 23C42.5 23 32.943 15.5 26.5 15.5C19.221 15.5 18.5 15.5 18.5 15.5C18.5 17.594 13.5 18 13.5 18L11.5 15.5L9 14.5C9 7.684 13.52 8.069 24.922 8.069C34.086 8.069 48 14.5 42.5 23C42.5 23 33.219 23 25.5 23C22.912 23 28.336 31.09 27.5 29.5C27.5 29.5 28 33 22 37C21.492 38.85 18.111 45.575 17.2 47.015C19.359 47.653 21.64 48 24.001 48C37.255 48 48 37.255 48 24.001C48 10.745 37.255 0 24.001 0Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.6 KiB |
@@ -30,7 +30,9 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Alarm information storage and distribution
|
||||||
* 告警信息入库分发
|
* 告警信息入库分发
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2021/12/10 12:58
|
* @date 2021/12/10 12:58
|
||||||
*/
|
*/
|
||||||
@@ -70,7 +72,7 @@ public class DispatchAlarm {
|
|||||||
try {
|
try {
|
||||||
Alert alert = dataQueue.pollAlertData();
|
Alert alert = dataQueue.pollAlertData();
|
||||||
if (alert != null) {
|
if (alert != null) {
|
||||||
// 判断告警类型入库
|
// Determining alarm type storage 判断告警类型入库
|
||||||
storeAlertData(alert);
|
storeAlertData(alert);
|
||||||
// 通知分发
|
// 通知分发
|
||||||
sendAlertDataListener(alert);
|
sendAlertDataListener(alert);
|
||||||
@@ -86,7 +88,7 @@ public class DispatchAlarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void storeAlertData(Alert alert) {
|
private void storeAlertData(Alert alert) {
|
||||||
// todo 使用缓存不直接操作库
|
// todo Using the cache does not directly manipulate the library 使用缓存不直接操作库
|
||||||
Monitor monitor = monitorService.getMonitor(alert.getMonitorId());
|
Monitor monitor = monitorService.getMonitor(alert.getMonitorId());
|
||||||
if (monitor == null) {
|
if (monitor == null) {
|
||||||
log.warn("Dispatch alarm the monitorId: {} not existed, ignored.", alert.getMonitorId());
|
log.warn("Dispatch alarm the monitorId: {} not existed, ignored.", alert.getMonitorId());
|
||||||
@@ -94,50 +96,70 @@ public class DispatchAlarm {
|
|||||||
}
|
}
|
||||||
alert.setMonitorName(monitor.getName());
|
alert.setMonitorName(monitor.getName());
|
||||||
if (monitor.getStatus() == CommonConstants.UN_MANAGE_CODE) {
|
if (monitor.getStatus() == CommonConstants.UN_MANAGE_CODE) {
|
||||||
|
// When monitoring is not managed, ignore and silence its alarm messages
|
||||||
// 当监控未管理时 忽略静默其告警信息
|
// 当监控未管理时 忽略静默其告警信息
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (monitor.getStatus() == CommonConstants.AVAILABLE_CODE) {
|
if (monitor.getStatus() == CommonConstants.AVAILABLE_CODE) {
|
||||||
if (CommonConstants.AVAILABLE.equals(alert.getTarget())) {
|
if (CommonConstants.AVAILABLE.equals(alert.getTarget())) {
|
||||||
|
// Availability Alarm Need to change the monitoring status to unavailable
|
||||||
// 可用性告警 需变更监控状态为不可用
|
// 可用性告警 需变更监控状态为不可用
|
||||||
monitorService.updateMonitorStatus(monitor.getId(), CommonConstants.UN_AVAILABLE_CODE);
|
monitorService.updateMonitorStatus(monitor.getId(), CommonConstants.UN_AVAILABLE_CODE);
|
||||||
} else if (CommonConstants.REACHABLE.equals(alert.getTarget())) {
|
} else if (CommonConstants.REACHABLE.equals(alert.getTarget())) {
|
||||||
|
// Reachability alarm The monitoring status needs to be changed to unreachable
|
||||||
// 可达性告警 需变更监控状态为不可达
|
// 可达性告警 需变更监控状态为不可达
|
||||||
monitorService.updateMonitorStatus(monitor.getId(), CommonConstants.UN_REACHABLE_CODE);
|
monitorService.updateMonitorStatus(monitor.getId(), CommonConstants.UN_REACHABLE_CODE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// If the alarm is restored, the monitoring state needs to be restored
|
||||||
// 若是恢复告警 需对监控状态进行恢复
|
// 若是恢复告警 需对监控状态进行恢复
|
||||||
if (alert.getStatus() == CommonConstants.ALERT_STATUS_CODE_RESTORED) {
|
if (alert.getStatus() == CommonConstants.ALERT_STATUS_CODE_RESTORED) {
|
||||||
monitorService.updateMonitorStatus(alert.getMonitorId(), CommonConstants.AVAILABLE_CODE);
|
monitorService.updateMonitorStatus(alert.getMonitorId(), CommonConstants.AVAILABLE_CODE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 告警落库
|
// Alarm drop library 告警落库
|
||||||
alertService.addAlert(alert);
|
alertService.addAlert(alert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendAlertDataListener(Alert alert) {
|
private void sendAlertDataListener(Alert alert) {
|
||||||
// todo 转发配置的邮件 微信 webhook
|
// todo Forward configured email WeChat webhook 转发配置的邮件 微信 webhook
|
||||||
List<NoticeReceiver> receivers = matchReceiverByNoticeRules(alert);
|
List<NoticeReceiver> receivers = matchReceiverByNoticeRules(alert);
|
||||||
// todo 发送通知这里暂时单线程
|
// todo Send notification here temporarily single thread 发送通知这里暂时单线程
|
||||||
for (NoticeReceiver receiver : receivers) {
|
for (NoticeReceiver receiver : receivers) {
|
||||||
switch (receiver.getType()) {
|
switch (receiver.getType()) {
|
||||||
// todo 短信通知
|
// todo SMS notification 短信通知
|
||||||
case 0: break;
|
case 0:
|
||||||
case 1: sendEmailAlert(receiver, alert); break;
|
break;
|
||||||
case 2: sendWebHookAlert(receiver, alert); break;
|
case 1:
|
||||||
case 3: sendWeChatAlert(receiver, alert); break;
|
sendEmailAlert(receiver, alert);
|
||||||
case 4: sendWeWorkRobotAlert(receiver, alert); break;
|
break;
|
||||||
case 5: sendDingTalkRobotAlert(receiver, alert); break;
|
case 2:
|
||||||
case 6: sendFlyBookAlert(receiver,alert); break;
|
sendWebHookAlert(receiver, alert);
|
||||||
default: break;
|
break;
|
||||||
|
case 3:
|
||||||
|
sendWeChatAlert(receiver, alert);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
sendWeWorkRobotAlert(receiver, alert);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
sendDingTalkRobotAlert(receiver, alert);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
sendFlyBookAlert(receiver, alert);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Send alert information through FeiShu
|
||||||
* 通过飞书发送告警信息
|
* 通过飞书发送告警信息
|
||||||
* @param receiver 接收人
|
*
|
||||||
* @param alert 告警信息
|
* @param receiver Notification configuration information 通知配置信息
|
||||||
|
* @param alert Alarm information 告警信息
|
||||||
*/
|
*/
|
||||||
private void sendFlyBookAlert(NoticeReceiver receiver, Alert alert) {
|
private void sendFlyBookAlert(NoticeReceiver receiver, Alert alert) {
|
||||||
FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto();
|
FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto();
|
||||||
@@ -183,9 +205,11 @@ public class DispatchAlarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Send alarm information through DingTalk robot
|
||||||
* 通过钉钉机器人发送告警信息
|
* 通过钉钉机器人发送告警信息
|
||||||
* @param receiver 通知配置信息
|
*
|
||||||
* @param alert 告警信息
|
* @param receiver Notification configuration information 通知配置信息
|
||||||
|
* @param alert Alarm information 告警信息
|
||||||
*/
|
*/
|
||||||
private void sendDingTalkRobotAlert(NoticeReceiver receiver, Alert alert) {
|
private void sendDingTalkRobotAlert(NoticeReceiver receiver, Alert alert) {
|
||||||
DingTalkWebHookDto dingTalkWebHookDto = new DingTalkWebHookDto();
|
DingTalkWebHookDto dingTalkWebHookDto = new DingTalkWebHookDto();
|
||||||
@@ -216,9 +240,11 @@ public class DispatchAlarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Send alarm information through enterprise WeChat
|
||||||
* 通过企业微信发送告警信息
|
* 通过企业微信发送告警信息
|
||||||
* @param receiver 通知配置信息
|
*
|
||||||
* @param alert 告警信息
|
* @param receiver Notification configuration information 通知配置信息
|
||||||
|
* @param alert Alarm information 告警信息
|
||||||
*/
|
*/
|
||||||
private void sendWeWorkRobotAlert(NoticeReceiver receiver, Alert alert) {
|
private void sendWeWorkRobotAlert(NoticeReceiver receiver, Alert alert) {
|
||||||
WeWorkWebHookDto weWorkWebHookDTO = new WeWorkWebHookDto();
|
WeWorkWebHookDto weWorkWebHookDTO = new WeWorkWebHookDto();
|
||||||
@@ -231,7 +257,7 @@ public class DispatchAlarm {
|
|||||||
if (alert.getPriority() < CommonConstants.ALERT_PRIORITY_CODE_WARNING) {
|
if (alert.getPriority() < CommonConstants.ALERT_PRIORITY_CODE_WARNING) {
|
||||||
content.append("告警级别 : <font color=\"warning\">")
|
content.append("告警级别 : <font color=\"warning\">")
|
||||||
.append(CommonUtil.transferAlertPriority(alert.getPriority())).append("</font>\n");
|
.append(CommonUtil.transferAlertPriority(alert.getPriority())).append("</font>\n");
|
||||||
}else {
|
} else {
|
||||||
content.append("告警级别 : <font color=\"comment\">")
|
content.append("告警级别 : <font color=\"comment\">")
|
||||||
.append(CommonUtil.transferAlertPriority(alert.getPriority())).append("</font>\n");
|
.append(CommonUtil.transferAlertPriority(alert.getPriority())).append("</font>\n");
|
||||||
}
|
}
|
||||||
@@ -273,28 +299,28 @@ public class DispatchAlarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void sendEmailAlert(final NoticeReceiver receiver,final Alert alert){
|
private void sendEmailAlert(final NoticeReceiver receiver, final Alert alert) {
|
||||||
try{
|
try {
|
||||||
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||||
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage,true,"UTF-8");
|
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||||
messageHelper.setSubject("TanCloud探云-监控告警");
|
messageHelper.setSubject("TanCloud探云-监控告警");
|
||||||
//设置发件人Email
|
//Set sender Email 设置发件人Email
|
||||||
messageHelper.setFrom(emailFromUser);
|
messageHelper.setFrom(emailFromUser);
|
||||||
//设定收件人Email
|
//Set recipient Email 设定收件人Email
|
||||||
messageHelper.setTo(receiver.getEmail());
|
messageHelper.setTo(receiver.getEmail());
|
||||||
messageHelper.setSentDate(new Date());
|
messageHelper.setSentDate(new Date());
|
||||||
//构建邮件模版
|
//Build email templates 构建邮件模版
|
||||||
String process = mailService.buildAlertHtmlTemplate(alert);
|
String process = mailService.buildAlertHtmlTemplate(alert);
|
||||||
//设置邮件内容模版
|
//Set Email Content Template 设置邮件内容模版
|
||||||
messageHelper.setText(process,true);
|
messageHelper.setText(process, true);
|
||||||
javaMailSender.send(mimeMessage);
|
javaMailSender.send(mimeMessage);
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("[邮箱告警] error,Exception information={}",e.getMessage());
|
log.error("[Email Alert] Exception,Exception information={}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<NoticeReceiver> matchReceiverByNoticeRules(Alert alert) {
|
private List<NoticeReceiver> matchReceiverByNoticeRules(Alert alert) {
|
||||||
// todo 使用缓存
|
// todo use cache 使用缓存
|
||||||
return noticeConfigService.getReceiverFilterRule(alert);
|
return noticeConfigService.getReceiverFilterRule(alert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,11 +28,13 @@ import java.util.List;
|
|||||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Message Notification Configuration API
|
||||||
* 消息通知配置API
|
* 消息通知配置API
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2021/12/16 16:18
|
* @date 2021/12/16 16:18
|
||||||
*/
|
*/
|
||||||
@Api(tags = "消息通知配置API")
|
@Api(tags = "en: Message Notification Configuration API,zh: 消息通知配置API")
|
||||||
@RestController()
|
@RestController()
|
||||||
@RequestMapping(value = "/notice", produces = {APPLICATION_JSON_VALUE})
|
@RequestMapping(value = "/notice", produces = {APPLICATION_JSON_VALUE})
|
||||||
public class NoticeConfigController {
|
public class NoticeConfigController {
|
||||||
@@ -41,33 +43,36 @@ public class NoticeConfigController {
|
|||||||
private NoticeConfigService noticeConfigService;
|
private NoticeConfigService noticeConfigService;
|
||||||
|
|
||||||
@PostMapping(path = "/receiver")
|
@PostMapping(path = "/receiver")
|
||||||
@ApiOperation(value = "新增接收人", notes = "新增一个接收人")
|
@ApiOperation(value = "Add a recipient", notes = "新增一个接收人")
|
||||||
public ResponseEntity<Message<Void>> addNewNoticeReceiver(@Valid @RequestBody NoticeReceiver noticeReceiver) {
|
public ResponseEntity<Message<Void>> addNewNoticeReceiver(@Valid @RequestBody NoticeReceiver noticeReceiver) {
|
||||||
noticeConfigService.addReceiver(noticeReceiver);
|
noticeConfigService.addReceiver(noticeReceiver);
|
||||||
return ResponseEntity.ok(new Message<>("Add success"));
|
return ResponseEntity.ok(new Message<>("Add success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping(path = "/receiver")
|
@PutMapping(path = "/receiver")
|
||||||
@ApiOperation(value = "修改接收人", notes = "修改已存在的接收人信息")
|
@ApiOperation(value = "Modify existing recipient information", notes = "修改已存在的接收人信息")
|
||||||
public ResponseEntity<Message<Void>> editNoticeReceiver(@Valid @RequestBody NoticeReceiver noticeReceiver) {
|
public ResponseEntity<Message<Void>> editNoticeReceiver(@Valid @RequestBody NoticeReceiver noticeReceiver) {
|
||||||
noticeConfigService.editReceiver(noticeReceiver);
|
noticeConfigService.editReceiver(noticeReceiver);
|
||||||
return ResponseEntity.ok(new Message<>("Edit success"));
|
return ResponseEntity.ok(new Message<>("Edit success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = "/receiver/{id}")
|
@DeleteMapping(path = "/receiver/{id}")
|
||||||
@ApiOperation(value = "删除指定接收人", notes = "删除已存在的接收人信息")
|
@ApiOperation(value = "Delete existing recipient information", notes = "删除已存在的接收人信息")
|
||||||
public ResponseEntity<Message<Void>> deleteNoticeReceiver(
|
public ResponseEntity<Message<Void>> deleteNoticeReceiver(
|
||||||
@ApiParam(value = "接收人ID", example = "6565463543") @PathVariable("id") final Long receiverId) {
|
@ApiParam(value = "en: Recipient ID,zh: 接收人ID", example = "6565463543") @PathVariable("id") final Long receiverId) {
|
||||||
// 不存在或删除成功都返回成功
|
// Returns success if it does not exist or if the deletion is successful
|
||||||
|
// todo 不存在或删除成功都返回成功
|
||||||
noticeConfigService.deleteReceiver(receiverId);
|
noticeConfigService.deleteReceiver(receiverId);
|
||||||
return ResponseEntity.ok(new Message<>("Delete success"));
|
return ResponseEntity.ok(new Message<>("Delete success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/receivers")
|
@GetMapping(path = "/receivers")
|
||||||
@ApiOperation(value = "查询消息通知接收人", notes = "根据查询过滤项获取消息通知接收人列表")
|
@ApiOperation(value = "Get a list of message notification recipients based on query filter items",
|
||||||
|
notes = "根据查询过滤项获取消息通知接收人列表")
|
||||||
public ResponseEntity<Message<List<NoticeReceiver>>> getReceivers(
|
public ResponseEntity<Message<List<NoticeReceiver>>> getReceivers(
|
||||||
@ApiParam(value = "接收人名称,模糊查询", example = "tom") @RequestParam(required = false) final String name) {
|
@ApiParam(value = "en: Recipient name,zh: 接收人名称,模糊查询", example = "tom") @RequestParam(required = false) final String name) {
|
||||||
|
|
||||||
|
//todo Writing can be optimized 写法可优化
|
||||||
Specification<NoticeReceiver> specification = (root, query, criteriaBuilder) -> {
|
Specification<NoticeReceiver> specification = (root, query, criteriaBuilder) -> {
|
||||||
Predicate predicate = criteriaBuilder.conjunction();
|
Predicate predicate = criteriaBuilder.conjunction();
|
||||||
if (name != null && !"".equals(name)) {
|
if (name != null && !"".equals(name)) {
|
||||||
@@ -83,32 +88,34 @@ public class NoticeConfigController {
|
|||||||
|
|
||||||
|
|
||||||
@PostMapping(path = "/rule")
|
@PostMapping(path = "/rule")
|
||||||
@ApiOperation(value = "新增通知策略", notes = "新增一个通知策略")
|
@ApiOperation(value = "Add a notification policy", notes = "新增一个通知策略")
|
||||||
public ResponseEntity<Message<Void>> addNewNoticeRule(@Valid @RequestBody NoticeRule noticeRule) {
|
public ResponseEntity<Message<Void>> addNewNoticeRule(@Valid @RequestBody NoticeRule noticeRule) {
|
||||||
noticeConfigService.addNoticeRule(noticeRule);
|
noticeConfigService.addNoticeRule(noticeRule);
|
||||||
return ResponseEntity.ok(new Message<>("Add success"));
|
return ResponseEntity.ok(new Message<>("Add success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping(path = "/rule")
|
@PutMapping(path = "/rule")
|
||||||
@ApiOperation(value = "修改通知策略", notes = "修改已存在的通知策略信息")
|
@ApiOperation(value = "Modify existing notification policy information", notes = "修改已存在的通知策略信息")
|
||||||
public ResponseEntity<Message<Void>> editNoticeRule(@Valid @RequestBody NoticeRule noticeRule) {
|
public ResponseEntity<Message<Void>> editNoticeRule(@Valid @RequestBody NoticeRule noticeRule) {
|
||||||
noticeConfigService.editNoticeRule(noticeRule);
|
noticeConfigService.editNoticeRule(noticeRule);
|
||||||
return ResponseEntity.ok(new Message<>("Edit success"));
|
return ResponseEntity.ok(new Message<>("Edit success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = "/rule/{id}")
|
@DeleteMapping(path = "/rule/{id}")
|
||||||
@ApiOperation(value = "删除指定通知策略", notes = "删除已存在的通知策略信息")
|
@ApiOperation(value = "Delete existing notification policy information", notes = "删除已存在的通知策略信息")
|
||||||
public ResponseEntity<Message<Void>> deleteNoticeRule(
|
public ResponseEntity<Message<Void>> deleteNoticeRule(
|
||||||
@ApiParam(value = "通知策略ID", example = "6565463543") @PathVariable("id") final Long ruleId) {
|
@ApiParam(value = "en: Notification Policy ID,zh: 通知策略ID", example = "6565463543") @PathVariable("id") final Long ruleId) {
|
||||||
// 不存在或删除成功都返回成功
|
// Returns success if it does not exist or if the deletion is successful
|
||||||
|
// todo 不存在或删除成功都返回成功
|
||||||
noticeConfigService.deleteNoticeRule(ruleId);
|
noticeConfigService.deleteNoticeRule(ruleId);
|
||||||
return ResponseEntity.ok(new Message<>("Delete success"));
|
return ResponseEntity.ok(new Message<>("Delete success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/rules")
|
@GetMapping(path = "/rules")
|
||||||
@ApiOperation(value = "查询消息通知策略", notes = "根据查询过滤项获取消息通知策略列表")
|
@ApiOperation(value = "Get a list of message notification policies based on query filter items",
|
||||||
|
notes = "根据查询过滤项获取消息通知策略列表")
|
||||||
public ResponseEntity<Message<List<NoticeRule>>> getRules(
|
public ResponseEntity<Message<List<NoticeRule>>> getRules(
|
||||||
@ApiParam(value = "接收人名称,模糊查询", example = "rule1") @RequestParam(required = false) final String name) {
|
@ApiParam(value = "en: Recipient name,zh: 接收人名称,模糊查询", example = "rule1") @RequestParam(required = false) final String name) {
|
||||||
|
|
||||||
Specification<NoticeRule> specification = (root, query, criteriaBuilder) -> {
|
Specification<NoticeRule> specification = (root, query, criteriaBuilder) -> {
|
||||||
Predicate predicate = criteriaBuilder.conjunction();
|
Predicate predicate = criteriaBuilder.conjunction();
|
||||||
|
|||||||
@@ -18,11 +18,13 @@ import java.util.List;
|
|||||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* System Summary Statistics API
|
||||||
* 系统摘要统计API
|
* 系统摘要统计API
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2021/12/7 15:57
|
* @date 2021/12/7 15:57
|
||||||
*/
|
*/
|
||||||
@Api(tags = "系统摘要统计API")
|
@Api(tags = "en: System Summary Statistics API,zh: 系统摘要统计API")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(path = "/summary", produces = {APPLICATION_JSON_VALUE})
|
@RequestMapping(path = "/summary", produces = {APPLICATION_JSON_VALUE})
|
||||||
public class SummaryController {
|
public class SummaryController {
|
||||||
@@ -31,7 +33,7 @@ public class SummaryController {
|
|||||||
private MonitorService monitorService;
|
private MonitorService monitorService;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@ApiOperation(value = "查询应用类别监控统计", notes = "查询所有应用类别监控统计信息")
|
@ApiOperation(value = "Query all application category monitoring statistics", notes = "查询所有应用类别监控统计信息")
|
||||||
public ResponseEntity<Message<Dashboard>> appMonitors() {
|
public ResponseEntity<Message<Dashboard>> appMonitors() {
|
||||||
List<AppCount> appsCount = monitorService.getAllAppMonitorsCount();
|
List<AppCount> appsCount = monitorService.getAllAppMonitorsCount();
|
||||||
Message<Dashboard> message = new Message<>(new Dashboard(appsCount));
|
Message<Dashboard> message = new Message<>(new Dashboard(appsCount));
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* AuthResources 数据库操作
|
* AuthResources 数据库操作
|
||||||
|
*
|
||||||
* @author tomsun28
|
* @author tomsun28
|
||||||
* @date 2021/11/14 11:24
|
* @date 2021/11/14 11:24
|
||||||
*/
|
*/
|
||||||
@@ -22,12 +23,14 @@ public interface MonitorDao extends JpaRepository<Monitor, Long>, JpaSpecificati
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据监控ID列表删除监控
|
* 根据监控ID列表删除监控
|
||||||
|
*
|
||||||
* @param monitorIds 监控ID列表
|
* @param monitorIds 监控ID列表
|
||||||
*/
|
*/
|
||||||
void deleteAllByIdIn(Set<Long> monitorIds);
|
void deleteAllByIdIn(Set<Long> monitorIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据监控ID列表查询监控
|
* 根据监控ID列表查询监控
|
||||||
|
*
|
||||||
* @param monitorIds 监控ID列表
|
* @param monitorIds 监控ID列表
|
||||||
* @return 监控列表
|
* @return 监控列表
|
||||||
*/
|
*/
|
||||||
@@ -35,6 +38,7 @@ public interface MonitorDao extends JpaRepository<Monitor, Long>, JpaSpecificati
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据监控类型查询监控
|
* 根据监控类型查询监控
|
||||||
|
*
|
||||||
* @param app 监控类型
|
* @param app 监控类型
|
||||||
* @return 监控列表
|
* @return 监控列表
|
||||||
*/
|
*/
|
||||||
@@ -42,29 +46,35 @@ public interface MonitorDao extends JpaRepository<Monitor, Long>, JpaSpecificati
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询已下发采集任务的监控
|
* 查询已下发采集任务的监控
|
||||||
|
*
|
||||||
* @param status 监控状态
|
* @param status 监控状态
|
||||||
* @return 监控列表
|
* @return 监控列表
|
||||||
*/
|
*/
|
||||||
List<Monitor> findMonitorsByStatusNotInAndAndJobIdNotNull(List<Byte> status);
|
List<Monitor> findMonitorsByStatusNotInAndAndJobIdNotNull(List<Byte> status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据监控名称查询监控
|
* Query monitoring by monitoring name 根据监控名称查询监控
|
||||||
* @param name 监控名称
|
*
|
||||||
* @return 监控列表
|
* @param name monitoring name 监控名称
|
||||||
|
* @return monitoring list 监控列表
|
||||||
*/
|
*/
|
||||||
Optional<Monitor> findMonitorByNameEquals(String name);
|
Optional<Monitor> findMonitorByNameEquals(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Query the monitoring category - the number of monitoring corresponding to the status
|
||||||
* 查询监控类别-状态对应的监控数量
|
* 查询监控类别-状态对应的监控数量
|
||||||
* @return 监控类别-状态与监控数量映射
|
*
|
||||||
|
* @return Monitoring Category-Status and Monitoring Quantity Mapping 监控类别-状态与监控数量映射
|
||||||
*/
|
*/
|
||||||
@Query("select new com.usthe.manager.pojo.dto.AppCount(mo.app, mo.status, COUNT(mo.id)) from Monitor mo group by mo.app, mo.status")
|
@Query("select new com.usthe.manager.pojo.dto.AppCount(mo.app, mo.status, COUNT(mo.id)) from Monitor mo group by mo.app, mo.status")
|
||||||
List<AppCount> findAppsStatusCount();
|
List<AppCount> findAppsStatusCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Update the status of the specified monitor
|
||||||
* 更新指定监控的状态
|
* 更新指定监控的状态
|
||||||
* @param id 监控ID
|
*
|
||||||
* @param status 监控状态
|
* @param id Monitor ID 监控ID
|
||||||
|
* @param status 监控状态 Monitor Status
|
||||||
*/
|
*/
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update Monitor set status = :status where id = :id")
|
@Query("update Monitor set status = :status where id = :id")
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 企业微信机器人请求消息体
|
* 企业微信机器人请求消息体
|
||||||
|
*
|
||||||
* @author 花城
|
* @author 花城
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @date 2022/2/21 6:55 下午
|
* @date 2022/2/21 6:55 下午
|
||||||
@@ -18,7 +19,14 @@ import lombok.NoArgsConstructor;
|
|||||||
public class WeWorkWebHookDto {
|
public class WeWorkWebHookDto {
|
||||||
|
|
||||||
public static final String WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=";
|
public static final String WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=";
|
||||||
|
/**
|
||||||
|
* markdown格式
|
||||||
|
*/
|
||||||
private static final String MARKDOWN = "markdown";
|
private static final String MARKDOWN = "markdown";
|
||||||
|
/**
|
||||||
|
* 文本格式
|
||||||
|
*/
|
||||||
|
private static final String TEXT = "TEXT";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息类型
|
* 消息类型
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.springframework.core.annotation.Order;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 邮箱发送服务
|
* Email delivery service 邮箱发送服务
|
||||||
*
|
*
|
||||||
* @author 花城
|
* @author 花城
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
@@ -15,9 +15,11 @@ import org.springframework.stereotype.Service;
|
|||||||
public interface MailService {
|
public interface MailService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Build an alert email template
|
||||||
* 构建告警邮件模版
|
* 构建告警邮件模版
|
||||||
* @param alert 告警信息
|
*
|
||||||
* @return 邮件内容
|
* @param alert Alarm data element information 告警数据元信息
|
||||||
|
* @return content of email 邮件内容
|
||||||
*/
|
*/
|
||||||
String buildAlertHtmlTemplate(Alert alert);
|
String buildAlertHtmlTemplate(Alert alert);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 监控管理服务
|
* 监控管理服务
|
||||||
|
*
|
||||||
* @author tomsun28
|
* @author tomsun28
|
||||||
* @date 2021/11/14 11:28
|
* @date 2021/11/14 11:28
|
||||||
*/
|
*/
|
||||||
@@ -23,6 +24,7 @@ public interface MonitorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 监控可用性探测
|
* 监控可用性探测
|
||||||
|
*
|
||||||
* @param monitor 监控实体信息
|
* @param monitor 监控实体信息
|
||||||
* @param params 参数信息
|
* @param params 参数信息
|
||||||
* @throws MonitorDetectException 探测失败抛出
|
* @throws MonitorDetectException 探测失败抛出
|
||||||
@@ -31,6 +33,7 @@ public interface MonitorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增监控
|
* 新增监控
|
||||||
|
*
|
||||||
* @param monitor 监控实体
|
* @param monitor 监控实体
|
||||||
* @param params 参数信息
|
* @param params 参数信息
|
||||||
* @throws RuntimeException 新增过程异常抛出
|
* @throws RuntimeException 新增过程异常抛出
|
||||||
@@ -39,6 +42,7 @@ public interface MonitorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验请求数据参数正确性
|
* 校验请求数据参数正确性
|
||||||
|
*
|
||||||
* @param monitorDto monitorDto
|
* @param monitorDto monitorDto
|
||||||
* @param isModify 是否是修改监控
|
* @param isModify 是否是修改监控
|
||||||
* @throws IllegalArgumentException 校验参数错误抛出
|
* @throws IllegalArgumentException 校验参数错误抛出
|
||||||
@@ -47,6 +51,7 @@ public interface MonitorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改更新监控
|
* 修改更新监控
|
||||||
|
*
|
||||||
* @param monitor 监控实体
|
* @param monitor 监控实体
|
||||||
* @param params 参数信息
|
* @param params 参数信息
|
||||||
* @throws RuntimeException 修改过程中异常抛出
|
* @throws RuntimeException 修改过程中异常抛出
|
||||||
@@ -55,6 +60,7 @@ public interface MonitorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除监控
|
* 删除监控
|
||||||
|
*
|
||||||
* @param id 监控ID
|
* @param id 监控ID
|
||||||
* @throws RuntimeException 删除过程中异常抛出
|
* @throws RuntimeException 删除过程中异常抛出
|
||||||
*/
|
*/
|
||||||
@@ -62,6 +68,7 @@ public interface MonitorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量删除监控
|
* 批量删除监控
|
||||||
|
*
|
||||||
* @param ids 监控ID
|
* @param ids 监控ID
|
||||||
* @throws RuntimeException 删除过程中异常抛出
|
* @throws RuntimeException 删除过程中异常抛出
|
||||||
*/
|
*/
|
||||||
@@ -69,6 +76,7 @@ public interface MonitorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取监控信息
|
* 获取监控信息
|
||||||
|
*
|
||||||
* @param id 监控ID
|
* @param id 监控ID
|
||||||
* @return MonitorDto
|
* @return MonitorDto
|
||||||
* @throws RuntimeException 查询过程中异常抛出
|
* @throws RuntimeException 查询过程中异常抛出
|
||||||
@@ -77,6 +85,7 @@ public interface MonitorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态条件查询
|
* 动态条件查询
|
||||||
|
*
|
||||||
* @param specification 查询条件
|
* @param specification 查询条件
|
||||||
* @param pageRequest 分页参数
|
* @param pageRequest 分页参数
|
||||||
* @return 查询结果
|
* @return 查询结果
|
||||||
@@ -85,38 +94,46 @@ public interface MonitorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据监控ID列表批量取消纳管监控项
|
* 根据监控ID列表批量取消纳管监控项
|
||||||
|
*
|
||||||
* @param ids 监控IDs
|
* @param ids 监控IDs
|
||||||
*/
|
*/
|
||||||
void cancelManageMonitors(HashSet<Long> ids);
|
void cancelManageMonitors(HashSet<Long> ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据监控ID列表批量启动纳管监控项
|
* 根据监控ID列表批量启动纳管监控项
|
||||||
|
*
|
||||||
* @param ids 监控IDs
|
* @param ids 监控IDs
|
||||||
*/
|
*/
|
||||||
void enableManageMonitors(HashSet<Long> ids);
|
void enableManageMonitors(HashSet<Long> ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询监控类别及其对应的监控数量
|
* 查询监控类别及其对应的监控数量
|
||||||
|
*
|
||||||
* @return 监控类别与监控数量映射
|
* @return 监控类别与监控数量映射
|
||||||
*/
|
*/
|
||||||
List<AppCount> getAllAppMonitorsCount();
|
List<AppCount> getAllAppMonitorsCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Query monitoring
|
||||||
* 查询监控
|
* 查询监控
|
||||||
* @param monitorId 监控ID
|
*
|
||||||
* @return 监控信息
|
* @param monitorId Monitor ID 监控ID
|
||||||
|
* @return Monitor information 监控信息
|
||||||
*/
|
*/
|
||||||
Monitor getMonitor(Long monitorId);
|
Monitor getMonitor(Long monitorId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Update the status of the specified monitor
|
||||||
* 更新指定监控的状态
|
* 更新指定监控的状态
|
||||||
* @param monitorId 监控ID
|
*
|
||||||
* @param status 监控状态
|
* @param monitorId monitorId 监控ID
|
||||||
|
* @param status monitor status 监控状态
|
||||||
*/
|
*/
|
||||||
void updateMonitorStatus(Long monitorId, byte status);
|
void updateMonitorStatus(Long monitorId, byte status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询指定监控类型下的所有监控信息列表
|
* 查询指定监控类型下的所有监控信息列表
|
||||||
|
*
|
||||||
* @param app 监控类型
|
* @param app 监控类型
|
||||||
* @return 监控列表
|
* @return 监控列表
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -8,66 +8,86 @@ import org.springframework.data.jpa.domain.Specification;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Message notification configuration interface
|
||||||
* 消息通知配置接口
|
* 消息通知配置接口
|
||||||
|
*
|
||||||
* @author tom
|
* @author tom
|
||||||
* @date 2021/12/16 16:14
|
* @date 2021/12/16 16:14
|
||||||
*/
|
*/
|
||||||
public interface NoticeConfigService {
|
public interface NoticeConfigService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Dynamic conditional query
|
||||||
* 动态条件查询
|
* 动态条件查询
|
||||||
* @param specification 查询条件
|
*
|
||||||
* @return 查询结果
|
* @param specification Query conditions 查询条件
|
||||||
|
* @return Search result 查询结果
|
||||||
*/
|
*/
|
||||||
List<NoticeReceiver> getNoticeReceivers(Specification<NoticeReceiver> specification);
|
List<NoticeReceiver> getNoticeReceivers(Specification<NoticeReceiver> specification);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Dynamic conditional query
|
||||||
* 动态条件查询
|
* 动态条件查询
|
||||||
* @param specification 查询条件
|
*
|
||||||
* @return 查询结果
|
* @param specification Query conditions 查询条件
|
||||||
|
* @return Search result 查询结果
|
||||||
*/
|
*/
|
||||||
List<NoticeRule> getNoticeRules(Specification<NoticeRule> specification);
|
List<NoticeRule> getNoticeRules(Specification<NoticeRule> specification);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Add a notification recipient
|
||||||
* 新增一个通知接收人
|
* 新增一个通知接收人
|
||||||
* @param noticeReceiver 接收人信息
|
*
|
||||||
|
* @param noticeReceiver recipient information 接收人信息
|
||||||
*/
|
*/
|
||||||
void addReceiver(NoticeReceiver noticeReceiver);
|
void addReceiver(NoticeReceiver noticeReceiver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Modify notification recipients
|
||||||
* 修改通知接收人
|
* 修改通知接收人
|
||||||
* @param noticeReceiver 接收人信息
|
*
|
||||||
|
* @param noticeReceiver recipient information 接收人信息
|
||||||
*/
|
*/
|
||||||
void editReceiver(NoticeReceiver noticeReceiver);
|
void editReceiver(NoticeReceiver noticeReceiver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Delete recipient information based on recipient ID
|
||||||
* 根据接收人ID删除接收人信息
|
* 根据接收人ID删除接收人信息
|
||||||
* @param receiverId 接收人ID
|
*
|
||||||
|
* @param receiverId Recipient ID 接收人ID
|
||||||
*/
|
*/
|
||||||
void deleteReceiver(Long receiverId);
|
void deleteReceiver(Long receiverId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Added notification policy
|
||||||
* 新增通知策略
|
* 新增通知策略
|
||||||
* @param noticeRule 通知策略
|
*
|
||||||
|
* @param noticeRule Notification strategy 通知策略
|
||||||
*/
|
*/
|
||||||
void addNoticeRule(NoticeRule noticeRule);
|
void addNoticeRule(NoticeRule noticeRule);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Modify Notification Policy
|
||||||
* 修改通知策略
|
* 修改通知策略
|
||||||
* @param noticeRule 通知策略
|
*
|
||||||
|
* @param noticeRule Notification strategy 通知策略
|
||||||
*/
|
*/
|
||||||
void editNoticeRule(NoticeRule noticeRule);
|
void editNoticeRule(NoticeRule noticeRule);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Delete the specified notification policy
|
||||||
* 删除指定的通知策略
|
* 删除指定的通知策略
|
||||||
* @param ruleId 通知策略ID
|
*
|
||||||
|
* @param ruleId Notification Policy ID 通知策略ID
|
||||||
*/
|
*/
|
||||||
void deleteNoticeRule(Long ruleId);
|
void deleteNoticeRule(Long ruleId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* According to the alarm information matching all notification policies, filter out the recipients who need to be notified
|
||||||
* 根据告警信息与所有通知策略匹配,过滤出需要通知的接收人
|
* 根据告警信息与所有通知策略匹配,过滤出需要通知的接收人
|
||||||
* @param alert 告警信息
|
*
|
||||||
* @return 接收人
|
* @param alert Alarm information 告警信息
|
||||||
|
* @return Receiver 接收人
|
||||||
*/
|
*/
|
||||||
List<NoticeReceiver> getReceiverFilterRule(Alert alert);
|
List<NoticeReceiver> getReceiverFilterRule(Alert alert);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 监控管理服务实现
|
* 监控管理服务实现
|
||||||
|
*
|
||||||
* @author tomsun28
|
* @author tomsun28
|
||||||
* @date 2021/11/14 13:06
|
* @date 2021/11/14 13:06
|
||||||
*/
|
*/
|
||||||
@@ -79,6 +80,10 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
List<Configmap> configmaps = params.stream().map(param ->
|
List<Configmap> configmaps = params.stream().map(param ->
|
||||||
new Configmap(param.getField(), param.getValue(), param.getType())).collect(Collectors.toList());
|
new Configmap(param.getField(), param.getValue(), param.getType())).collect(Collectors.toList());
|
||||||
appDefine.setConfigmap(configmaps);
|
appDefine.setConfigmap(configmaps);
|
||||||
|
// 探测可用性只需要采集优先级为0的可用性指标集合
|
||||||
|
List<Metrics> availableMetrics = appDefine.getMetrics().stream()
|
||||||
|
.filter(item -> item.getPriority() == 0).collect(Collectors.toList());
|
||||||
|
appDefine.setMetrics(availableMetrics);
|
||||||
List<CollectRep.MetricsData> collectRep = collectJobService.collectSyncJobData(appDefine);
|
List<CollectRep.MetricsData> collectRep = collectJobService.collectSyncJobData(appDefine);
|
||||||
// 判断探测结果 失败则抛出探测异常
|
// 判断探测结果 失败则抛出探测异常
|
||||||
if (collectRep == null || collectRep.isEmpty()) {
|
if (collectRep == null || collectRep.isEmpty()) {
|
||||||
@@ -387,7 +392,8 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
if (appCounts == null) {
|
if (appCounts == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// 关联大类别信息 计算每个状态对应数量
|
//Statistical category information, calculate the number of corresponding states for each monitor
|
||||||
|
//统计类别信息,计算每个监控分别对应状态的数量
|
||||||
Map<String, AppCount> appCountMap = new HashMap<>(appCounts.size());
|
Map<String, AppCount> appCountMap = new HashMap<>(appCounts.size());
|
||||||
for (AppCount item : appCounts) {
|
for (AppCount item : appCounts) {
|
||||||
AppCount appCount = appCountMap.getOrDefault(item.getApp(), new AppCount());
|
AppCount appCount = appCountMap.getOrDefault(item.getApp(), new AppCount());
|
||||||
@@ -405,10 +411,13 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
case CommonConstants.UN_REACHABLE_CODE:
|
case CommonConstants.UN_REACHABLE_CODE:
|
||||||
appCount.setUnReachableSize(appCount.getUnReachableSize() + item.getSize());
|
appCount.setUnReachableSize(appCount.getUnReachableSize() + item.getSize());
|
||||||
break;
|
break;
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
appCountMap.put(item.getApp(), appCount);
|
appCountMap.put(item.getApp(), appCount);
|
||||||
}
|
}
|
||||||
|
//Traverse the map obtained by statistics and convert it into a List<App Count> result set
|
||||||
|
//遍历统计得到的map,转换成List<App Count>结果集
|
||||||
return appCountMap.values().stream().peek(item -> {
|
return appCountMap.values().stream().peek(item -> {
|
||||||
item.setSize(item.getAvailableSize() + item.getUnManageSize()
|
item.setSize(item.getAvailableSize() + item.getUnManageSize()
|
||||||
+ item.getUnReachableSize() + item.getUnAvailableSize());
|
+ item.getUnReachableSize() + item.getUnAvailableSize());
|
||||||
|
|||||||
@@ -26,6 +26,14 @@ configmap:
|
|||||||
type: 1
|
type: 1
|
||||||
- key: payload
|
- key: payload
|
||||||
type: 1
|
type: 1
|
||||||
|
- key: authType
|
||||||
|
type: 1
|
||||||
|
- key: headers
|
||||||
|
type: 3
|
||||||
|
- key: params
|
||||||
|
type: 3
|
||||||
|
- key: keyword
|
||||||
|
type: 1
|
||||||
# 指标组列表
|
# 指标组列表
|
||||||
metrics:
|
metrics:
|
||||||
# 第一个监控指标组 cpu
|
# 第一个监控指标组 cpu
|
||||||
@@ -40,6 +48,9 @@ metrics:
|
|||||||
- field: responseTime
|
- field: responseTime
|
||||||
type: 0
|
type: 0
|
||||||
unit: ms
|
unit: ms
|
||||||
|
- field: keyword
|
||||||
|
type: 0
|
||||||
|
unit: 次数
|
||||||
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||||
protocol: http
|
protocol: http
|
||||||
# 当protocol为http协议时具体的采集配置
|
# 当protocol为http协议时具体的采集配置
|
||||||
@@ -58,12 +69,19 @@ metrics:
|
|||||||
# 请求头内容
|
# 请求头内容
|
||||||
headers:
|
headers:
|
||||||
content-type: ^_^contentType^_^
|
content-type: ^_^contentType^_^
|
||||||
|
^_^headers^_^: ^_^headers^_^
|
||||||
|
# 请求参数内容
|
||||||
|
params:
|
||||||
|
^_^params^_^: ^_^params^_^
|
||||||
# 认证
|
# 认证
|
||||||
authorization:
|
authorization:
|
||||||
# 认证方式: Basic Auth, Digest Auth, Bearer Token
|
# 认证方式: Basic Auth, Digest Auth, Bearer Token
|
||||||
type: Basic Auth
|
type: ^_^authType^_^
|
||||||
basicAuthUsername: ^_^username^_^
|
basicAuthUsername: ^_^username^_^
|
||||||
basicAuthPassword: ^_^password^_^
|
basicAuthPassword: ^_^password^_^
|
||||||
|
digestAuthUsername: ^_^username^_^
|
||||||
|
digestAuthPassword: ^_^password^_^
|
||||||
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-网站可用性指标监控
|
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-网站可用性指标监控
|
||||||
# todo xmlPath-xmlPath脚本,prometheus-Prometheus数据规则
|
# todo xmlPath-xmlPath脚本,prometheus-Prometheus数据规则
|
||||||
parseType: website
|
parseType: website
|
||||||
|
keyword: ^_^keyword^_^
|
||||||
@@ -68,6 +68,26 @@ metrics:
|
|||||||
- field: context_switch
|
- field: context_switch
|
||||||
type: 0
|
type: 0
|
||||||
unit: 个数
|
unit: 个数
|
||||||
|
- field: usage
|
||||||
|
type: 0
|
||||||
|
unit: '%'
|
||||||
|
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
|
||||||
|
aliasFields:
|
||||||
|
- info
|
||||||
|
- cores
|
||||||
|
- interrupt
|
||||||
|
- load
|
||||||
|
- context_switch
|
||||||
|
- idle
|
||||||
|
# (非必须)指标计算表达式,与上面的别名一起作用,计算出最终需要的指标值
|
||||||
|
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
|
||||||
|
calculates:
|
||||||
|
- info=info
|
||||||
|
- cores=cores
|
||||||
|
- interrupt=interrupt
|
||||||
|
- load=load
|
||||||
|
- context_switch=context_switch
|
||||||
|
- usage=100-idle
|
||||||
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||||
protocol: ssh
|
protocol: ssh
|
||||||
# 当protocol为http协议时具体的采集配置
|
# 当protocol为http协议时具体的采集配置
|
||||||
@@ -79,7 +99,7 @@ metrics:
|
|||||||
username: ^_^username^_^
|
username: ^_^username^_^
|
||||||
password: ^_^password^_^
|
password: ^_^password^_^
|
||||||
timeout: ^_^timeout^_^
|
timeout: ^_^timeout^_^
|
||||||
script: "LANG=C lscpu | awk -F: '/Model name/ {print $2}';awk '/processor/{core++} END{print core}' /proc/cpuinfo;uptime | sed 's/,/ /g' | awk '{for(i=NF-2;i<=NF;i++)print $i }' | xargs;vmstat 1 1 | awk 'NR==3{print $11}';vmstat 1 1 | awk 'NR==3{print $12}'"
|
script: "LANG=C lscpu | awk -F: '/Model name/ {print $2}';awk '/processor/{core++} END{print core}' /proc/cpuinfo;uptime | sed 's/,/ /g' | awk '{for(i=NF-2;i<=NF;i++)print $i }' | xargs;vmstat 1 1 | awk 'NR==3{print $11}';vmstat 1 1 | awk 'NR==3{print $12}';vmstat 1 1 | awk 'NR==3{print $15}'"
|
||||||
parseType: oneRow
|
parseType: oneRow
|
||||||
|
|
||||||
- name: memory
|
- name: memory
|
||||||
@@ -101,6 +121,25 @@ metrics:
|
|||||||
- field: available
|
- field: available
|
||||||
type: 0
|
type: 0
|
||||||
unit: Mb
|
unit: Mb
|
||||||
|
- field: usage
|
||||||
|
type: 0
|
||||||
|
unit: '%'
|
||||||
|
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
|
||||||
|
aliasFields:
|
||||||
|
- total
|
||||||
|
- used
|
||||||
|
- free
|
||||||
|
- buff_cache
|
||||||
|
- available
|
||||||
|
# (非必须)指标计算表达式,与上面的别名一起作用,计算出最终需要的指标值
|
||||||
|
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
|
||||||
|
calculates:
|
||||||
|
- total=total
|
||||||
|
- used=used
|
||||||
|
- free=free
|
||||||
|
- buff_cache=buff_cache
|
||||||
|
- available=available
|
||||||
|
- usage=(used / total) * 100
|
||||||
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||||
protocol: ssh
|
protocol: ssh
|
||||||
# 当protocol为http协议时具体的采集配置
|
# 当protocol为http协议时具体的采集配置
|
||||||
@@ -154,6 +193,7 @@ metrics:
|
|||||||
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
||||||
- field: interface_name
|
- field: interface_name
|
||||||
type: 1
|
type: 1
|
||||||
|
instance: true
|
||||||
- field: receive_bytes
|
- field: receive_bytes
|
||||||
type: 0
|
type: 0
|
||||||
unit: byte
|
unit: byte
|
||||||
@@ -173,3 +213,35 @@ metrics:
|
|||||||
timeout: ^_^timeout^_^
|
timeout: ^_^timeout^_^
|
||||||
script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {print $1,$2,$10}'
|
script: cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "interface_name receive_bytes transmit_bytes"} {print $1,$2,$10}'
|
||||||
parseType: multiRow
|
parseType: multiRow
|
||||||
|
|
||||||
|
- name: disk_free
|
||||||
|
priority: 5
|
||||||
|
fields:
|
||||||
|
# 指标信息 包括 field名称 type字段类型:0-number数字,1-string字符串 instance是否为实例主键 unit:指标单位
|
||||||
|
- field: filesystem
|
||||||
|
type: 1
|
||||||
|
- field: used
|
||||||
|
type: 0
|
||||||
|
unit: Mb
|
||||||
|
- field: available
|
||||||
|
type: 0
|
||||||
|
unit: Mb
|
||||||
|
- field: usage
|
||||||
|
type: 0
|
||||||
|
unit: '%'
|
||||||
|
- field: mounted
|
||||||
|
type: 1
|
||||||
|
instance: true
|
||||||
|
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||||
|
protocol: ssh
|
||||||
|
# 当protocol为http协议时具体的采集配置
|
||||||
|
ssh:
|
||||||
|
# 主机host: ipv4 ipv6 域名
|
||||||
|
host: ^_^host^_^
|
||||||
|
# 端口
|
||||||
|
port: ^_^port^_^
|
||||||
|
username: ^_^username^_^
|
||||||
|
password: ^_^password^_^
|
||||||
|
timeout: ^_^timeout^_^
|
||||||
|
script: df -m | tail -n +2 | awk 'BEGIN{ print "filesystem used available usage mounted"} {print $1,$3,$4,$5,$6}'
|
||||||
|
parseType: multiRow
|
||||||
@@ -32,8 +32,6 @@ metrics:
|
|||||||
- field: database_version
|
- field: database_version
|
||||||
type: 1
|
type: 1
|
||||||
instance: true
|
instance: true
|
||||||
- field: database_type
|
|
||||||
type: 1
|
|
||||||
- field: hostname
|
- field: hostname
|
||||||
type: 1
|
type: 1
|
||||||
- field: instance_name
|
- field: instance_name
|
||||||
@@ -45,7 +43,6 @@ metrics:
|
|||||||
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
|
# (非必须)监控指标别名,与上面的指标名映射。用于采集接口数据字段不直接是最终指标名称,需要此别名做映射转换
|
||||||
aliasFields:
|
aliasFields:
|
||||||
- VERSION
|
- VERSION
|
||||||
- DATABASE_TYPE
|
|
||||||
- HOST_NAME
|
- HOST_NAME
|
||||||
- INSTANCE_NAME
|
- INSTANCE_NAME
|
||||||
- STARTUP_TIME
|
- STARTUP_TIME
|
||||||
@@ -54,7 +51,6 @@ metrics:
|
|||||||
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
|
# eg: cores=core1+core2, usage=usage, waitTime=allTime-runningTime
|
||||||
calculates:
|
calculates:
|
||||||
- database_version=VERSION
|
- database_version=VERSION
|
||||||
- database_type=DATABASE_TYPE
|
|
||||||
- hostname=HOST_NAME
|
- hostname=HOST_NAME
|
||||||
- instance_name=INSTANCE_NAME
|
- instance_name=INSTANCE_NAME
|
||||||
- startup_time=STARTUP_TIME
|
- startup_time=STARTUP_TIME
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
category: service
|
|
||||||
app: telnet
|
|
||||||
name:
|
|
||||||
zh-CN: TELNET端口可用性
|
|
||||||
en-US: PORT TELNET
|
|
||||||
configmap:
|
|
||||||
- key: host
|
|
||||||
type: 1
|
|
||||||
- key: port
|
|
||||||
type: 0
|
|
||||||
- key: timeout
|
|
||||||
type: 0
|
|
||||||
metrics:
|
|
||||||
- name: summary
|
|
||||||
priority: 0
|
|
||||||
fields:
|
|
||||||
- field: responseTime
|
|
||||||
type: 0
|
|
||||||
unit: ms
|
|
||||||
protocol: telnet
|
|
||||||
# 当protocol为telnet协议时具体的采集配置
|
|
||||||
telnet:
|
|
||||||
host: ^_^host^_^
|
|
||||||
port: ^_^port^_^
|
|
||||||
timeout: ^_^timeout^_^
|
|
||||||
@@ -12,10 +12,18 @@ configmap:
|
|||||||
type: 1
|
type: 1
|
||||||
- key: ssl
|
- key: ssl
|
||||||
type: 1
|
type: 1
|
||||||
|
- key: authType
|
||||||
|
type: 1
|
||||||
|
- key: username
|
||||||
|
type: 1
|
||||||
|
- key: password
|
||||||
|
type: 2
|
||||||
|
- key: keyword
|
||||||
|
type: 1
|
||||||
# 指标组列表
|
# 指标组列表
|
||||||
metrics:
|
metrics:
|
||||||
# 第一个监控指标组 cpu
|
# 第一个监控指标组 cpu
|
||||||
# 注意:内置监控指标有 (responseTime - 响应时间)
|
# 注意:内置监控指标有 (responseTime - 响应时间, keyword - 关键字数量)
|
||||||
- name: summary
|
- name: summary
|
||||||
# 指标组调度优先级(0-127)越小优先级越高,优先级低的指标组会等优先级高的指标组采集完成后才会被调度,相同优先级的指标组会并行调度采集
|
# 指标组调度优先级(0-127)越小优先级越高,优先级低的指标组会等优先级高的指标组采集完成后才会被调度,相同优先级的指标组会并行调度采集
|
||||||
# 优先级为0的指标组为可用性指标组,即它会被首先调度,采集成功才会继续调度其它指标组,采集失败则中断调度
|
# 优先级为0的指标组为可用性指标组,即它会被首先调度,采集成功才会继续调度其它指标组,采集失败则中断调度
|
||||||
@@ -26,6 +34,9 @@ metrics:
|
|||||||
- field: responseTime
|
- field: responseTime
|
||||||
type: 0
|
type: 0
|
||||||
unit: ms
|
unit: ms
|
||||||
|
- field: keyword
|
||||||
|
type: 0
|
||||||
|
unit: 次数
|
||||||
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
# 监控采集使用协议 eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||||
protocol: http
|
protocol: http
|
||||||
# 当protocol为http协议时具体的采集配置
|
# 当protocol为http协议时具体的采集配置
|
||||||
@@ -40,6 +51,14 @@ metrics:
|
|||||||
method: GET
|
method: GET
|
||||||
# 是否启用ssl/tls,即是http还是https,默认false
|
# 是否启用ssl/tls,即是http还是https,默认false
|
||||||
ssl: ^_^ssl^_^
|
ssl: ^_^ssl^_^
|
||||||
|
authorization:
|
||||||
|
# 认证方式: Basic Auth, Digest Auth, Bearer Token
|
||||||
|
type: ^_^authType^_^
|
||||||
|
basicAuthUsername: ^_^username^_^
|
||||||
|
basicAuthPassword: ^_^password^_^
|
||||||
|
digestAuthUsername: ^_^username^_^
|
||||||
|
digestAuthPassword: ^_^password^_^
|
||||||
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-网站可用性指标监控
|
# 响应数据解析方式: default-系统规则,jsonPath-jsonPath脚本,website-网站可用性指标监控
|
||||||
# todo xmlPath-xmlPath脚本,prometheus-Prometheus数据规则
|
# todo xmlPath-xmlPath脚本,prometheus-Prometheus数据规则
|
||||||
parseType: website
|
parseType: website
|
||||||
|
keyword: ^_^keyword^_^
|
||||||
@@ -26,10 +26,12 @@ param:
|
|||||||
# 当type为text时,用limit表示字符串限制大小
|
# 当type为text时,用limit表示字符串限制大小
|
||||||
limit: 20
|
limit: 20
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
- field: password
|
- field: password
|
||||||
name: 密码
|
name: 密码
|
||||||
type: password
|
type: password
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
- field: ssl
|
- field: ssl
|
||||||
name: 启动SSL
|
name: 启动SSL
|
||||||
# 当type为boolean时,前端用switch展示开关
|
# 当type为boolean时,前端用switch展示开关
|
||||||
@@ -50,7 +52,7 @@ param:
|
|||||||
- label: DELETE请求
|
- label: DELETE请求
|
||||||
value: DELETE
|
value: DELETE
|
||||||
- field: headers
|
- field: headers
|
||||||
name: 请求头
|
name: 请求Headers
|
||||||
type: key-value
|
type: key-value
|
||||||
required: false
|
required: false
|
||||||
keyAlias: Header Name
|
keyAlias: Header Name
|
||||||
|
|||||||
@@ -17,13 +17,6 @@ param:
|
|||||||
range: '[0,65535]'
|
range: '[0,65535]'
|
||||||
required: true
|
required: true
|
||||||
defaultValue: 80
|
defaultValue: 80
|
||||||
- field: uri
|
|
||||||
name: 相对路径
|
|
||||||
type: text
|
|
||||||
# 当type为text时,用limit表示字符串限制大小
|
|
||||||
limit: 200
|
|
||||||
required: false
|
|
||||||
placeholder: 'API地址除IP端口外的路径 例如:/v2/book/bar'
|
|
||||||
- field: method
|
- field: method
|
||||||
name: 请求方式
|
name: 请求方式
|
||||||
type: radio
|
type: radio
|
||||||
@@ -38,28 +31,67 @@ param:
|
|||||||
value: PUT
|
value: PUT
|
||||||
- label: DELETE请求
|
- label: DELETE请求
|
||||||
value: DELETE
|
value: DELETE
|
||||||
|
- field: uri
|
||||||
|
name: 相对路径
|
||||||
|
type: text
|
||||||
|
# 当type为text时,用limit表示字符串限制大小
|
||||||
|
limit: 200
|
||||||
|
required: false
|
||||||
|
placeholder: 'API地址除IP端口外的路径 例如:/v2/book/bar'
|
||||||
- field: ssl
|
- field: ssl
|
||||||
name: 启用HTTPS
|
name: 启用HTTPS
|
||||||
# 当type为boolean时,前端用switch展示开关
|
# 当type为boolean时,前端用switch展示开关
|
||||||
type: boolean
|
type: boolean
|
||||||
required: true
|
required: true
|
||||||
|
- field: headers
|
||||||
|
name: 请求Headers
|
||||||
|
type: key-value
|
||||||
|
required: false
|
||||||
|
keyAlias: Header Name
|
||||||
|
valueAlias: Header Value
|
||||||
|
- field: params
|
||||||
|
name: 查询Params
|
||||||
|
type: key-value
|
||||||
|
required: false
|
||||||
|
keyAlias: Param Key
|
||||||
|
valueAlias: Param Value
|
||||||
|
- field: contentType
|
||||||
|
name: Content-Type
|
||||||
|
type: text
|
||||||
|
placeholder: '请求BODY资源类型'
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
- field: payload
|
||||||
|
name: 请求BODY
|
||||||
|
type: textarea
|
||||||
|
placeholder: 'POST PUT请求时有效'
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
- field: authType
|
||||||
|
name: 认证方式
|
||||||
|
type: radio
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
# 当type为radio单选框,checkbox复选框时,option表示可选项值列表 {name1:value1,name2:value2}
|
||||||
|
options:
|
||||||
|
- label: Basic Auth
|
||||||
|
value: Basic Auth
|
||||||
|
- label: Digest Auth
|
||||||
|
value: Digest Auth
|
||||||
- field: username
|
- field: username
|
||||||
name: 用户名
|
name: 用户名
|
||||||
type: text
|
type: text
|
||||||
# 当type为text时,用limit表示字符串限制大小
|
# 当type为text时,用limit表示字符串限制大小
|
||||||
limit: 20
|
limit: 20
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
- field: password
|
- field: password
|
||||||
name: 密码
|
name: 密码
|
||||||
type: password
|
type: password
|
||||||
required: false
|
required: false
|
||||||
- field: contentType
|
hide: true
|
||||||
name: Content-Type
|
- field: keyword
|
||||||
|
name: 关键字
|
||||||
type: text
|
type: text
|
||||||
placeholder: '请求BODY资源类型'
|
|
||||||
required: false
|
|
||||||
- field: payload
|
|
||||||
name: 请求BODY
|
|
||||||
type: textarea
|
|
||||||
placeholder: 'POST PUT请求时有效'
|
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ param:
|
|||||||
required: false
|
required: false
|
||||||
defaultValue: 6000
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
|
hide: true
|
||||||
- field: database
|
- field: database
|
||||||
name: 数据库名称
|
name: 数据库名称
|
||||||
type: text
|
type: text
|
||||||
@@ -34,3 +35,4 @@ param:
|
|||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -15,6 +15,7 @@ param:
|
|||||||
name: 查询超时时间
|
name: 查询超时时间
|
||||||
type: number
|
type: number
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
defaultValue: 6000
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
- field: database
|
- field: database
|
||||||
@@ -34,3 +35,4 @@ param:
|
|||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -15,6 +15,7 @@ param:
|
|||||||
name: 查询超时时间
|
name: 查询超时时间
|
||||||
type: number
|
type: number
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
defaultValue: 6000
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
- field: database
|
- field: database
|
||||||
@@ -34,3 +35,4 @@ param:
|
|||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -15,6 +15,7 @@ param:
|
|||||||
name: 查询超时时间
|
name: 查询超时时间
|
||||||
type: number
|
type: number
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
defaultValue: 6000
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
- field: database
|
- field: database
|
||||||
@@ -34,3 +35,4 @@ param:
|
|||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -15,6 +15,7 @@ param:
|
|||||||
name: 查询超时时间
|
name: 查询超时时间
|
||||||
type: number
|
type: number
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
defaultValue: 6000
|
defaultValue: 6000
|
||||||
placeholder: '查询超时时间'
|
placeholder: '查询超时时间'
|
||||||
- field: database
|
- field: database
|
||||||
@@ -34,3 +35,4 @@ param:
|
|||||||
name: URL
|
name: URL
|
||||||
type: text
|
type: text
|
||||||
required: false
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# 监控应用类型名称(与文件名保持一致) eg: linux windows tomcat mysql aws...
|
|
||||||
app: telnet
|
|
||||||
# 强制固定必须参数 - host(ipv4,ipv6,域名)
|
|
||||||
param:
|
|
||||||
# field-字段名称标识符
|
|
||||||
- field: host
|
|
||||||
# name-参数字段显示名称
|
|
||||||
name: 主机Host
|
|
||||||
# type-字段类型,样式(大部分映射input标签type属性)
|
|
||||||
type: host
|
|
||||||
# 是否是必输项 true-必填 false-可选
|
|
||||||
required: true
|
|
||||||
- field: port
|
|
||||||
name: 端口
|
|
||||||
type: number
|
|
||||||
# 当type为number时,用range表示范围
|
|
||||||
range: '[0,65535]'
|
|
||||||
required: true
|
|
||||||
defaultValue: 80
|
|
||||||
- field: timeout
|
|
||||||
name: Telnet超时时间
|
|
||||||
type: number
|
|
||||||
# 当type为number时,用range表示范围
|
|
||||||
range: '[0,100000]'
|
|
||||||
required: true
|
|
||||||
placeholder: '请输入超时时间,单位毫秒'
|
|
||||||
defaultValue: 6000
|
|
||||||
@@ -29,3 +29,31 @@ param:
|
|||||||
# 当type为boolean时,前端用switch展示开关
|
# 当type为boolean时,前端用switch展示开关
|
||||||
type: boolean
|
type: boolean
|
||||||
required: true
|
required: true
|
||||||
|
- field: authType
|
||||||
|
name: 认证方式
|
||||||
|
type: radio
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
# 当type为radio单选框,checkbox复选框时,option表示可选项值列表 {name1:value1,name2:value2}
|
||||||
|
options:
|
||||||
|
- label: Basic Auth
|
||||||
|
value: Basic Auth
|
||||||
|
- label: Digest Auth
|
||||||
|
value: Digest Auth
|
||||||
|
- field: username
|
||||||
|
name: 用户名
|
||||||
|
type: text
|
||||||
|
# 当type为text时,用limit表示字符串限制大小
|
||||||
|
limit: 20
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
- field: password
|
||||||
|
name: 密码
|
||||||
|
type: password
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
|
- field: keyword
|
||||||
|
name: 关键字
|
||||||
|
type: text
|
||||||
|
required: false
|
||||||
|
hide: true
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd
|
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd
|
||||||
http://maven.apache.org/ASSEMBLY/2.0.0 ">
|
http://maven.apache.org/ASSEMBLY/2.0.0 ">
|
||||||
<!--必填,会追加到打包文件名称的末尾-->
|
<!--必填,会追加到打包文件名称的末尾-->
|
||||||
<id>1.0-beta.6</id>
|
<id>1.0-beta.7</id>
|
||||||
<!--打包类型,可以设置多种类型,打包的时候不同的类型都会打包打出来-->
|
<!--打包类型,可以设置多种类型,打包的时候不同的类型都会打包打出来-->
|
||||||
<formats>
|
<formats>
|
||||||
<format>tar</format>
|
<format>tar</format>
|
||||||
|
|||||||
@@ -28,9 +28,7 @@ if [ ! -d $LOGS_DIR ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# JVM Configuration
|
# JVM Configuration
|
||||||
JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true "
|
JAVA_MEM_OPTS=" -server -XX:SurvivorRatio=6 -XX:+UseParallelGC "
|
||||||
|
|
||||||
JAVA_MEM_OPTS=" -server -Xms256m -Xmx1024m -XX:SurvivorRatio=2 -XX:+UseParallelGC "
|
|
||||||
|
|
||||||
# 加载外部log文件的配置
|
# 加载外部log文件的配置
|
||||||
LOG_IMPL_FILE=logback-spring.xml
|
LOG_IMPL_FILE=logback-spring.xml
|
||||||
@@ -41,4 +39,4 @@ then
|
|||||||
fi
|
fi
|
||||||
CONFIG_FILES=" -Dlogging.path=$LOGS_DIR $LOGGING_CONFIG -Dspring.config.location=$CONF_DIR/ "
|
CONFIG_FILES=" -Dlogging.path=$LOGS_DIR $LOGGING_CONFIG -Dspring.config.location=$CONF_DIR/ "
|
||||||
echo -e "Starting the $SERVER_NAME ..."
|
echo -e "Starting the $SERVER_NAME ..."
|
||||||
java $JAVA_OPTS $JAVA_MEM_OPTS $CONFIG_FILES -jar $DEPLOY_DIR/$JAR_NAME --spring.profiles.active=prod
|
java $JAVA_MEM_OPTS $CONFIG_FILES -jar $DEPLOY_DIR/$JAR_NAME --spring.profiles.active=prod
|
||||||
23
script/assembly/server/bin/shutdown.bat
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
@title HertzBeat
|
||||||
|
@echo off
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
rem 项目名称
|
||||||
|
set SERVER_NAME="${project.artifactId}"
|
||||||
|
|
||||||
|
|
||||||
|
rem 应用的端口号
|
||||||
|
set SERVER_PORT=1157
|
||||||
|
|
||||||
|
echo Start shutdown HertzBeat %SERVER_NAME%
|
||||||
|
|
||||||
|
for /f "tokens=1-5" %%i in ('netstat -ano^|findstr ":%SERVER_PORT%"') do (
|
||||||
|
echo kill the process %%m who use the port
|
||||||
|
taskkill /pid %%m -t -f
|
||||||
|
echo Shutdown HertzBeat %SERVER_NAME% Success!
|
||||||
|
goto q
|
||||||
|
)
|
||||||
|
echo Faild shutdown HertzBeat %SERVER_NAME%
|
||||||
|
|
||||||
|
:q
|
||||||
|
pause
|
||||||
56
script/assembly/server/bin/startup.bat
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
@title HertzBeat
|
||||||
|
@echo off
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
rem 项目名称
|
||||||
|
set SERVER_NAME=${project.artifactId}
|
||||||
|
|
||||||
|
rem jar名称
|
||||||
|
set JAR_NAME=${project.build.finalName}.jar
|
||||||
|
|
||||||
|
rem 进入bin目录
|
||||||
|
cd /d %~dp0
|
||||||
|
rem 返回到上一级项目根目录路径
|
||||||
|
cd ..
|
||||||
|
rem 打印项目安装根目录绝对路径
|
||||||
|
set DEPLOY_DIR=%~dp0..
|
||||||
|
echo %DEPLOY_DIR%
|
||||||
|
rem 外部配置文件绝对目录,如果是目录需要/结尾,也可以直接指定文件
|
||||||
|
rem 如果指定的是目录,spring则会读取目录中的所有配置文件
|
||||||
|
set CONF_DIR=%DEPLOY_DIR%\config
|
||||||
|
echo %CONF_DIR%
|
||||||
|
|
||||||
|
rem 应用的端口号
|
||||||
|
set SERVER_PORT=1157
|
||||||
|
|
||||||
|
for /f "tokens=1-5" %%i in ('netstat -ano^|findstr "0.0.0.0:%SERVER_PORT%"') do (
|
||||||
|
echo The HertzBeat %SERVER_NAME% port %SERVER_PORT% already used!
|
||||||
|
echo exit!
|
||||||
|
goto q
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rem 项目日志输出绝对路径
|
||||||
|
set LOGS_DIR=%DEPLOY_DIR%\logs
|
||||||
|
|
||||||
|
rem JVM Configuration
|
||||||
|
set JAVA_OPTS= -Duser.timezone=Asia/Shanghai
|
||||||
|
|
||||||
|
set JAVA_MEM_OPTS= -server -XX:SurvivorRatio=6 -XX:+UseParallelGC
|
||||||
|
|
||||||
|
rem 加载外部log文件的配置
|
||||||
|
set LOGGING_CONFIG=-Dlogging.config=%CONF_DIR%\logback-spring.xml
|
||||||
|
rem 注意配置文件目录最后的后缀需为 / 而不是 windows \
|
||||||
|
set CONFIG_FILES= -Dlogging.path=%LOGS_DIR% %LOGGING_CONFIG% -Dspring.config.location=%CONF_DIR%/
|
||||||
|
echo Starting the %SERVER_NAME% ...
|
||||||
|
|
||||||
|
start javaw %JAVA_OPTS% %JAVA_MEM_OPTS% %CONFIG_FILES% -jar %DEPLOY_DIR%\%JAR_NAME%
|
||||||
|
|
||||||
|
echo "Service starting OK!"
|
||||||
|
for /f "tokens=1-5" %%i in ('netstat -ano^|findstr ":%SERVER_PORT%"') do (
|
||||||
|
echo Service PID: %%m , Port %SERVER_PORT%
|
||||||
|
goto q
|
||||||
|
)
|
||||||
|
|
||||||
|
:q
|
||||||
|
pause
|
||||||
@@ -66,9 +66,9 @@ if [ ! -d $LOGS_DIR ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# JVM Configuration
|
# JVM Configuration
|
||||||
JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Duser.timezone=Asia/Shanghai"
|
JAVA_OPTS=" -Duser.timezone=Asia/Shanghai"
|
||||||
|
|
||||||
JAVA_MEM_OPTS=" -server -Xms256m -Xmx1024m -XX:SurvivorRatio=2 -XX:+UseParallelGC "
|
JAVA_MEM_OPTS=" -server -XX:SurvivorRatio=6 -XX:+UseParallelGC "
|
||||||
|
|
||||||
# 加载外部log文件的配置
|
# 加载外部log文件的配置
|
||||||
LOG_IMPL_FILE=logback-spring.xml
|
LOG_IMPL_FILE=logback-spring.xml
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ services:
|
|||||||
- heartzbeat
|
- heartzbeat
|
||||||
|
|
||||||
hertzbeat:
|
hertzbeat:
|
||||||
image: "tancloud/hertzbeat:1.0-beta.6"
|
image: "tancloud/hertzbeat:1.0-beta.7"
|
||||||
container_name: hertzbeat
|
container_name: hertzbeat
|
||||||
hostname: hertzbeat
|
hostname: hertzbeat
|
||||||
restart: always
|
restart: always
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ FROM openjdk:8-alpine
|
|||||||
|
|
||||||
MAINTAINER tomsun28 "tomsun28@outlook.com"
|
MAINTAINER tomsun28 "tomsun28@outlook.com"
|
||||||
|
|
||||||
ADD hertzbeat-1.0-beta.6.tar /opt/
|
ADD hertzbeat-1.0-beta.7.tar /opt/
|
||||||
|
|
||||||
RUN apk add --no-cache tzdata
|
RUN apk add --no-cache tzdata
|
||||||
|
|
||||||
|
|||||||
BIN
tancloud.gif
|
Before Width: | Height: | Size: 30 MiB After Width: | Height: | Size: 15 MiB |
@@ -61,11 +61,11 @@ public class TdEngineDataStorage implements DisposableBean {
|
|||||||
log.error("init error, please config Warehouse TdEngine props in application.yml");
|
log.error("init error, please config Warehouse TdEngine props in application.yml");
|
||||||
throw new IllegalArgumentException("please config Warehouse TdEngine props");
|
throw new IllegalArgumentException("please config Warehouse TdEngine props");
|
||||||
}
|
}
|
||||||
initTdEngineDatasource(properties.getStore().getTdEngine());
|
boolean success = initTdEngineDatasource(properties.getStore().getTdEngine());
|
||||||
startStorageData();
|
startStorageData(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initTdEngineDatasource(WarehouseProperties.StoreProperties.TdEngineProperties tdEngineProperties) {
|
private boolean initTdEngineDatasource(WarehouseProperties.StoreProperties.TdEngineProperties tdEngineProperties) {
|
||||||
HikariConfig config = new HikariConfig();
|
HikariConfig config = new HikariConfig();
|
||||||
// jdbc properties
|
// jdbc properties
|
||||||
config.setJdbcUrl(tdEngineProperties.getUrl());
|
config.setJdbcUrl(tdEngineProperties.getUrl());
|
||||||
@@ -84,16 +84,28 @@ public class TdEngineDataStorage implements DisposableBean {
|
|||||||
config.setIdleTimeout(0);
|
config.setIdleTimeout(0);
|
||||||
//validation query
|
//validation query
|
||||||
config.setConnectionTestQuery("select server_status()");
|
config.setConnectionTestQuery("select server_status()");
|
||||||
|
try {
|
||||||
this.hikariDataSource = new HikariDataSource(config);
|
this.hikariDataSource = new HikariDataSource(config);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("\n\t------------------WARN WARN WARN------------------\n" +
|
||||||
|
"\t---------------Init TdEngine Failed---------------\n" +
|
||||||
|
"\t---------------Init TdEngine Failed---------------\n" +
|
||||||
|
"\t--------------Please Config Tdengine--------------\n" +
|
||||||
|
"\t----------Can Not Use Metric History Now----------\n" +
|
||||||
|
"\t----------Can Not Use Metric History Now----------\n" +
|
||||||
|
"\t----------Can Not Use Metric History Now----------\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startStorageData() {
|
private void startStorageData(boolean consume) {
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
Thread.currentThread().setName("warehouse-tdEngine-data-storage");
|
Thread.currentThread().setName("warehouse-tdEngine-data-storage");
|
||||||
while (!Thread.currentThread().isInterrupted()) {
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
try {
|
try {
|
||||||
CollectRep.MetricsData metricsData = dataExporter.pollPersistentStorageMetricsData();
|
CollectRep.MetricsData metricsData = dataExporter.pollPersistentStorageMetricsData();
|
||||||
if (metricsData != null) {
|
if (consume && metricsData != null) {
|
||||||
saveData(metricsData);
|
saveData(metricsData);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@@ -232,6 +244,12 @@ public class TdEngineDataStorage implements DisposableBean {
|
|||||||
Connection connection = null;
|
Connection connection = null;
|
||||||
Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
|
Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
|
||||||
try {
|
try {
|
||||||
|
if (hikariDataSource == null) {
|
||||||
|
log.error("\n\t---------------TdEngine Init Failed---------------\n" +
|
||||||
|
"\t--------------Please Config Tdengine--------------\n" +
|
||||||
|
"\t----------Can Not Use Metric History Now----------\n");
|
||||||
|
return instanceValuesMap;
|
||||||
|
}
|
||||||
connection = hikariDataSource.getConnection();
|
connection = hikariDataSource.getConnection();
|
||||||
Statement statement = connection.createStatement();
|
Statement statement = connection.createStatement();
|
||||||
ResultSet resultSet = statement.executeQuery(selectSql);
|
ResultSet resultSet = statement.executeQuery(selectSql);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<global-footer [links]="links">
|
<global-footer [links]="links">
|
||||||
Copyright
|
Copyright
|
||||||
<i nz-icon nzType="copyright" nzTheme="outline"></i>
|
<i nz-icon nzType="copyright" nzTheme="outline"></i>
|
||||||
2021
|
2022
|
||||||
<a href="https://tancloud.cn" target="_blank">探云 tancloud.cn | </a>
|
<a href="https://tancloud.cn" target="_blank">探云 tancloud.cn | </a>
|
||||||
<a href="https://hertzbeat.com" target="_blank">赫兹跳动 hertzbeat.com</a>
|
<a href="https://hertzbeat.com" target="_blank">赫兹跳动 hertzbeat.com</a>
|
||||||
</global-footer>
|
</global-footer>
|
||||||
|
|||||||
@@ -12,4 +12,6 @@ export class ParamDefine {
|
|||||||
// 当type为key-value时有效,表示别名描述
|
// 当type为key-value时有效,表示别名描述
|
||||||
keyAlias!: string;
|
keyAlias!: string;
|
||||||
valueAlias!: string;
|
valueAlias!: string;
|
||||||
|
// 此参数是否隐藏 即默认不显示, 在高级设置区显示
|
||||||
|
hide: boolean = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,6 +125,7 @@
|
|||||||
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
<nz-switch
|
<nz-switch
|
||||||
[(ngModel)]="params[i].value"
|
[(ngModel)]="params[i].value"
|
||||||
|
(ngModelChange)="onParamBooleanChanged($event, paramDefine.field)"
|
||||||
[required]="paramDefine.required"
|
[required]="paramDefine.required"
|
||||||
[name]="paramDefine.field"
|
[name]="paramDefine.field"
|
||||||
[id]="paramDefine.field"
|
[id]="paramDefine.field"
|
||||||
@@ -161,11 +162,151 @@
|
|||||||
</nz-form-control>
|
</nz-form-control>
|
||||||
</nz-form-item>
|
</nz-form-item>
|
||||||
|
|
||||||
|
<nz-collapse [nzGhost]="true">
|
||||||
|
<nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
|
||||||
|
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control
|
||||||
|
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
|
||||||
|
nzSpan="8"
|
||||||
|
[nzErrorTip]="'validation.required' | i18n"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
nz-input
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[type]="paramDefine.type"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
/>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'textarea'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'textarea'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<textarea
|
||||||
|
nz-input
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
rows="3"
|
||||||
|
></textarea>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'password'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-input-group [nzSuffix]="suffixTemplate" style="width: 100%">
|
||||||
|
<input
|
||||||
|
[type]="passwordVisible ? 'text' : 'password'"
|
||||||
|
nz-input
|
||||||
|
placeholder="input password"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
/>
|
||||||
|
</nz-input-group>
|
||||||
|
<ng-template #suffixTemplate>
|
||||||
|
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i>
|
||||||
|
</ng-template>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'number'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-input-number
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[nzMin]="-1000"
|
||||||
|
[nzMax]="65535"
|
||||||
|
[nzStep]="1"
|
||||||
|
[nzPlaceHolder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
></nz-input-number>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'boolean'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-switch
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
></nz-switch>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'radio'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-radio-group
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
nzButtonStyle="solid"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
>
|
||||||
|
<label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options">
|
||||||
|
{{ optionItem.label }}
|
||||||
|
</label>
|
||||||
|
</nz-radio-group>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'key-value'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'key-value'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<app-key-value-input
|
||||||
|
[(value)]="advancedParams[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
keyAlias="Header Name"
|
||||||
|
valueAlias="Header Value"
|
||||||
|
></app-key-value-input>
|
||||||
|
</nz-form-control>
|
||||||
|
</nz-form-item>
|
||||||
|
</nz-collapse-panel>
|
||||||
|
</nz-collapse>
|
||||||
|
<ng-template #extraColHeader>
|
||||||
|
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
|
||||||
|
<span>高级设置</span>
|
||||||
|
<i nz-icon nzType="down-circle" nzTheme="outline"></i>
|
||||||
|
</button>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<nz-divider></nz-divider>
|
<nz-divider></nz-divider>
|
||||||
|
|
||||||
<nz-form-item>
|
<nz-form-item>
|
||||||
<nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
|
<nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
|
||||||
<nz-form-control nzSpan="10">
|
<nz-form-control nzSpan="8">
|
||||||
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="604800" [nzStep]="60" name="intervals" id="intervals">
|
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="604800" [nzStep]="60" name="intervals" id="intervals">
|
||||||
</nz-input-number>
|
</nz-input-number>
|
||||||
</nz-form-control>
|
</nz-form-control>
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
|
|
||||||
paramDefines!: ParamDefine[];
|
paramDefines!: ParamDefine[];
|
||||||
params!: Param[];
|
params!: Param[];
|
||||||
|
advancedParamDefines!: ParamDefine[];
|
||||||
|
advancedParams!: Param[];
|
||||||
paramValueMap = new Map<String, Param>();
|
paramValueMap = new Map<String, Param>();
|
||||||
monitor = new Monitor();
|
monitor = new Monitor();
|
||||||
profileForm: FormGroup = new FormGroup({});
|
profileForm: FormGroup = new FormGroup({});
|
||||||
@@ -59,7 +61,6 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
this.paramValueMap.set(item.field, item);
|
this.paramValueMap.set(item.field, item);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.params = message.data.params;
|
|
||||||
this.detected = message.data.detected ? message.data.detected : true;
|
this.detected = message.data.detected ? message.data.detected : true;
|
||||||
} else {
|
} else {
|
||||||
console.warn(message.msg);
|
console.warn(message.msg);
|
||||||
@@ -71,9 +72,11 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
)
|
)
|
||||||
.subscribe(message => {
|
.subscribe(message => {
|
||||||
if (message.code === 0) {
|
if (message.code === 0) {
|
||||||
this.paramDefines = message.data;
|
|
||||||
this.params = [];
|
this.params = [];
|
||||||
this.paramDefines.forEach(define => {
|
this.advancedParams = [];
|
||||||
|
this.paramDefines = [];
|
||||||
|
this.advancedParamDefines = [];
|
||||||
|
message.data.forEach(define => {
|
||||||
let param = this.paramValueMap.get(define.field);
|
let param = this.paramValueMap.get(define.field);
|
||||||
if (param === undefined) {
|
if (param === undefined) {
|
||||||
param = new Param();
|
param = new Param();
|
||||||
@@ -100,7 +103,13 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (define.hide) {
|
||||||
|
this.advancedParams.push(param);
|
||||||
|
this.advancedParamDefines.push(define);
|
||||||
|
} else {
|
||||||
this.params.push(param);
|
this.params.push(param);
|
||||||
|
this.paramDefines.push(define);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn(message.msg);
|
console.warn(message.msg);
|
||||||
@@ -108,6 +117,21 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onParamBooleanChanged(booleanValue: boolean, field: string) {
|
||||||
|
// 对SSL的端口联动处理, 不开启SSL默认80端口,开启SSL默认443
|
||||||
|
if (field === 'ssl') {
|
||||||
|
this.params.forEach(param => {
|
||||||
|
if (param.field === 'port') {
|
||||||
|
if (booleanValue) {
|
||||||
|
param.value = '443';
|
||||||
|
} else {
|
||||||
|
param.value = '80';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit(formGroup: FormGroup) {
|
onSubmit(formGroup: FormGroup) {
|
||||||
if (formGroup.invalid) {
|
if (formGroup.invalid) {
|
||||||
Object.values(formGroup.controls).forEach(control => {
|
Object.values(formGroup.controls).forEach(control => {
|
||||||
@@ -129,10 +153,15 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
param.value = (param.value as string).trim();
|
param.value = (param.value as string).trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.advancedParams.forEach(param => {
|
||||||
|
if (param.value != null && typeof param.value == 'string') {
|
||||||
|
param.value = (param.value as string).trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
let addMonitor = {
|
let addMonitor = {
|
||||||
detected: this.detected,
|
detected: this.detected,
|
||||||
monitor: this.monitor,
|
monitor: this.monitor,
|
||||||
params: this.params
|
params: this.params.concat(this.advancedParams)
|
||||||
};
|
};
|
||||||
this.isSpinning = true;
|
this.isSpinning = true;
|
||||||
this.monitorSvc.editMonitor(addMonitor).subscribe(
|
this.monitorSvc.editMonitor(addMonitor).subscribe(
|
||||||
@@ -173,10 +202,15 @@ export class MonitorEditComponent implements OnInit {
|
|||||||
param.value = (param.value as string).trim();
|
param.value = (param.value as string).trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.advancedParams.forEach(param => {
|
||||||
|
if (param.value != null && typeof param.value == 'string') {
|
||||||
|
param.value = (param.value as string).trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
let detectMonitor = {
|
let detectMonitor = {
|
||||||
detected: this.detected,
|
detected: this.detected,
|
||||||
monitor: this.monitor,
|
monitor: this.monitor,
|
||||||
params: this.params
|
params: this.params.concat(this.advancedParams)
|
||||||
};
|
};
|
||||||
this.isSpinning = true;
|
this.isSpinning = true;
|
||||||
this.monitorSvc.detectMonitor(detectMonitor).subscribe(
|
this.monitorSvc.detectMonitor(detectMonitor).subscribe(
|
||||||
|
|||||||
@@ -134,6 +134,7 @@
|
|||||||
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
<nz-switch
|
<nz-switch
|
||||||
[(ngModel)]="params[i].value"
|
[(ngModel)]="params[i].value"
|
||||||
|
(ngModelChange)="onParamBooleanChanged($event, paramDefine.field)"
|
||||||
[required]="paramDefine.required"
|
[required]="paramDefine.required"
|
||||||
[name]="paramDefine.field"
|
[name]="paramDefine.field"
|
||||||
[id]="paramDefine.field"
|
[id]="paramDefine.field"
|
||||||
@@ -170,6 +171,146 @@
|
|||||||
</nz-form-control>
|
</nz-form-control>
|
||||||
</nz-form-item>
|
</nz-form-item>
|
||||||
|
|
||||||
|
<nz-collapse [nzGhost]="true">
|
||||||
|
<nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
|
||||||
|
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control
|
||||||
|
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
|
||||||
|
nzSpan="8"
|
||||||
|
[nzErrorTip]="'validation.required' | i18n"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
nz-input
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[type]="paramDefine.type"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
/>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'textarea'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'textarea'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<textarea
|
||||||
|
nz-input
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
rows="3"
|
||||||
|
></textarea>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'password'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-input-group [nzSuffix]="suffixTemplate" style="width: 100%">
|
||||||
|
<input
|
||||||
|
[type]="passwordVisible ? 'text' : 'password'"
|
||||||
|
nz-input
|
||||||
|
placeholder="input password"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
/>
|
||||||
|
</nz-input-group>
|
||||||
|
<ng-template #suffixTemplate>
|
||||||
|
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i>
|
||||||
|
</ng-template>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'number'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-input-number
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[nzMin]="-1000"
|
||||||
|
[nzMax]="65535"
|
||||||
|
[nzStep]="1"
|
||||||
|
[nzPlaceHolder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
></nz-input-number>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'boolean'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-switch
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
></nz-switch>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label *ngIf="paramDefine.type === 'radio'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<nz-radio-group
|
||||||
|
[(ngModel)]="advancedParams[i].value"
|
||||||
|
[required]="paramDefine.required"
|
||||||
|
nzButtonStyle="solid"
|
||||||
|
[name]="paramDefine.field"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
>
|
||||||
|
<label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options">
|
||||||
|
{{ optionItem.label }}
|
||||||
|
</label>
|
||||||
|
</nz-radio-group>
|
||||||
|
</nz-form-control>
|
||||||
|
|
||||||
|
<nz-form-label
|
||||||
|
*ngIf="paramDefine.type === 'key-value'"
|
||||||
|
nzSpan="7"
|
||||||
|
[nzRequired]="paramDefine.required"
|
||||||
|
[nzFor]="paramDefine.field"
|
||||||
|
>{{ paramDefine.name }}
|
||||||
|
</nz-form-label>
|
||||||
|
<nz-form-control *ngIf="paramDefine.type === 'key-value'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
|
||||||
|
<app-key-value-input
|
||||||
|
[(value)]="advancedParams[i].value"
|
||||||
|
[id]="paramDefine.field"
|
||||||
|
keyAlias="Header Name"
|
||||||
|
valueAlias="Header Value"
|
||||||
|
></app-key-value-input>
|
||||||
|
</nz-form-control>
|
||||||
|
</nz-form-item>
|
||||||
|
</nz-collapse-panel>
|
||||||
|
</nz-collapse>
|
||||||
|
<ng-template #extraColHeader>
|
||||||
|
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
|
||||||
|
<span>高级设置</span>
|
||||||
|
<i nz-icon nzType="down-circle" nzTheme="outline"></i>
|
||||||
|
</button>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<nz-divider></nz-divider>
|
<nz-divider></nz-divider>
|
||||||
|
|
||||||
<nz-form-item>
|
<nz-form-item>
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import { MonitorService } from '../../../service/monitor.service';
|
|||||||
export class MonitorNewComponent implements OnInit {
|
export class MonitorNewComponent implements OnInit {
|
||||||
paramDefines!: ParamDefine[];
|
paramDefines!: ParamDefine[];
|
||||||
params!: Param[];
|
params!: Param[];
|
||||||
|
advancedParamDefines!: ParamDefine[];
|
||||||
|
advancedParams!: Param[];
|
||||||
monitor!: Monitor;
|
monitor!: Monitor;
|
||||||
detected: boolean = true;
|
detected: boolean = true;
|
||||||
passwordVisible: boolean = false;
|
passwordVisible: boolean = false;
|
||||||
@@ -53,9 +55,11 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
)
|
)
|
||||||
.subscribe(message => {
|
.subscribe(message => {
|
||||||
if (message.code === 0) {
|
if (message.code === 0) {
|
||||||
this.paramDefines = message.data;
|
|
||||||
this.params = [];
|
this.params = [];
|
||||||
this.paramDefines.forEach(define => {
|
this.advancedParams = [];
|
||||||
|
this.paramDefines = [];
|
||||||
|
this.advancedParamDefines = [];
|
||||||
|
message.data.forEach(define => {
|
||||||
let param = new Param();
|
let param = new Param();
|
||||||
param.field = define.field;
|
param.field = define.field;
|
||||||
if (define.type === 'number') {
|
if (define.type === 'number') {
|
||||||
@@ -77,7 +81,13 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
param.value = define.defaultValue;
|
param.value = define.defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (define.hide) {
|
||||||
|
this.advancedParams.push(param);
|
||||||
|
this.advancedParamDefines.push(define);
|
||||||
|
} else {
|
||||||
this.params.push(param);
|
this.params.push(param);
|
||||||
|
this.paramDefines.push(define);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn(message.msg);
|
console.warn(message.msg);
|
||||||
@@ -89,6 +99,21 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
this.monitor.name = `${this.monitor.app.toUpperCase()}_${hostValue}`;
|
this.monitor.name = `${this.monitor.app.toUpperCase()}_${hostValue}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onParamBooleanChanged(booleanValue: boolean, field: string) {
|
||||||
|
// 对SSL的端口联动处理, 不开启SSL默认80端口,开启SSL默认443
|
||||||
|
if (field === 'ssl') {
|
||||||
|
this.params.forEach(param => {
|
||||||
|
if (param.field === 'port') {
|
||||||
|
if (booleanValue) {
|
||||||
|
param.value = '443';
|
||||||
|
} else {
|
||||||
|
param.value = '80';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit(formGroup: FormGroup) {
|
onSubmit(formGroup: FormGroup) {
|
||||||
if (formGroup.invalid) {
|
if (formGroup.invalid) {
|
||||||
Object.values(formGroup.controls).forEach(control => {
|
Object.values(formGroup.controls).forEach(control => {
|
||||||
@@ -110,10 +135,15 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
param.value = (param.value as string).trim();
|
param.value = (param.value as string).trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.advancedParams.forEach(param => {
|
||||||
|
if (param.value != null && typeof param.value == 'string') {
|
||||||
|
param.value = (param.value as string).trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
let addMonitor = {
|
let addMonitor = {
|
||||||
detected: this.detected,
|
detected: this.detected,
|
||||||
monitor: this.monitor,
|
monitor: this.monitor,
|
||||||
params: this.params
|
params: this.params.concat(this.advancedParams)
|
||||||
};
|
};
|
||||||
this.isSpinning = true;
|
this.isSpinning = true;
|
||||||
this.monitorSvc.newMonitor(addMonitor).subscribe(
|
this.monitorSvc.newMonitor(addMonitor).subscribe(
|
||||||
@@ -154,10 +184,15 @@ export class MonitorNewComponent implements OnInit {
|
|||||||
param.value = (param.value as string).trim();
|
param.value = (param.value as string).trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.advancedParams.forEach(param => {
|
||||||
|
if (param.value != null && typeof param.value == 'string') {
|
||||||
|
param.value = (param.value as string).trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
let detectMonitor = {
|
let detectMonitor = {
|
||||||
detected: true,
|
detected: true,
|
||||||
monitor: this.monitor,
|
monitor: this.monitor,
|
||||||
params: this.params
|
params: this.params.concat(this.advancedParams)
|
||||||
};
|
};
|
||||||
this.isSpinning = true;
|
this.isSpinning = true;
|
||||||
this.monitorSvc.detectMonitor(detectMonitor).subscribe(
|
this.monitorSvc.detectMonitor(detectMonitor).subscribe(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { MonitorEditComponent } from './monitor-edit/monitor-edit.component';
|
|||||||
import { MonitorListComponent } from './monitor-list/monitor-list.component';
|
import { MonitorListComponent } from './monitor-list/monitor-list.component';
|
||||||
import { MonitorNewComponent } from './monitor-new/monitor-new.component';
|
import { MonitorNewComponent } from './monitor-new/monitor-new.component';
|
||||||
import { MonitorRoutingModule } from './monitor-routing.module';
|
import { MonitorRoutingModule } from './monitor-routing.module';
|
||||||
|
import { NzCollapseModule } from 'ng-zorro-antd/collapse';
|
||||||
|
|
||||||
const COMPONENTS: Array<Type<void>> = [
|
const COMPONENTS: Array<Type<void>> = [
|
||||||
MonitorNewComponent,
|
MonitorNewComponent,
|
||||||
@@ -37,7 +38,8 @@ const COMPONENTS: Array<Type<void>> = [
|
|||||||
NzRadioModule,
|
NzRadioModule,
|
||||||
NgxEchartsModule,
|
NgxEchartsModule,
|
||||||
NzLayoutModule,
|
NzLayoutModule,
|
||||||
NzSpaceModule
|
NzSpaceModule,
|
||||||
|
NzCollapseModule
|
||||||
],
|
],
|
||||||
declarations: COMPONENTS
|
declarations: COMPONENTS
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
.dynamic-button {
|
.dynamic-button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 4px;
|
top: 20%;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
margin-left: 6%;
|
margin-left: 12%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dynamic-button:hover {
|
.dynamic-button:hover {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"name": "TANCLOUD",
|
"name": "HertzBeat",
|
||||||
"description": "易用友好的高性能监控云"
|
"description": "易用友好的高性能监控云"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 8.9 KiB |
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>TanCloud</title>
|
<title>HertzBeat</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
|||||||