Compare commits

..

11 Commits

Author SHA1 Message Date
tomsun28
0281e5f0c2 [web-app]i18n for notify 2022-04-11 22:58:22 +08:00
tomsun28
89efd96448 [web-app]i18n for alert setting 2022-04-11 22:35:36 +08:00
tomsun28
1126d2e41e [web-app]i18n for alert notice 2022-04-11 18:11:54 +08:00
tomsun28
b78f463ed1 [web-app]i18n for alert center 2022-04-11 13:21:22 +08:00
tomsun28
2de1aa4069 [web-app]i18n for login 2022-04-11 11:42:48 +08:00
tomsun28
95a062eff4 [web-app]i18n for monitor detail 2022-04-11 11:15:35 +08:00
tomsun28
7fbf112240 [web-app]i18n for add edit monitor 2022-04-11 10:13:31 +08:00
tomsun28
a3d1f08b39 [web-app]i18n for monitor list 2022-04-11 08:06:55 +08:00
tomsun28
f685298741 [web-app]dashboard and monitor list i18n 2022-04-10 22:14:20 +08:00
tomsun28
a7658624ab [docs]support en webapp 2022-04-10 19:15:42 +08:00
tomsun28
69af6d2a12 [docs]support en docs 2022-04-10 17:14:05 +08:00
60 changed files with 468 additions and 1065 deletions

View File

@@ -62,8 +62,6 @@
- 如果您不想部署而是直接使用我们提供SAAS监控云-[TanCloud探云](https://console.tancloud.cn),即刻 **[登录注册](https://console.tancloud.cn)** 免费使用。 - 如果您不想部署而是直接使用我们提供SAAS监控云-[TanCloud探云](https://console.tancloud.cn),即刻 **[登录注册](https://console.tancloud.cn)** 免费使用。
- 如果您是想将HertzBeat部署到内网环境搭建监控系统请参考下面的 [部署文档](https://hertzbeat.com/docs/start/quickstart) 进行操作。 - 如果您是想将HertzBeat部署到内网环境搭建监控系统请参考下面的 [部署文档](https://hertzbeat.com/docs/start/quickstart) 进行操作。
安装部署视频教程: [HertzBeat安装部署-BiliBili](https://www.bilibili.com/video/BV1GY41177YL)
### 🐵 依赖服务部署 ### 🐵 依赖服务部署
> HertzBeat最少依赖于 关系型数据库[MYSQL5+](https://www.mysql.com/) 和 时序性数据库[TDengine2+](https://www.taosdata.com/getting-started) > HertzBeat最少依赖于 关系型数据库[MYSQL5+](https://www.mysql.com/) 和 时序性数据库[TDengine2+](https://www.taosdata.com/getting-started)

View File

@@ -1,12 +1,10 @@
package com.usthe.alert; package com.usthe.alert;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* 数据仓储配置属性 * 数据仓储配置属性
*
* @author tom * @author tom
* @date 2021/11/24 10:38 * @date 2021/11/24 10:38
*/ */
@@ -14,22 +12,11 @@ import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "alerter") @ConfigurationProperties(prefix = "alerter")
public class AlerterProperties { public class AlerterProperties {
private String consoleUrl = "https://console.tancloud.cn";
public String getConsoleUrl() {
return consoleUrl;
}
public void setConsoleUrl(String url) {
this.consoleUrl = url;
}
/** /**
* 数据入口配置属性 * 数据入口配置属性
*/ */
private EntranceProperties entrance; private EntranceProperties entrance;
public EntranceProperties getEntrance() { public EntranceProperties getEntrance() {
return entrance; return entrance;
} }
@@ -38,7 +25,6 @@ public class AlerterProperties {
this.entrance = entrance; this.entrance = entrance;
} }
/** /**
* 数据入口配置属性 * 数据入口配置属性
* 入口可以是从kafka rabbitmq rocketmq等消息中间件获取数据 * 入口可以是从kafka rabbitmq rocketmq等消息中间件获取数据
@@ -112,5 +98,4 @@ public class AlerterProperties {
} }
} }

View File

@@ -30,12 +30,11 @@ import java.util.List;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/** /**
* Alarm Management API 告警管理API * 告警管理API
*
* @author tom * @author tom
* @date 2021/12/9 10:32 * @date 2021/12/9 10:32
*/ */
@Api(tags = "en: Alarm batch management API, zh:告警批量管理API") @Api(tags = "告警批量管理API")
@RestController @RestController
@RequestMapping(path = "/alerts", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/alerts", produces = {APPLICATION_JSON_VALUE})
public class AlertsController { public class AlertsController {
@@ -44,23 +43,23 @@ public class AlertsController {
private AlertService alertService; private AlertService alertService;
@GetMapping @GetMapping
@ApiOperation(value = "Get a list of alarm information based on query filter items", notes = "根据查询过滤项获取告警信息列表") @ApiOperation(value = "查询告警列表", notes = "根据查询过滤项获取告警信息列表")
public ResponseEntity<Message<Page<Alert>>> getAlerts( public ResponseEntity<Message<Page<Alert>>> getAlerts(
@ApiParam(value = "en: Alarm ID List,zh: 告警IDS", example = "6565466456") @RequestParam(required = false) List<Long> ids, @ApiParam(value = "告警ID", example = "6565466456") @RequestParam(required = false) List<Long> ids,
@ApiParam(value = "en: Alarm monitor object ID,zh: 告警监控对象ID", example = "6565463543") @RequestParam(required = false) Long monitorId, @ApiParam(value = "告警监控对象ID", example = "6565463543") @RequestParam(required = false) Long monitorId,
@ApiParam(value = "en: Alarm level,zh: 告警级别", example = "6565463543") @RequestParam(required = false) Byte priority, @ApiParam(value = "告警级别", example = "6565463543") @RequestParam(required = false) Byte priority,
@ApiParam(value = "en: Alarm Status,zh: 告警状态", example = "6565463543") @RequestParam(required = false) Byte status, @ApiParam(value = "告警状态", example = "6565463543") @RequestParam(required = false) Byte status,
@ApiParam(value = "en: Alarm content fuzzy query,zh:告警内容模糊查询", example = "linux") @RequestParam(required = false) String content, @ApiParam(value = "告警内容模糊查询", example = "linux") @RequestParam(required = false) String content,
@ApiParam(value = "en: Sort field, default id,zh: 排序字段默认id", example = "name") @RequestParam(defaultValue = "id") String sort, @ApiParam(value = "排序字段默认id", example = "name") @RequestParam(defaultValue = "id") String sort,
@ApiParam(value = "en: Sort Type,zh: 排序方式asc:升序desc:降序", example = "desc") @RequestParam(defaultValue = "desc") String order, @ApiParam(value = "排序方式asc:升序desc:降序", example = "desc") @RequestParam(defaultValue = "desc") String order,
@ApiParam(value = "en: List current page,zh: 列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex, @ApiParam(value = "列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
@ApiParam(value = "en: Number of list pagination,zh: 列表分页数量", example = "8") @RequestParam(defaultValue = "8") int pageSize) { @ApiParam(value = "列表分页数量", 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);
} }
@@ -93,9 +92,10 @@ public class AlertsController {
} }
@DeleteMapping @DeleteMapping
@ApiOperation(value = "Delete alarms in batches", notes = "根据告警ID列表批量删除告警") @ApiOperation(value = "批量删除告警", notes = "根据告警ID列表批量删除告警")
public ResponseEntity<Message<Void>> deleteAlertDefines( public ResponseEntity<Message<Void>> deleteAlertDefines(
@ApiParam(value = "en:Alarm List ID,zh: 告警IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids) { @ApiParam(value = "告警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 = "Batch modify alarm status, set read and unread", notes = "批量修改告警状态,设置已读未读") @ApiOperation(value = "批量修改告警状态", notes = "批量修改告警状态,设置已读未读")
public ResponseEntity<Message<Void>> applyAlertDefinesStatus( public ResponseEntity<Message<Void>> applyAlertDefinesStatus(
@ApiParam(value = "en:Alarm status value,zh: 告警状态值", example = "0") @PathVariable Byte status, @ApiParam(value = "告警状态值", example = "0") @PathVariable Byte status,
@ApiParam(value = "en:Alarm List IDS,zh: 告警IDS", example = "6565463543") @RequestParam(required = false) List<Long> ids) { @ApiParam(value = "告警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 = "Get alarm statistics", notes = "获取告警统计信息") @ApiOperation(value = "获取告警统计信息", 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);

View File

@@ -12,35 +12,30 @@ import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Alert Database Operations Alert数据库操作 * 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> {
/** /**
* Delete alerts based on ID list 根据ID列表删除告警 * 根据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列表
*/ */
@Modifying @Modifying
@Query("update Alert set status = :status where id in :ids") @Query("update Alert set status = :status where id in :ids")
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();

View File

@@ -7,43 +7,34 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List; import java.util.List;
/** /**
* AlertDefineBind database operations 数据库操作 * AlertDefineBind 数据库操作
*
* @author tom * @author tom
* @date 2021/12/9 10:03 * @date 2021/12/9 10:03
*/ */
public interface AlertDefineBindDao extends JpaRepository<AlertDefineMonitorBind, Long>, JpaSpecificationExecutor<AlertDefineMonitorBind> { public interface AlertDefineBindDao extends JpaRepository<AlertDefineMonitorBind, Long>, JpaSpecificationExecutor<AlertDefineMonitorBind> {
/** /**
* Delete the alarm definition and monitor association based on the alarm definition ID
* 根据告警定义ID删除告警定义与监控关联 * 根据告警定义ID删除告警定义与监控关联
* * @param alertDefineId 告警定义ID
* @param alertDefineId Alarm Definition ID 告警定义ID
*/ */
void deleteAlertDefineBindsByAlertDefineIdEquals(Long alertDefineId); void deleteAlertDefineBindsByAlertDefineIdEquals(Long alertDefineId);
/** /**
* Deleting alarms based on monitoring IDs defines monitoring associations
* 根据监控ID删除告警定义监控关联 * 根据监控ID删除告警定义监控关联
* * @param monitorId 监控ID
* @param monitorId Monitor Id 监控ID
*/ */
void deleteAlertDefineMonitorBindsByMonitorIdEquals(Long monitorId); void deleteAlertDefineMonitorBindsByMonitorIdEquals(Long monitorId);
/** /**
* Delete alarm definition monitoring association based on monitoring ID list
* 根据监控ID列表删除告警定义监控关联 * 根据监控ID列表删除告警定义监控关联
* * @param monitorIds 监控ID列表
* @param monitorIds Monitoring ID List 监控ID列表
*/ */
void deleteAlertDefineMonitorBindsByMonitorIdIn(List<Long> monitorIds); void deleteAlertDefineMonitorBindsByMonitorIdIn(List<Long> monitorIds);
/** /**
* Query monitoring related information based on alarm definition ID
* 根据告警定义ID查询监控关联信息 * 根据告警定义ID查询监控关联信息
* * @param alertDefineId 告警定义ID
* @param alertDefineId Alarm Definition ID 告警定义ID * @return 关联监控信息
* @return Associated monitoring information 关联监控信息
*/ */
List<AlertDefineMonitorBind> getAlertDefineBindsByAlertDefineIdEquals(Long alertDefineId); List<AlertDefineMonitorBind> getAlertDefineBindsByAlertDefineIdEquals(Long alertDefineId);
} }

View File

@@ -4,8 +4,7 @@ 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
*/ */
@@ -13,13 +12,7 @@ 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;
} }

View File

@@ -9,43 +9,31 @@ 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 = "en:Alarm Statistics Information,zh: 告警统计信息") @ApiModel(description = "告警统计信息")
public class AlertSummary { public class AlertSummary {
@ApiModelProperty(value = "Total number of alerts (including processed and unprocessed alerts)", @ApiModelProperty(value = "告警总数量(包括已处理未处理告警)", example = "134", accessMode = READ_ONLY, position = 0)
notes = "告警总数量(包括已处理未处理告警)",
example = "134", accessMode = READ_ONLY, position = 0)
private long total; private long total;
@ApiModelProperty(value = "Number of alerts handled", @ApiModelProperty(value = "已处理告警数量", example = "34", accessMode = READ_ONLY, position = 1)
notes = "已处理告警数量",
example = "34", accessMode = READ_ONLY, position = 1)
private long dealNum; private long dealNum;
@ApiModelProperty(value = "Alarm handling rate", @ApiModelProperty(value = "告警处理率", example = "39.34", accessMode = READ_ONLY, position = 2)
notes = "告警处理率",
example = "39.34", accessMode = READ_ONLY, position = 2)
private float rate; private float rate;
@ApiModelProperty(value = "Number of alarms whose alarm severity is warning alarms (referring to unhandled alarms)", @ApiModelProperty(value = "告警级别为警告告警的告警数量(指未处理告警)", example = "43", accessMode = READ_ONLY, position = 3)
notes = "告警级别为警告告警的告警数量(指未处理告警)",
example = "43", accessMode = READ_ONLY, position = 3)
private long priorityWarningNum; private long priorityWarningNum;
@ApiModelProperty(value = "Number of alarms whose alarm severity is critical alarms (referring to unhandled alarms)", @ApiModelProperty(value = "告警级别为严重告警的告警数量(指未处理告警)", example = "56", accessMode = READ_ONLY, position = 4)
notes = "告警级别为严重告警的告警数量(指未处理告警)",
example = "56", accessMode = READ_ONLY, position = 4)
private long priorityCriticalNum; private long priorityCriticalNum;
@ApiModelProperty(value = "Number of alarms whose alarm severity is urgent alarms (referring to unhandled alarms)", @ApiModelProperty(value = "告警级别为紧急告警的告警数量(指未处理告警)", example = "23", accessMode = READ_ONLY, position = 5)
notes = "告警级别为紧急告警的告警数量(指未处理告警)", example = "23", accessMode = READ_ONLY, position = 5)
private long priorityEmergencyNum; private long priorityEmergencyNum;
} }

View File

@@ -10,54 +10,43 @@ 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 specification Query conditions 查询条件 * @param pageRequest 分页参数
* @param pageRequest pagination parameters 分页参数 * @return 查询结果
* @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 status Alarm status to be modified 待修改的告警状态 * @param ids 待修改的告警IDs
* @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();

View File

@@ -20,8 +20,7 @@ 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
*/ */
@@ -56,24 +55,18 @@ 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()); alertSummary.setPriorityWarningNum(priorityNum.getNum());break;
break;
case CommonConstants.ALERT_PRIORITY_CODE_CRITICAL: case CommonConstants.ALERT_PRIORITY_CODE_CRITICAL:
alertSummary.setPriorityCriticalNum(priorityNum.getNum()); alertSummary.setPriorityCriticalNum(priorityNum.getNum());break;
break;
case CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY: case CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY:
alertSummary.setPriorityEmergencyNum(priorityNum.getNum()); alertSummary.setPriorityEmergencyNum(priorityNum.getNum());break;
break; default: break;
default:
break;
} }
} }
} }

View File

@@ -115,11 +115,6 @@
<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>

View File

@@ -15,7 +15,6 @@ import java.util.concurrent.TimeUnit;
/** /**
* 采集job管理提供api接口 * 采集job管理提供api接口
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/6 13:58 * @date 2021/11/6 13:58
*/ */
@@ -27,11 +26,9 @@ public class CollectJobService {
private TimerDispatch timerDispatch; private TimerDispatch timerDispatch;
/** /**
* Execute a one-time collection task and get the collected data response
* 执行一次性采集任务,获取采集数据响应 * 执行一次性采集任务,获取采集数据响应
* * @param job 采集任务详情
* @param job Collect task details 采集任务详情 * @return 采集结果
* @return Collection results 采集结果
*/ */
public List<CollectRep.MetricsData> collectSyncJobData(Job job) { public List<CollectRep.MetricsData> collectSyncJobData(Job job) {
final List<CollectRep.MetricsData> metricsData = new LinkedList<>(); final List<CollectRep.MetricsData> metricsData = new LinkedList<>();
@@ -55,11 +52,9 @@ public class CollectJobService {
} }
/** /**
* Issue periodic asynchronous collection tasks
* 下发周期性异步采集任务 * 下发周期性异步采集任务
* * @param job 采集任务详情
* @param job Collect task details 采集任务详情 * @return long 任务ID
* @return long Job ID 任务ID
*/ */
public long addAsyncCollectJob(Job job) { public long addAsyncCollectJob(Job job) {
if (job.getId() == 0L) { if (job.getId() == 0L) {
@@ -71,10 +66,8 @@ public class CollectJobService {
} }
/** /**
* Update the periodic asynchronous collection tasks that have been delivered
* 更新已经下发的周期性异步采集任务 * 更新已经下发的周期性异步采集任务
* * @param modifyJob 采集任务详情
* @param modifyJob Collect task details 采集任务详情
*/ */
public void updateAsyncCollectJob(Job modifyJob) { public void updateAsyncCollectJob(Job modifyJob) {
timerDispatch.deleteJob(modifyJob.getId(), true); timerDispatch.deleteJob(modifyJob.getId(), true);
@@ -82,10 +75,8 @@ public class CollectJobService {
} }
/** /**
* Cancel periodic asynchronous collection tasks
* 取消周期性异步采集任务 * 取消周期性异步采集任务
* * @param jobId 任务ID
* @param jobId Job ID 任务ID
*/ */
public void cancelAsyncCollectJob(Long jobId) { public void cancelAsyncCollectJob(Long jobId) {
timerDispatch.deleteJob(jobId, true); timerDispatch.deleteJob(jobId, true);

View File

@@ -10,44 +10,36 @@ import java.util.concurrent.TimeUnit;
/** /**
* 时间轮调度接口 * 时间轮调度接口
*
* @author tomsun28 * @author tomsun28
* @date 2021/10/17 22:14 * @date 2021/10/17 22:14
*/ */
public interface TimerDispatch { public interface TimerDispatch {
/** /**
* Add new job
* 增加新的job * 增加新的job
* * @param addJob job
* @param addJob job * @param eventListener 一次性同步任务监听器异步任务不需要listener
* @param eventListener One-time synchronous task listener, asynchronous task does not need listener一次性同步任务监听器异步任务不需要listener
*/ */
void addJob(Job addJob, CollectResponseEventListener eventListener); void addJob(Job addJob, CollectResponseEventListener eventListener);
/** /**
* 调度循环周期性job * 调度循环周期性job
*
* @param timerTask timerTask * @param timerTask timerTask
* @param interval 开始调度的间隔时间 * @param interval 开始调度的间隔时间
* @param timeUnit 时间单位 * @param timeUnit 时间单位
*/ */
void cyclicJob(WheelTimerTask timerTask, long interval, TimeUnit timeUnit); void cyclicJob(WheelTimerTask timerTask, long interval, TimeUnit timeUnit);
/** /**
* Delete existing job
* 删除存在的job * 删除存在的job
* * @param jobId jobId
* @param jobId jobId * @param isCyclic 是否是周期性任务,true是, false为临时性任务
* @param isCyclic Whether it is a periodic task, true is, false is a temporary task
* 是否是周期性任务,true是, false为临时性任务
*/ */
void deleteJob(long jobId, boolean isCyclic); void deleteJob(long jobId, boolean isCyclic);
/** /**
* 一次性同步采集任务采集结果通知监听器 * 一次性同步采集任务采集结果通知监听器
* * @param jobId jobId
* @param jobId jobId
* @param metricsDataTemps 采集结果数据 * @param metricsDataTemps 采集结果数据
*/ */
void responseSyncJobData(long jobId, List<CollectRep.MetricsData> metricsDataTemps); void responseSyncJobData(long jobId, List<CollectRep.MetricsData> metricsDataTemps);

View File

@@ -18,22 +18,18 @@ import java.util.concurrent.TimeUnit;
public class TimerDispatcher implements TimerDispatch { public class TimerDispatcher implements TimerDispatch {
/** /**
* time round schedule
* 时间轮调度 * 时间轮调度
*/ */
private Timer wheelTimer; private Timer wheelTimer;
/** /**
* Existing periodic scheduled tasks
* 已存在的周期性调度任务 * 已存在的周期性调度任务
*/ */
private Map<Long, Timeout> currentCyclicTaskMap; private Map<Long, Timeout> currentCyclicTaskMap;
/** /**
* Existing temporary scheduled tasks
* 已存在的临时性调度任务 * 已存在的临时性调度任务
*/ */
private Map<Long, Timeout> currentTempTaskMap; private Map<Long, Timeout> currentTempTaskMap;
/** /**
* One-time task response listener holds
* 一次性任务响应监听器持有 * 一次性任务响应监听器持有
* jobId - listener * jobId - listener
*/ */

View File

@@ -22,9 +22,7 @@ import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* Timer Task implementation
* TimerTask实现 * TimerTask实现
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/1 17:18 * @date 2021/11/1 17:18
*/ */
@@ -38,15 +36,12 @@ public class WheelTimerTask implements TimerTask {
public WheelTimerTask(Job job) { public WheelTimerTask(Job job) {
this.metricsTaskDispatch = SpringContextHolder.getBean(MetricsTaskDispatch.class); this.metricsTaskDispatch = SpringContextHolder.getBean(MetricsTaskDispatch.class);
this.job = job; this.job = job;
// The initialization job will monitor the actual parameter value and replace the collection field
// 初始化job 将监控实际参数值对采集字段进行替换 // 初始化job 将监控实际参数值对采集字段进行替换
initJobMetrics(job); initJobMetrics(job);
} }
/** /**
* Initialize job fill information
* 初始化job填充信息 * 初始化job填充信息
*
* @param job job * @param job job
*/ */
private void initJobMetrics(Job job) { private void initJobMetrics(Job job) {
@@ -78,10 +73,9 @@ public class WheelTimerTask implements TimerTask {
} }
/** /**
* json parameter replacement json参数替换 * json参数替换
*
* @param jsonElement json * @param jsonElement json
* @param configmap parameter map 参数map * @param configmap 参数map
* @return json * @return json
*/ */
private JsonElement replaceSpecialValue(JsonElement jsonElement, Map<String, Configmap> configmap) { private JsonElement replaceSpecialValue(JsonElement jsonElement, Map<String, Configmap> configmap) {
@@ -92,29 +86,26 @@ public class WheelTimerTask implements TimerTask {
Map.Entry<String, JsonElement> entry = iterator.next(); Map.Entry<String, JsonElement> entry = iterator.next();
JsonElement element = entry.getValue(); JsonElement element = entry.getValue();
String key = entry.getKey(); String key = entry.getKey();
// Replace the attributes of the KEY-VALUE case such as http headers params
// 替换KEY-VALUE情况的属性 比如http headers params // 替换KEY-VALUE情况的属性 比如http headers params
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 != null && 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) {
map.forEach((name, value) -> { map.forEach((name, value) -> {
if (name != null && !"".equals(name.trim())) { if (name != null && !"".equals(name.trim())) {
jsonObject.addProperty(name, value); jsonObject.addProperty(name, value);
} }
}); });
} }
} }
iterator.remove(); iterator.remove();
continue; continue;
} }
// Replace normal VALUE value
// 替换正常的VALUE值 // 替换正常的VALUE值
if (element.isJsonPrimitive()) { if (element.isJsonPrimitive()) {
// Check if there are special characters Replace
// 判断是否含有特殊字符 替换 // 判断是否含有特殊字符 替换
String value = element.getAsString(); String value = element.getAsString();
if (value.startsWith("^_^") && value.endsWith("^_^")) { if (value.startsWith("^_^") && value.endsWith("^_^")) {
@@ -138,7 +129,6 @@ public class WheelTimerTask implements TimerTask {
while (iterator.hasNext()) { while (iterator.hasNext()) {
JsonElement element = iterator.next(); JsonElement element = iterator.next();
if (element.isJsonPrimitive()) { if (element.isJsonPrimitive()) {
// Check if there are special characters Replace
// 判断是否含有特殊字符 替换 // 判断是否含有特殊字符 替换
String value = element.getAsString(); String value = element.getAsString();
if (value.startsWith("^_^") && value.endsWith("^_^")) { if (value.startsWith("^_^") && value.endsWith("^_^")) {

View File

@@ -23,8 +23,7 @@ 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
*/ */
@@ -34,68 +33,52 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(description = "en: Alarm record entity zh: 告警记录实体") @ApiModel(description = "告警记录实体")
public class Alert { public class Alert {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "Alarm record entity primary key index ID", @ApiModelProperty(value = "告警记录实体主键索引ID", example = "87584674384", accessMode = READ_ONLY, position = 0)
notes = "告警记录实体主键索引ID",
example = "87584674384", accessMode = READ_ONLY, position = 0)
private Long id; private Long id;
@ApiModelProperty(value = "Alert target object: monitor availability-available metrics-app.metrics.field", @ApiModelProperty(value = "告警目标对象: 监控可用性-available 指标-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 = "Monitoring ID associated with the alarm object", @ApiModelProperty(value = "告警对象关联的监控ID", example = "87432674336", accessMode = READ_WRITE, position = 2)
notes = "告警对象关联的监控ID",
example = "87432674336", accessMode = READ_WRITE, position = 2)
private Long monitorId; private Long monitorId;
@ApiModelProperty(value = "Monitoring name associated with the alarm object", @ApiModelProperty(value = "告警对象关联的监控名称", example = "Linux_192.132.23.1",
notes = "告警对象关联的监控名称", accessMode = READ_WRITE, position = 3)
example = "Linux_192.132.23.1", accessMode = READ_WRITE, position = 3)
private String monitorName; private String monitorName;
@ApiModelProperty(value = "Alarm definition ID associated with the alarm", @ApiModelProperty(value = "告警关联的告警定义ID", example = "8743267443543", accessMode = READ_WRITE, position = 4)
notes = "告警关联的告警定义ID",
example = "8743267443543", accessMode = READ_WRITE, position = 4)
private Long alertDefineId; private Long alertDefineId;
@ApiModelProperty(value = "Alarm level 0: high-emergency-critical alarm-red 1: medium-critical-critical alarm-orange 2: low-warning-warning alarm-yellow", @ApiModelProperty(value = "告警级别 0:高-emergency-紧急告警-红色 1:中-critical-严重告警-橙色 2:低-warning-警告告警-黄色",
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 = "The actual content of the alarm notification", @ApiModelProperty(value = "告警通知实际内容", example = "linux_192.134.32.1: 534543534 cpu usage high",
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 = "Alarm status: 0-normal alarm (to be processed) 1-threshold triggered but not reached the number of alarms 2-recovered alarm 3-processed", @ApiModelProperty(value = "告警状态: 0-正常告警(待处理) 1-阈值触发但未达到告警次数 2-恢复告警 3-已处理",
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 = "Alarm threshold trigger times", @ApiModelProperty(value = "告警阈值触发次数", example = "3", accessMode = READ_WRITE, position = 8)
notes = "告警阈值触发次数",
example = "3", accessMode = READ_WRITE, position = 8)
@Min(0) @Min(0)
@Max(10) @Max(10)
private int times; private int times;
@ApiModelProperty(value = "Alarm trigger time (timestamp in milliseconds)", @ApiModelProperty(value = "告警触发时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 9)
notes = "告警触发时间(毫秒时间戳)",
example = "1612198922000", accessMode = READ_ONLY, position = 9)
@Column(insertable = false, updatable = false) @Column(insertable = false, updatable = false)
private LocalDateTime gmtCreate; private LocalDateTime gmtCreate;

View File

@@ -6,12 +6,8 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
/** /**
* Monitoring configuration parameter properties and values
* 监控配置参数属性及值 * 监控配置参数属性及值
* During the process, you need to replace the content with the identifier ^_^key^_^
* in the protocol configuration parameter with the real value in the configuration parameter
* 过程中需要将协议配置参数里面的标识符为^_^key^_^的内容替换为配置参数里的真实值 * 过程中需要将协议配置参数里面的标识符为^_^key^_^的内容替换为配置参数里的真实值
*
* @author tomsun28 * @author tomsun28
* @date 2021/10/29 22:04 * @date 2021/10/29 22:04
*/ */
@@ -22,20 +18,16 @@ import lombok.NoArgsConstructor;
public class Configmap { public class Configmap {
/** /**
* Parameter key, replace the content with the identifier ^^_key_^^ in the protocol
* configuration parameter with the real value in the configuration parameter
* <p>
* 参数key,将协议配置参数里面的标识符为^^_key_^^的内容替换为配置参数里的真实值 * 参数key,将协议配置参数里面的标识符为^^_key_^^的内容替换为配置参数里的真实值
*/ */
private String key; private String key;
/** /**
* parameter value 参数value * 参数value
*/ */
private Object value; private Object value;
/** /**
* Parameter type 0: number 1: string 2: encrypted string 3: json string mapped by map
* 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串 * 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串
* number,string,secret * number,string,secret
* 数字,非加密字符串,加密字符串 * 数字,非加密字符串,加密字符串

View File

@@ -21,9 +21,7 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* Collect task details
* 采集任务详情 * 采集任务详情
*
* @author tomsun28 * @author tomsun28
* @date 2021/10/17 21:19 * @date 2021/10/17 21:19
*/ */
@@ -37,72 +35,61 @@ public class Job {
private static final String AVAILABILITY = "availability"; private static final String AVAILABILITY = "availability";
/** /**
* Task id 任务ID * 任务ID
*/ */
private long id; private long id;
/** /**
* Monitoring ID Application ID
* 监控ID 应用ID * 监控ID 应用ID
*/ */
private long monitorId; private long monitorId;
/** /**
* Large categories of monitoring 监控的大类别 * 监控的大类别
* service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
* service-应用服务监控 db-数据库监控 custom-自定义监控 os-操作系统监控 * service-应用服务监控 db-数据库监控 custom-自定义监控 os-操作系统监控
*/ */
private String category; private String category;
/** /**
* Type of monitoring eg: linux | mysql | jvm
* 监控的类型 eg: linux | mysql | jvm * 监控的类型 eg: linux | mysql | jvm
*/ */
private String app; private String app;
/** /**
* The internationalized name of the monitoring type 监控类型的国际化名称 * 监控类型的国际化名称
* zh-CN: PING连通性 * zh-CN: PING连通性
* en-US: PING CONNECT * en-US: PING CONNECT
*/ */
private Map<String, String> name; private Map<String, String> name;
/** /**
* Task dispatch start timestamp
* 任务派发开始时间戳 * 任务派发开始时间戳
*/ */
private long timestamp; private long timestamp;
/** /**
* Task collection time interval (unit: second) eg: 30,60,600
* 任务采集时间间隔(单位秒) eg: 30,60,600 * 任务采集时间间隔(单位秒) eg: 30,60,600
*/ */
private long interval = 600L; private long interval = 600L;
/** /**
* Whether it is a recurring periodic task true is yes, false is no
* 是否是循环周期性任务 true为是,false为否 * 是否是循环周期性任务 true为是,false为否
*/ */
private boolean isCyclic = false; private boolean isCyclic = false;
/** /**
* Indicator group configuration eg: cpu memory
* 指标组配置 eg: cpu memory * 指标组配置 eg: cpu memory
*/ */
private List<Metrics> metrics; private List<Metrics> metrics;
/** /**
* Monitoring configuration parameter properties and values eg: username password timeout host
* 监控配置参数属性及值 eg: username password timeout host * 监控配置参数属性及值 eg: username password timeout host
*/ */
private List<Configmap> configmap; private List<Configmap> configmap;
/** /**
* collector use - timestamp when the task was scheduled by the time wheel
* collector使用 - 任务被时间轮开始调度的时间戳 * collector使用 - 任务被时间轮开始调度的时间戳
*/ */
@JsonIgnore @JsonIgnore
private transient long dispatchTime; private transient long dispatchTime;
/** /**
* collector use - task version, this field is not stored in etcd
* collector使用 - 任务版本,此字段不存储于etcd * collector使用 - 任务版本,此字段不存储于etcd
*/ */
@JsonIgnore @JsonIgnore
private transient long version; private transient long version;
/** /**
* collector usage - metric group task execution priority view
* collector使用 - 指标组任务执行优先级视图 * collector使用 - 指标组任务执行优先级视图
* 0 - availability * 0 - availability
* 1 - cpu | memory * 1 - cpu | memory
@@ -116,32 +103,27 @@ public class Job {
private transient List<Set<Metrics>> priorMetrics; private transient List<Set<Metrics>> priorMetrics;
/** /**
* collector use - Temporarily store one-time task indicator group response data
* collector使用 - 临时存储一次性任务指标组响应数据 * collector使用 - 临时存储一次性任务指标组响应数据
*/ */
@JsonIgnore @JsonIgnore
private transient List<CollectRep.MetricsData> responseDataTemp; private transient List<CollectRep.MetricsData> responseDataTemp;
/** /**
* collector uses - construct to initialize metrics group execution view
* collector使用 - 构造初始化指标组执行视图 * collector使用 - 构造初始化指标组执行视图
*/ */
public synchronized void constructPriorMetrics() { public synchronized void constructPriorMetrics() {
Map<Byte, List<Metrics>> map = metrics.stream() Map<Byte, List<Metrics>> map = metrics.stream()
.peek(metric -> { .peek(metric -> {
// Determine whether to configure aliasFields If not, configure the default
// 判断是否配置aliasFields 没有则配置默认 // 判断是否配置aliasFields 没有则配置默认
if (metric.getAliasFields() == null || metric.getAliasFields().isEmpty()) { if (metric.getAliasFields() == null || metric.getAliasFields().isEmpty()) {
metric.setAliasFields(metric.getFields().stream().map(Metrics.Field::getField).collect(Collectors.toList())); metric.setAliasFields(metric.getFields().stream().map(Metrics.Field::getField).collect(Collectors.toList()));
} }
// Set the default indicator group execution priority, if not filled, the default last priority
// 设置默认的指标组执行优先级,不填则默认最后优先级 // 设置默认的指标组执行优先级,不填则默认最后优先级
if (metric.getPriority() == null) { if (metric.getPriority() == null) {
metric.setPriority(Byte.MAX_VALUE); metric.setPriority(Byte.MAX_VALUE);
} }
}) })
.collect(Collectors.groupingBy(Metrics::getPriority)); .collect(Collectors.groupingBy(Metrics::getPriority));
// Construct a linked list of task execution order of the indicator group
// 构造指标组任务执行顺序链表 // 构造指标组任务执行顺序链表
priorMetrics = new LinkedList<>(); priorMetrics = new LinkedList<>();
map.values().forEach(metric -> { map.values().forEach(metric -> {
@@ -159,18 +141,12 @@ public class Job {
} }
/** /**
* collector use - to get the next set of priority metric group tasks
* collector使用 - 获取下一组优先级的指标组任务 * collector使用 - 获取下一组优先级的指标组任务
* * @param metrics 当前指标组
* @param metrics Current indicator group 当前指标组 * @param first 是否是第一次获取
* @param first Is it the first time to get 是否是第一次获取 * @return 指标组任务
* @return Metric Group Tasks 指标组任务
* Returning null means: the job has been completed, and the collection of all indicator groups has ended
* 返回null表示job已完成,所有指标组采集结束 * 返回null表示job已完成,所有指标组采集结束
* Returning the empty set indicates that there are still indicator group collection tasks at the current
* level that have not been completed,and the next level indicator group task collection cannot be performed.
* 返回empty的集合表示当前级别下还有指标组采集任务未结束,无法进行下一级别的指标组任务采集 * 返回empty的集合表示当前级别下还有指标组采集任务未结束,无法进行下一级别的指标组任务采集
* Returns a set of data representation: get the next set of priority index group tasks
* 返回有数据集合表示:获取到下一组优先级的指标组任务 * 返回有数据集合表示:获取到下一组优先级的指标组任务
*/ */
public synchronized Set<Metrics> getNextCollectMetrics(Metrics metrics, boolean first) { public synchronized Set<Metrics> getNextCollectMetrics(Metrics metrics, boolean first) {
@@ -213,7 +189,7 @@ public class Job {
@Override @Override
public Job clone() { public Job clone() {
// deep clone 深度克隆 // 深度克隆
return GsonUtil.fromJson(GsonUtil.toJson(this), Job.class); return GsonUtil.fromJson(GsonUtil.toJson(this), Job.class);
} }
} }

View File

@@ -15,10 +15,7 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
* Details of the collection of indicators collected by monitoring
* eg: cpu | memory | health
* 监控采集的指标集合详情 eg: cpu | memory | health * 监控采集的指标集合详情 eg: cpu | memory | health
*
* @author tomsun28 * @author tomsun28
* @date 2021/10/17 21:24 * @date 2021/10/17 21:24
*/ */
@@ -29,7 +26,6 @@ import java.util.Objects;
public class Metrics { public class Metrics {
/** /**
* public property-name eg: cpu | memory | health
* 公共属性-名称 eg: cpu | memory | health * 公共属性-名称 eg: cpu | memory | health
*/ */
private String name; private String name;
@@ -38,27 +34,20 @@ public class Metrics {
*/ */
private String protocol; private String protocol;
/** /**
* Range (0-127) indicator group scheduling priority, the smaller the value, the higher the priority
* The collection task of the next priority indicator group will be scheduled only after the scheduled collection with the higher priority is completed.
* The default priority of the availability indicator group is 0, and the range of other common indicator groups is 1-127, that is,
* the subsequent indicator group tasks will only be scheduled after the availability is collected successfully.
* 范围(0-127)指标组调度优先级,数值越小优先级越高 * 范围(0-127)指标组调度优先级,数值越小优先级越高
* 优先级高的调度采集完成后才会调度下一优先级的指标组采集任务 * 优先级高的调度采集完成后才会调度下一优先级的指标组采集任务
* 可用性指标组(availability)默认优先级为0,其它普通指标组范围为1-127,即需要等availability采集成功后才会调度后面的指标组任务 * 可用性指标组(availability)默认优先级为0,其它普通指标组范围为1-127,即需要等availability采集成功后才会调度后面的指标组任务
*/ */
private Byte priority; private Byte priority;
/** /**
* Public attribute - collection and monitoring final result attribute set eg: speed | times | size
* 公共属性-采集监控的最终结果属性集合 eg: speed | times | size * 公共属性-采集监控的最终结果属性集合 eg: speed | times | size
*/ */
private List<Field> fields; private List<Field> fields;
/** /**
* Public attribute - collection and monitoring pre-query attribute set eg: size1 | size2 | speedSize
* 公共属性-采集监控的前置查询属性集合 eg: size1 | size2 | speedSize * 公共属性-采集监控的前置查询属性集合 eg: size1 | size2 | speedSize
*/ */
private List<String> aliasFields; private List<String> aliasFields;
/** /**
* Public attribute - expression calculation, map the pre-query attribute (pre Fields) with the final attribute (fields), and calculate the final attribute (fields) value
* 公共属性-表达式计算,将前置查询属性(preFields)与最终属性(fields)映射,计算出最终属性(fields)值 * 公共属性-表达式计算,将前置查询属性(preFields)与最终属性(fields)映射,计算出最终属性(fields)值
* eg: size = size1 + size2, speed = speedSize * eg: size = size1 + size2, speed = speedSize
* https://www.yuque.com/boyan-avfmj/aviatorscript/ban32m * https://www.yuque.com/boyan-avfmj/aviatorscript/ban32m
@@ -66,32 +55,26 @@ public class Metrics {
private List<String> calculates; private List<String> calculates;
/** /**
* Monitoring configuration information using the http protocol
* 使用http协议的监控配置信息 * 使用http协议的监控配置信息
*/ */
private HttpProtocol http; private HttpProtocol http;
/** /**
* Monitoring configuration information for ping using the icmp protocol
* 使用icmp协议进行ping的监控配置信息 * 使用icmp协议进行ping的监控配置信息
*/ */
private IcmpProtocol icmp; private IcmpProtocol icmp;
/** /**
* Monitoring configuration information using the telnet protocol
* 使用telnet协议的监控配置信息 * 使用telnet协议的监控配置信息
*/ */
private TelnetProtocol telnet; private TelnetProtocol telnet;
/** /**
* Use tcp or ucp implemented by socket for service port detection configuration information
* 使用socket实现的tcp或ucp进行服务端口探测配置信息 * 使用socket实现的tcp或ucp进行服务端口探测配置信息
*/ */
private TcpUdpProtocol tcpUdp; private TcpUdpProtocol tcpUdp;
/** /**
* Database configuration information implemented using the public jdbc specification
* 使用公共的jdbc规范实现的数据库配置信息 * 使用公共的jdbc规范实现的数据库配置信息
*/ */
private JdbcProtocol jdbc; private JdbcProtocol jdbc;
/** /**
* Monitoring configuration information using the public ssh protocol
* 使用公共的ssh协议的监控配置信息 * 使用公共的ssh协议的监控配置信息
*/ */
private SshProtocol ssh; private SshProtocol ssh;
@@ -118,22 +101,18 @@ public class Metrics {
@NoArgsConstructor @NoArgsConstructor
public static class Field { public static class Field {
/** /**
* Indicator name
* 指标名称 * 指标名称
*/ */
private String field; private String field;
/** /**
* Indicator type 0-number: number 1-string: string
* 指标类型 0-number:数字 1-string:字符串 * 指标类型 0-number:数字 1-string:字符串
*/ */
private byte type = 1; private byte type = 1;
/** /**
* Whether this field is the instance primary key
* 此字段是否为实例主键 * 此字段是否为实例主键
*/ */
private boolean instance = false; private boolean instance = false;
/** /**
* Indicator unit
* 指标单位 * 指标单位
*/ */
private String unit; private String unit;

View File

@@ -22,9 +22,7 @@ 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;
/** /**
* Monitor Entity
* 监控实体 * 监控实体
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 9:53 * @date 2021/11/14 9:53
*/ */
@@ -34,11 +32,10 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(description = "en: Monitor Entity,zh: 监控实体") @ApiModel(description = "监控实体")
public class Monitor { public class Monitor {
/** /**
* Monitor ID
* 主键ID * 主键ID
*/ */
@Id @Id
@@ -46,14 +43,12 @@ public class Monitor {
private Long id; private Long id;
/** /**
* Job ID
* 监控对应下发的任务ID * 监控对应下发的任务ID
*/ */
@ApiModelProperty(value = "任务ID", example = "43243543543", accessMode = READ_ONLY, position = 1) @ApiModelProperty(value = "任务ID", example = "43243543543", accessMode = READ_ONLY, position = 1)
private Long jobId; private Long jobId;
/** /**
* Monitor Name
* 监控的名称 * 监控的名称
*/ */
@ApiModelProperty(value = "监控名称", example = "Api-TanCloud.cn", accessMode = READ_WRITE, position = 2) @ApiModelProperty(value = "监控名称", example = "Api-TanCloud.cn", accessMode = READ_WRITE, position = 2)
@@ -61,7 +56,6 @@ public class Monitor {
private String name; private String name;
/** /**
* Type of monitoring: linux, mysql, jvm...
* 监控的类型:linux,mysql,jvm... * 监控的类型:linux,mysql,jvm...
*/ */
@ApiModelProperty(value = "监控类型", example = "TanCloud", accessMode = READ_WRITE, position = 3) @ApiModelProperty(value = "监控类型", example = "TanCloud", accessMode = READ_WRITE, position = 3)
@@ -69,7 +63,6 @@ public class Monitor {
private String app; private String app;
/** /**
* Monitored peer host: ipv4, ipv6, domain name
* 监控的对端host:ipv4,ipv6,域名 * 监控的对端host:ipv4,ipv6,域名
*/ */
@ApiModelProperty(value = "监控的对端host", example = "192.167.25.11", accessMode = READ_WRITE, position = 4) @ApiModelProperty(value = "监控的对端host", example = "192.167.25.11", accessMode = READ_WRITE, position = 4)
@@ -78,7 +71,6 @@ public class Monitor {
private String host; private String host;
/** /**
* Monitoring collection interval time, in seconds
* 监控的采集间隔时间,单位秒 * 监控的采集间隔时间,单位秒
*/ */
@ApiModelProperty(value = "监控的采集间隔时间,单位秒", example = "600", accessMode = READ_WRITE, position = 5) @ApiModelProperty(value = "监控的采集间隔时间,单位秒", example = "600", accessMode = READ_WRITE, position = 5)
@@ -86,7 +78,6 @@ public class Monitor {
private Integer intervals; private Integer intervals;
/** /**
* Monitoring status 0: Unmonitored, 1: Available, 2: Unavailable, 3: Unreachable, 4: Suspended
* 监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起 * 监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起
*/ */
@ApiModelProperty(value = "监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起", accessMode = READ_WRITE, position = 6) @ApiModelProperty(value = "监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起", accessMode = READ_WRITE, position = 6)
@@ -95,7 +86,6 @@ public class Monitor {
private byte status; private byte status;
/** /**
* Monitoring note description
* 监控备注描述 * 监控备注描述
*/ */
@ApiModelProperty(value = "监控备注描述", example = "对SAAS网站TanCloud的可用性监控", accessMode = READ_WRITE, position = 7) @ApiModelProperty(value = "监控备注描述", example = "对SAAS网站TanCloud的可用性监控", accessMode = READ_WRITE, position = 7)
@@ -103,21 +93,18 @@ public class Monitor {
private String description; private String description;
/** /**
* The creator of this record
* 此条记录创建者 * 此条记录创建者
*/ */
@ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 8) @ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 8)
private String creator; private String creator;
/** /**
* This record was last modified by
* 此条记录最新修改者 * 此条记录最新修改者
*/ */
@ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 9) @ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 9)
private String modifier; private String modifier;
/** /**
* record creation time (millisecond timestamp)
* 记录创建时间 * 记录创建时间
*/ */
@ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 10) @ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 10)
@@ -125,7 +112,6 @@ public class Monitor {
private LocalDateTime gmtCreate; private LocalDateTime gmtCreate;
/** /**
* Record the latest modification time (timestamp in milliseconds)
* 记录最新修改时间 * 记录最新修改时间
*/ */
@ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 11) @ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 11)

View File

@@ -23,9 +23,7 @@ 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
*/ */
@@ -35,80 +33,56 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(description = "en: Message notification recipient entity,zh:消息通知接收人实体") @ApiModel(description = "消息通知接收人实体")
public class NoticeReceiver { public class NoticeReceiver {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "Recipient entity primary key index ID", @ApiModelProperty(value = "接收人实体主键索引ID", example = "87584674384", accessMode = READ_ONLY, position = 0)
notes = "接收人实体主键索引ID",
example = "87584674384", accessMode = READ_ONLY, position = 0)
private Long id; private Long id;
@ApiModelProperty(value = "Recipient name", @ApiModelProperty(value = "接收人名称", example = "tom", accessMode = READ_WRITE, position = 1)
notes = "接收人名称",
example = "tom", accessMode = READ_WRITE, position = 1)
@Length(max = 100) @Length(max = 100)
@NotNull @NotNull
private String name; private String name;
@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", @ApiModelProperty(value = "通知信息方式: 0-手机短信 1-邮箱 2-webhook 3-微信公众号 4-企业微信机器人 5-钉钉机器人 6-飞书机器人", accessMode = READ_WRITE, position = 2)
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 = "Mobile number: Valid when the notification method is SMS", @ApiModelProperty(value = "手机号, 通知方式为手机短信时有效", example = "18923435643", accessMode = READ_WRITE, position = 3)
notes = "手机号 : 通知方式为手机短信时有效",
example = "18923435643", accessMode = READ_WRITE, position = 3)
@Length(max = 100) @Length(max = 100)
private String phone; private String phone;
@ApiModelProperty(value = "Email account: Valid when the notification method is email", @ApiModelProperty(value = "邮箱账号, 通知方式为邮箱时有效", example = "tom@qq.com", accessMode = READ_WRITE, position = 4)
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 address: The notification method is valid for webhook", @ApiModelProperty(value = "URL地址, 通知方式为webhook有效", example = "https://www.tancloud.cn", accessMode = READ_WRITE, position = 5)
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 : The notification method is valid for WeChat official account or enterprise WeChat robot", @ApiModelProperty(value = "openId, 通知方式为微信公众号或企业微信机器人有效", example = "343432", accessMode = READ_WRITE, position = 6)
notes = "openId : 通知方式为微信公众号或企业微信机器人有效",
example = "343432", accessMode = READ_WRITE, position = 6)
@Length(max = 300) @Length(max = 300)
private String wechatId; private String wechatId;
@ApiModelProperty(value = "Access token : The notification method is valid for DingTalk robot", @ApiModelProperty(value = "访问token, 通知方式为钉钉机器人有效", example = "34823984635647", accessMode = READ_WRITE, position = 7)
notes = "访问token : 通知方式为钉钉机器人有效",
example = "34823984635647", accessMode = READ_WRITE, position = 7)
@Length(max = 300) @Length(max = 300)
private String accessToken; private String accessToken;
@ApiModelProperty(value = "The creator of this record", @ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 7)
notes = "此条记录创建者",
example = "tom", accessMode = READ_ONLY, position = 7)
private String creator; private String creator;
@ApiModelProperty(value = "This record was last modified by", @ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 8)
notes = "此条记录最新修改者",
example = "tom", accessMode = READ_ONLY, position = 8)
private String modifier; private String modifier;
@ApiModelProperty(value = "Record creation time (millisecond timestamp)", @ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 9)
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 = "Record the latest modification time (timestamp in milliseconds)", @ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 10)
notes = "记录最新修改时间(毫秒时间戳)",
example = "1612198444000", accessMode = READ_ONLY, position = 10)
@Column(insertable = false, updatable = false) @Column(insertable = false, updatable = false)
private LocalDateTime gmtUpdate; private LocalDateTime gmtUpdate;

View File

@@ -21,9 +21,7 @@ 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
*/ */
@@ -33,65 +31,45 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(description = "en: Notify Policy Entity,zh: 通知策略实体") @ApiModel(description = "通知策略实体")
public class NoticeRule { public class NoticeRule {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "Notification Policy Entity Primary Key Index ID", @ApiModelProperty(value = "通知策略实体主键索引ID", example = "87584674384", accessMode = READ_ONLY, position = 0)
notes = "通知策略实体主键索引ID",
example = "87584674384", accessMode = READ_ONLY, position = 0)
private Long id; private Long id;
@ApiModelProperty(value = "Policy name", @ApiModelProperty(value = "策略名称", example = "dispatch-1", accessMode = READ_WRITE, position = 1)
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 = "Recipient ID", @ApiModelProperty(value = "接收人ID", example = "4324324", accessMode = READ_WRITE, position = 2)
notes = "接收人ID",
example = "4324324", accessMode = READ_WRITE, position = 2)
@NotNull @NotNull
private Long receiverId; private Long receiverId;
@ApiModelProperty(value = "Recipient identification", @ApiModelProperty(value = "接收人标识", example = "tom", accessMode = READ_WRITE, position = 3)
notes = "接收人标识",
example = "tom", accessMode = READ_WRITE, position = 3)
@Length(max = 100) @Length(max = 100)
@NotNull @NotNull
private String receiverName; private String receiverName;
@ApiModelProperty(value = "Whether to enable this policy", @ApiModelProperty(value = "是否启用此策略", example = "true", accessMode = READ_WRITE, position = 4)
notes = "是否启用此策略",
example = "true", accessMode = READ_WRITE, position = 4)
private boolean enable = true; private boolean enable = true;
@ApiModelProperty(value = "Whether to forward all", @ApiModelProperty(value = "是否转发所有", example = "false", accessMode = READ_WRITE, position = 5)
notes = "是否转发所有",
example = "false", accessMode = READ_WRITE, position = 5)
private boolean filterAll = true; private boolean filterAll = true;
@ApiModelProperty(value = "The creator of this record", @ApiModelProperty(value = "此条记录创建者", example = "tom", accessMode = READ_ONLY, position = 7)
notes = "此条记录创建者",
example = "tom", accessMode = READ_ONLY, position = 7)
private String creator; private String creator;
@ApiModelProperty(value = "This record was last modified by", @ApiModelProperty(value = "此条记录最新修改者", example = "tom", accessMode = READ_ONLY, position = 8)
notes = "此条记录最新修改者",
example = "tom", accessMode = READ_ONLY, position = 8)
private String modifier; private String modifier;
@ApiModelProperty(value = "This record creation time (millisecond timestamp)", @ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 9)
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 = "Record the latest modification time (timestamp in milliseconds)", @ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 10)
notes = "记录最新修改时间(毫秒时间戳)",
example = "1612198444000", accessMode = READ_ONLY, position = 10)
@Column(insertable = false, updatable = false) @Column(insertable = false, updatable = false)
private LocalDateTime gmtUpdate; private LocalDateTime gmtUpdate;

View File

@@ -23,9 +23,7 @@ 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;
/** /**
* Monitor parameter values
* 监控参数值 * 监控参数值
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/13 22:19 * @date 2021/11/13 22:19
*/ */
@@ -35,26 +33,21 @@ import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_WRITE;
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(description = "嗯: Parameter Entity,zh: 参数实体") @ApiModel(description = "参数实体")
public class Param { public class Param {
/**
* Parameter primary key index ID
*/
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "参数主键索引ID", example = "87584674384", accessMode = READ_ONLY, position = 0) @ApiModelProperty(value = "参数主键索引ID", example = "87584674384", accessMode = READ_ONLY, position = 0)
private Long id; private Long id;
/** /**
* Monitor ID
* 监控ID * 监控ID
*/ */
@ApiModelProperty(value = "监控ID", example = "875846754543", accessMode = READ_WRITE, position = 1) @ApiModelProperty(value = "监控ID", example = "875846754543", accessMode = READ_WRITE, position = 1)
private Long monitorId; private Long monitorId;
/** /**
* Parameter Field Identifier
* 参数字段标识符 * 参数字段标识符
*/ */
@ApiModelProperty(value = "参数标识符字段", example = "port", accessMode = READ_WRITE, position = 2) @ApiModelProperty(value = "参数标识符字段", example = "port", accessMode = READ_WRITE, position = 2)
@@ -63,7 +56,6 @@ public class Param {
private String field; private String field;
/** /**
* Param Value
* 参数值 * 参数值
*/ */
@ApiModelProperty(value = "参数值", example = "8080", accessMode = READ_WRITE, position = 3) @ApiModelProperty(value = "参数值", example = "8080", accessMode = READ_WRITE, position = 3)
@@ -71,7 +63,6 @@ public class Param {
private String value; private String value;
/** /**
* Parameter type 0: number 1: string 2: encrypted string 3: json string mapped by map
* 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串 * 参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串
*/ */
@ApiModelProperty(value = "参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串", accessMode = READ_WRITE, position = 4) @ApiModelProperty(value = "参数类型 0:数字 1:字符串 2:加密串 3:map映射的json串", accessMode = READ_WRITE, position = 4)
@@ -80,7 +71,6 @@ public class Param {
private byte type; private byte type;
/** /**
* Record Creation Time
* 记录创建时间 * 记录创建时间
*/ */
@ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 5) @ApiModelProperty(value = "记录创建时间(毫秒时间戳)", example = "1612198922000", accessMode = READ_ONLY, position = 5)
@@ -88,7 +78,6 @@ public class Param {
private LocalDateTime gmtCreate; private LocalDateTime gmtCreate;
/** /**
* Record the latest modification time
* 记录最新修改时间 * 记录最新修改时间
*/ */
@ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 6) @ApiModelProperty(value = "记录最新修改时间(毫秒时间戳)", example = "1612198444000", accessMode = READ_ONLY, position = 6)

View File

@@ -1,208 +1,175 @@
package com.usthe.common.util; package com.usthe.common.util;
/** /**
* Public Constant
* 公共常量 * 公共常量
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 12:06 * @date 2021/11/14 12:06
*/ */
public interface CommonConstants { public interface CommonConstants {
/** /**
* Response status code: generic success
* 响应状态码: 通用成功 * 响应状态码: 通用成功
*/ */
byte SUCCESS_CODE = 0x00; byte SUCCESS_CODE = 0x00;
/** /**
* Response status code: generic failure
* 响应状态码: 通用失败 * 响应状态码: 通用失败
*/ */
byte FAIL_CODE = 0x0F; byte FAIL_CODE = 0x0F;
/** /**
* Response status code: Parameter verification failed
* 响应状态码: 参数校验失败 * 响应状态码: 参数校验失败
*/ */
byte PARAM_INVALID_CODE = 0x01; byte PARAM_INVALID_CODE = 0x01;
/** /**
* Response Status Code: Probe Failed
* 响应状态码: 探测失败 * 响应状态码: 探测失败
*/ */
byte DETECT_FAILED_CODE = 0x02; byte DETECT_FAILED_CODE = 0x02;
/** /**
* Response status code: monitoring does not exist
* 响应状态码: 监控不存在 * 响应状态码: 监控不存在
*/ */
byte MONITOR_NOT_EXIST_CODE = 0x03; byte MONITOR_NOT_EXIST_CODE = 0x03;
/** /**
* Response Status Code: Monitor Service Conflict
* 响应状态码: 监控服务冲突 * 响应状态码: 监控服务冲突
*/ */
byte MONITOR_CONFLICT_CODE = 0x04; byte MONITOR_CONFLICT_CODE = 0x04;
/** /**
* Response status code: Incorrect login account password
* 响应状态码: 登录账户密码错误 * 响应状态码: 登录账户密码错误
*/ */
byte MONITOR_LOGIN_FAILED_CODE = 0x05; byte MONITOR_LOGIN_FAILED_CODE = 0x05;
/** /**
* Response status code: Registration failed exception
* 响应状态码: 注册失败异常 * 响应状态码: 注册失败异常
*/ */
byte MONITOR_REGISTER_FAILED_CODE = 0x06; byte MONITOR_REGISTER_FAILED_CODE = 0x06;
/** /**
* Monitoring Status Code: Unmanaged
* 监控状态码: 未管理 * 监控状态码: 未管理
*/ */
byte UN_MANAGE_CODE = 0x00; byte UN_MANAGE_CODE = 0x00;
/** /**
* Monitoring Status Code: Available
* 监控状态码: 可用 * 监控状态码: 可用
*/ */
byte AVAILABLE_CODE = 0x01; byte AVAILABLE_CODE = 0x01;
/** /**
* Monitoring Status Code: Not Available
* 监控状态码: 不可用 * 监控状态码: 不可用
*/ */
byte UN_AVAILABLE_CODE = 0x02; byte UN_AVAILABLE_CODE = 0x02;
/** /**
* Monitoring Status Code: Unreachable
* 监控状态码: 不可达 * 监控状态码: 不可达
*/ */
byte UN_REACHABLE_CODE = 0x03; byte UN_REACHABLE_CODE = 0x03;
/** /**
* Monitoring Status Code: Pending
* 监控状态码: 挂起 * 监控状态码: 挂起
*/ */
byte SUSPENDING_CODE = 0x04; byte SUSPENDING_CODE = 0x04;
/** /**
* Alarm status: 0 - normal alarm (to be processed)
* 告警状态: 0-正常告警(待处理) * 告警状态: 0-正常告警(待处理)
*/ */
byte ALERT_STATUS_CODE_PENDING = 0x00; byte ALERT_STATUS_CODE_PENDING = 0x00;
/** /**
* Alarm Status: 1 - Threshold triggered but not reached the number of alarms
* 告警状态: 1-阈值触发但未达到告警次数 * 告警状态: 1-阈值触发但未达到告警次数
*/ */
byte ALERT_STATUS_CODE_NOT_REACH = 0x01; byte ALERT_STATUS_CODE_NOT_REACH = 0x01;
/** /**
* Alarm Status: 2-Restore Alarm
* 告警状态: 2-恢复告警 * 告警状态: 2-恢复告警
*/ */
byte ALERT_STATUS_CODE_RESTORED = 0x02; byte ALERT_STATUS_CODE_RESTORED = 0x02;
/** /**
* Alert Status: 3-Handled
* 告警状态: 3-已处理 * 告警状态: 3-已处理
*/ */
byte ALERT_STATUS_CODE_SOLVED = 0x03; byte ALERT_STATUS_CODE_SOLVED = 0x03;
/** /**
* Alarm level: 0: high-emergency-emergency-red
* 告警级别: 0:高-emergency-紧急告警-红色 * 告警级别: 0:高-emergency-紧急告警-红色
*/ */
byte ALERT_PRIORITY_CODE_EMERGENCY = 0x00; byte ALERT_PRIORITY_CODE_EMERGENCY = 0x00;
/** /**
* Alarm severity: 1: medium-critical-critical alarm-orange
* 告警级别: 1:中-critical-严重告警-橙色 * 告警级别: 1:中-critical-严重告警-橙色
*/ */
byte ALERT_PRIORITY_CODE_CRITICAL = 0x01; byte ALERT_PRIORITY_CODE_CRITICAL = 0x01;
/** /**
* Warning level: 2: low-warning-warning warning-yellow
* 告警级别: 2:低-warning-警告告警-黄色 * 告警级别: 2:低-warning-警告告警-黄色
*/ */
byte ALERT_PRIORITY_CODE_WARNING = 0x02; byte ALERT_PRIORITY_CODE_WARNING = 0x02;
/** /**
* Field parameter type: number
* 字段参数类型: 数字 * 字段参数类型: 数字
*/ */
byte TYPE_NUMBER = 0; byte TYPE_NUMBER = 0;
/** /**
* Field parameter type: String
* 字段参数类型: 字符串 * 字段参数类型: 字符串
*/ */
byte TYPE_STRING = 1; byte TYPE_STRING = 1;
/** /**
* Field parameter type: encrypted string
* 字段参数类型: 加密字符串 * 字段参数类型: 加密字符串
*/ */
byte TYPE_SECRET = 2; byte TYPE_SECRET = 2;
/** /**
* Collection indicator value: null placeholder for empty value
* 采集指标值null空值占位符 * 采集指标值null空值占位符
*/ */
String NULL_VALUE = "&nbsp;"; String NULL_VALUE = "&nbsp;";
/** /**
* Availability Object
* 可用性对象 * 可用性对象
*/ */
String AVAILABLE = "available"; String AVAILABLE = "available";
/** /**
* Reachability Object可达性对象 * 可达性对象
*/ */
String REACHABLE = "reachable"; String REACHABLE = "reachable";
/** /**
* Parameter Type Number
* 参数类型 数字 * 参数类型 数字
*/ */
byte PARAM_TYPE_NUMBER = 0; byte PARAM_TYPE_NUMBER = 0;
/** /**
* Parameter Type String
* 参数类型 字符串 * 参数类型 字符串
*/ */
byte PARAM_TYPE_STRING = 1; byte PARAM_TYPE_STRING = 1;
/** /**
* Parameter Type Password
* 参数类型 密码 * 参数类型 密码
*/ */
byte PARAM_TYPE_PASSWORD = 2; byte PARAM_TYPE_PASSWORD = 2;
/** /**
* Authentication type Account password
* 认证类型 账户密码 * 认证类型 账户密码
*/ */
byte AUTH_TYPE_PASSWORD = 1; byte AUTH_TYPE_PASSWORD = 1;
/** /**
* Authentication type GITHUB three-party login
* 认证类型 GITHUB三方登录 * 认证类型 GITHUB三方登录
*/ */
byte AUTH_TYPE_GITHUB = 2; byte AUTH_TYPE_GITHUB = 2;
/** /**
* Authentication type WeChat three-party login
* 认证类型 微信三方登录 * 认证类型 微信三方登录
*/ */
byte AUTH_TYPE_WEIXIN = 3; byte AUTH_TYPE_WEIXIN = 3;
/** /**
* Authentication type GITEE three-party login
* 认证类型 GITEE三方登录 * 认证类型 GITEE三方登录
*/ */
byte AUTH_TYPE_GITEE = 5; byte AUTH_TYPE_GITEE = 5;

View File

@@ -1,9 +1,7 @@
package com.usthe.common.util; package com.usthe.common.util;
/** /**
* Snowflake Algorithm Generator Tool
* 雪花算法生成器工具 * 雪花算法生成器工具
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/10 11:04 * @date 2021/11/10 11:04
*/ */

View File

@@ -1,18 +0,0 @@
---
id: alert_console
title: 告警模板中自定义的控制台地址
sidebar_label: 告警模板登录台地址
---
> 阈值触发后发送告警信息,通过钉钉/企业微信/飞书机器人通知或者使用邮箱通知的时候,告警内容中有登录控制台的详情链接
### 自定义设置
在我们的启动配置文件application.yml中找到下面的配置
```yml
alerter:
console-url: #这里就是我们的自定义控制台地址
```
默认值是赫兹跳动的官方控制台地址

View File

@@ -6,8 +6,6 @@ sidebar_label: Docker方式部署
> 推荐使用docker部署HertzBeat > 推荐使用docker部署HertzBeat
安装部署视频教程: [HertzBeat安装部署-BiliBili](https://www.bilibili.com/video/BV1GY41177YL)
1. 下载安装Docker环境 1. 下载安装Docker环境
Docker 工具自身的下载请参考 [Docker官网文档](https://docs.docker.com/get-docker/)。 Docker 工具自身的下载请参考 [Docker官网文档](https://docs.docker.com/get-docker/)。
安装完毕后终端查看Docker版本是否正常输出。 安装完毕后终端查看Docker版本是否正常输出。
@@ -49,101 +47,71 @@ sidebar_label: Docker方式部署
```yaml ```yaml
resourceRole: resourceRole:
- /account/auth/refresh===post===[admin,user,guest] - /account/auth/refresh===post===[role1,role2,role3,role4]
- /apps/**===get===[admin,user,guest]
- /monitor/**===get===[admin,user,guest]
- /monitor/**===post===[admin,user]
- /monitor/**===put===[admin,user]
- /monitor/**===delete==[admin]
- /monitors/**===get===[admin,user,guest]
- /monitors/**===post===[admin,user]
- /monitors/**===put===[admin,user]
- /monitors/**===delete===[admin]
- /alert/**===get===[admin,user,guest]
- /alert/**===post===[admin,user]
- /alert/**===put===[admin,user]
- /alert/**===delete===[admin]
- /alerts/**===get===[admin,user,guest]
- /alerts/**===post===[admin,user]
- /alerts/**===put===[admin,user]
- /alerts/**===delete===[admin]
- /notice/**===get===[admin,user,guest]
- /notice/**===post===[admin,user]
- /notice/**===put===[admin,user]
- /notice/**===delete===[admin]
- /summary/**===get===[admin,user,guest]
- /summary/**===post===[admin,user]
- /summary/**===put===[admin,user]
- /summary/**===delete===[admin]
excludedResource: excludedResource:
- /account/auth/**===* - /account/auth/**===*
- /===get - /===get
- /i18n/**===get - /i18n/**===get
- /apps/hierarchy===get - /apps/hierarchy===get
# web ui 静态资源 - /console/**===get
- /console/**===get - /**/*.html===get
- /**/*.html===get - /**/*.js===get
- /**/*.js===get - /**/*.css===get
- /**/*.css===get - /**/*.ico===get
- /**/*.ico===get - /**/*.ttf===get
- /**/*.ttf===get - /**/*.png===get
- /**/*.png===get - /**/*.gif===get
- /**/*.gif===get
- /**/*.png===* - /**/*.png===*
# swagger ui 资源 - /swagger-resources/**===get
- /swagger-resources/**===get - /v2/api-docs===get
- /v2/api-docs===get - /v3/api-docs===get
- /v3/api-docs===get
account:
- appId: admin
credential: admin
role: [admin,user]
- appId: tom
credential: tom@123
role: [user]
- appId: guest
credential: guest
role: [guest]
- appId: lili
# 注意 Digest认证不支持加盐加密的密码账户
# 加盐加密的密码,通过 MD5(password+salt)计算
# 此账户的原始密码为 lili
credential: 1A676730B0C7F54654B0E09184448289
salt: 123
role: [guest]
# 用户账户信息
# 下面有 admin tom lili 三个账户
# eg: admin 拥有[role1,role2]角色,密码为admin
# eg: tom 拥有[role1,role2,role3],密码为tom@123
# eg: lili 拥有[role1,role2],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289
account:
- appId: admin
credential: admin
role: [role1,role2]
- appId: tom
credential: tom@123
role: [role1,role2,role3]
- appId: lili
# 注意 Digest认证不支持加盐加密的密码账户
# 加盐加密的密码,通过 MD5(password+salt)计算
# 此账户的原始密码为 lili
credential: 1A676730B0C7F54654B0E09184448289
salt: 123
role: [role1,role2]
``` ```
修改sureness.yml的如下**部分参数****[注意⚠sureness配置的其它默认参数需保留]** 修改sureness.yml的如下**部分参数****[注意⚠sureness配置的其它默认参数需保留]**
```yaml ```yaml
# 用户账户信息 # 用户账户信息
# 下面有 admin tom lili 三个账户 # 下面有 admin tom lili 三个账户
# eg: admin 拥有[admin,user]角色,密码为admin # eg: admin 拥有[role1,role2]角色,密码为admin
# eg: tom 拥有[user],密码为tom@123 # eg: tom 拥有[role1,role2,role3],密码为tom@123
# eg: lili 拥有[guest],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289 # eg: lili 拥有[role1,role2],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289
account: account:
- appId: admin - appId: admin
credential: admin credential: admin
role: [admin,user] role: [role1,role2]
- appId: tom - appId: tom
credential: tom@123 credential: tom@123
role: [user] role: [role1,role2,role3]
- appId: guest - appId: lili
credential: guest # 注意 Digest认证不支持加盐加密的密码账户
role: [guest] # 加盐加密的密码,通过 MD5(password+salt)计算
- appId: lili # 此账户的原始密码为 lili
# 注意 Digest认证不支持加盐加密的密码账户 credential: 1A676730B0C7F54654B0E09184448289
# 加盐加密的密码,通过 MD5(password+salt)计算 salt: 123
# 此账户的原始密码为 lili role: [role1,role2]
credential: 1A676730B0C7F54654B0E09184448289
salt: 123
role: [guest]
``` ```
6. 启动HertzBeat Docker容器 6. 启动HertzBeat Docker容器

View File

@@ -5,8 +5,6 @@ sidebar_label: MYSQL安装初始化
--- ---
MYSQL是一款值得信赖的关系型数据库HertzBeat使用其存储监控信息告警信息配置信息等结构化关系数据。 MYSQL是一款值得信赖的关系型数据库HertzBeat使用其存储监控信息告警信息配置信息等结构化关系数据。
安装部署视频教程: [HertzBeat安装部署-BiliBili](https://www.bilibili.com/video/BV1GY41177YL)
> 如果您已有MYSQL环境可直接跳到SQL脚本执行那一步。 > 如果您已有MYSQL环境可直接跳到SQL脚本执行那一步。
### 通过Docker方式安装MYSQL ### 通过Docker方式安装MYSQL

View File

@@ -3,9 +3,7 @@ id: package-deploy
title: 通过安装包安装HertzBeat title: 通过安装包安装HertzBeat
sidebar_label: 安装包方式部署 sidebar_label: 安装包方式部署
--- ---
> HertzBeat支持在Linux Windows Mac系统安装运行CPU支持X86/ARM64。由于安装包自身不包含JAVA运行环境需您提前准备JAVA运行环境。 > HertzBeat支持在Linux Windows Mac系统安装运行CPU支持X64/ARM64。由于安装包自身不包含JAVA运行环境需您提前准备JAVA运行环境。
安装部署视频教程: [HertzBeat安装部署-BiliBili](https://www.bilibili.com/video/BV1GY41177YL)
1. 安装JAVA运行环境-可参考[官方网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html) 1. 安装JAVA运行环境-可参考[官方网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
要求JDK8+(已验证JDK8) 要求JDK8+(已验证JDK8)
@@ -51,30 +49,25 @@ sidebar_label: 安装包方式部署
修改sureness.yml的如下**部分参数****[注意⚠sureness配置的其它默认参数需保留]** 修改sureness.yml的如下**部分参数****[注意⚠sureness配置的其它默认参数需保留]**
```yaml ```yaml
# 用户账户信息
# 用户账户信息 # 下面有 admin tom lili 三个账户
# 下面有 admin tom lili 三个账户 # eg: admin 拥有[role1,role2]角色,密码为admin
# eg: admin 拥有[admin,user]角色,密码为admin # eg: tom 拥有[role1,role2,role3],密码为tom@123
# eg: tom 拥有[user],密码为tom@123 # eg: lili 拥有[role1,role2],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289
# eg: lili 拥有[guest],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289 account:
account: - appId: admin
- appId: admin credential: admin
credential: admin role: [role1,role2]
role: [admin,user] - appId: tom
- appId: tom credential: tom@123
credential: tom@123 role: [role1,role2,role3]
role: [user] - appId: lili
- appId: guest # 注意 Digest认证不支持加盐加密的密码账户
credential: guest # 加盐加密的密码,通过 MD5(password+salt)计算
role: [guest] # 此账户的原始密码为 lili
- appId: lili credential: 1A676730B0C7F54654B0E09184448289
# 注意 Digest认证不支持加盐加密的密码账户 salt: 123
# 加盐加密的密码,通过 MD5(password+salt)计算 role: [role1,role2]
# 此账户的原始密码为 lili
credential: 1A676730B0C7F54654B0E09184448289
salt: 123
role: [guest]
``` ```
5. 部署启动 5. 部署启动

View File

@@ -9,8 +9,6 @@ sidebar_label: 快速开始
- 如果您不想部署而是直接使用我们提供SAAS监控云-[TanCloud探云](https://console.tancloud.cn),即刻[登录注册](https://console.tancloud.cn)免费使用。 - 如果您不想部署而是直接使用我们提供SAAS监控云-[TanCloud探云](https://console.tancloud.cn),即刻[登录注册](https://console.tancloud.cn)免费使用。
- 如果您是想将HertzBeat部署到内网环境搭建监控系统请参考下面的部署文档进行操作。 - 如果您是想将HertzBeat部署到内网环境搭建监控系统请参考下面的部署文档进行操作。
安装部署视频教程: [HertzBeat安装部署-BiliBili](https://www.bilibili.com/video/BV1GY41177YL)
### 🐵 依赖服务部署 ### 🐵 依赖服务部署
> HertzBeat最少依赖于 关系型数据库[MYSQL5+](https://www.mysql.com/) 和 时序性数据库[TDengine2+](https://www.taosdata.com/getting-started) > HertzBeat最少依赖于 关系型数据库[MYSQL5+](https://www.mysql.com/) 和 时序性数据库[TDengine2+](https://www.taosdata.com/getting-started)

View File

@@ -5,11 +5,8 @@ sidebar_label: TDengine安装初始化
--- ---
TDengine是一款国产的开源物联网时序型数据库我们使用其替换了InfluxDb来存储采集到的监控指标数据。 TDengine是一款国产的开源物联网时序型数据库我们使用其替换了InfluxDb来存储采集到的监控指标数据。
安装部署视频教程: [HertzBeat安装部署-BiliBili](https://www.bilibili.com/video/BV1GY41177YL)
> 如果您已有TDengine环境可直接跳到创建数据库实例那一步。 > 如果您已有TDengine环境可直接跳到创建数据库实例那一步。
### 通过Docker方式安装TDengine ### 通过Docker方式安装TDengine
> 可参考官方网站[安装教程](https://www.taosdata.com/docs/cn/v2.0/getting-started/docker) > 可参考官方网站[安装教程](https://www.taosdata.com/docs/cn/v2.0/getting-started/docker)
1. 下载安装Docker环境 1. 下载安装Docker环境

View File

@@ -1,14 +0,0 @@
{
"title": {
"message": "Blog",
"description": "The title for the blog used in SEO"
},
"description": {
"message": "Blog",
"description": "The description for the blog used in SEO"
},
"sidebar.title": {
"message": "Recent posts",
"description": "The label for the left sidebar"
}
}

View File

@@ -1,7 +1,6 @@
package com.usthe.manager.component.alerter; package com.usthe.manager.component.alerter;
import com.usthe.alert.AlerterDataQueue; import com.usthe.alert.AlerterDataQueue;
import com.usthe.alert.AlerterProperties;
import com.usthe.alert.AlerterWorkerPool; import com.usthe.alert.AlerterWorkerPool;
import com.usthe.common.util.CommonUtil; import com.usthe.common.util.CommonUtil;
import com.usthe.common.entity.alerter.Alert; import com.usthe.common.entity.alerter.Alert;
@@ -25,14 +24,12 @@ import org.springframework.stereotype.Component;
import org.springframework.web.client.ResourceAccessException; import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
/** /**
* Alarm information storage and distribution
* 告警信息入库分发 * 告警信息入库分发
* *
* @author tom * @author tom
@@ -50,8 +47,6 @@ public class DispatchAlarm {
private JavaMailSender javaMailSender; private JavaMailSender javaMailSender;
private RestTemplate restTemplate; private RestTemplate restTemplate;
private MailService mailService; private MailService mailService;
@Resource
private AlerterProperties alerterProperties;
@Value("${spring.mail.username}") @Value("${spring.mail.username}")
private String emailFromUser; private String emailFromUser;
@@ -76,7 +71,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);
@@ -92,7 +87,7 @@ public class DispatchAlarm {
} }
private void storeAlertData(Alert alert) { private void storeAlertData(Alert alert) {
// todo Using the cache does not directly manipulate the library 使用缓存不直接操作库 // todo 使用缓存不直接操作库
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());
@@ -100,38 +95,34 @@ 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 Forward configured email WeChat webhook 转发配置的邮件 微信 webhook // todo 转发配置的邮件 微信 webhook
List<NoticeReceiver> receivers = matchReceiverByNoticeRules(alert); List<NoticeReceiver> receivers = matchReceiverByNoticeRules(alert);
// todo Send notification here temporarily single thread 发送通知这里暂时单线程 // todo 发送通知这里暂时单线程
for (NoticeReceiver receiver : receivers) { for (NoticeReceiver receiver : receivers) {
switch (receiver.getType()) { switch (receiver.getType()) {
// todo SMS notification 短信通知 // todo 短信通知
case 0: case 0:
break; break;
case 1: case 1:
@@ -159,11 +150,10 @@ public class DispatchAlarm {
} }
/** /**
* Send alert information through FeiShu
* 通过飞书发送告警信息 * 通过飞书发送告警信息
* *
* @param receiver Notification configuration information 通知配置信息 * @param receiver 接收人
* @param alert Alarm information 告警信息 * @param alert 告警信息
*/ */
private void sendFlyBookAlert(NoticeReceiver receiver, Alert alert) { private void sendFlyBookAlert(NoticeReceiver receiver, Alert alert) {
FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto(); FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto();
@@ -181,13 +171,13 @@ public class DispatchAlarm {
"\n所属监控ID :" + alert.getMonitorId() + "\n所属监控ID :" + alert.getMonitorId() +
"\n所属监控名称 :" + alert.getMonitorName() + "\n所属监控名称 :" + alert.getMonitorName() +
"\n告警级别 :" + CommonUtil.transferAlertPriority(alert.getPriority()) + "\n告警级别 :" + CommonUtil.transferAlertPriority(alert.getPriority()) +
"\n内容详情 : " + alert.getContent() + "\n"; "\n内容详情 : " + alert.getContent();
flyBookContent.setText(text); flyBookContent.setText(text);
contents1.add(flyBookContent); contents1.add(flyBookContent);
FlyBookWebHookDto.FlyBookContent bookContent = new FlyBookWebHookDto.FlyBookContent(); FlyBookWebHookDto.FlyBookContent bookContent = new FlyBookWebHookDto.FlyBookContent();
bookContent.setTag("a"); bookContent.setTag("a");
bookContent.setText("登入控制台"); bookContent.setText("登入控制台");
bookContent.setHref(alerterProperties.getConsoleUrl()); bookContent.setHref("https://www.tancloud.cn");
contents1.add(bookContent); contents1.add(bookContent);
contents.add(contents1); contents.add(contents1);
zhCn.setTitle("[TanCloud探云告警通知]"); zhCn.setTitle("[TanCloud探云告警通知]");
@@ -209,25 +199,22 @@ public class DispatchAlarm {
} }
/** /**
* Send alarm information through DingTalk robot
* 通过钉钉机器人发送告警信息 * 通过钉钉机器人发送告警信息
* *
* @param receiver Notification configuration information 通知配置信息 * @param receiver 通知配置信息
* @param alert Alarm information 告警信息 * @param alert 告警信息
*/ */
private void sendDingTalkRobotAlert(NoticeReceiver receiver, Alert alert) { private void sendDingTalkRobotAlert(NoticeReceiver receiver, Alert alert) {
DingTalkWebHookDto dingTalkWebHookDto = new DingTalkWebHookDto(); DingTalkWebHookDto dingTalkWebHookDto = new DingTalkWebHookDto();
DingTalkWebHookDto.MarkdownDTO markdownDTO = new DingTalkWebHookDto.MarkdownDTO(); DingTalkWebHookDto.MarkdownDTO markdownDTO = new DingTalkWebHookDto.MarkdownDTO();
StringBuilder content = new StringBuilder(); String content = "#### [TanCloud探云告警通知]\n##### **告警目标对象** : " +
content.append("#### [TanCloud探云告警通知]\n##### **告警目标对象** : " +
alert.getTarget() + "\n " + alert.getTarget() + "\n " +
"##### **所属监控ID** : " + alert.getMonitorId() + "\n " + "##### **所属监控ID** : " + alert.getMonitorId() + "\n " +
"##### **所属监控名称** : " + alert.getMonitorName() + "\n " + "##### **所属监控名称** : " + alert.getMonitorName() + "\n " +
"##### **告警级别** : " + "##### **告警级别** : " +
CommonUtil.transferAlertPriority(alert.getPriority()) + "\n " + CommonUtil.transferAlertPriority(alert.getPriority()) + "\n " +
"##### **内容详情** : " + alert.getContent()); "##### **内容详情** : " + alert.getContent();
content.append("[点击跳转查看详情](" + alerterProperties.getConsoleUrl() + ")"); markdownDTO.setText(content);
markdownDTO.setText(content.toString());
markdownDTO.setTitle("TanCloud探云告警通知"); markdownDTO.setTitle("TanCloud探云告警通知");
dingTalkWebHookDto.setMarkdown(markdownDTO); dingTalkWebHookDto.setMarkdown(markdownDTO);
String webHookUrl = DingTalkWebHookDto.WEBHOOK_URL + receiver.getAccessToken(); String webHookUrl = DingTalkWebHookDto.WEBHOOK_URL + receiver.getAccessToken();
@@ -246,11 +233,10 @@ public class DispatchAlarm {
} }
/** /**
* Send alarm information through enterprise WeChat
* 通过企业微信发送告警信息 * 通过企业微信发送告警信息
* *
* @param receiver Notification configuration information 通知配置信息 * @param receiver 通知配置信息
* @param alert Alarm information 告警信息 * @param alert 告警信息
*/ */
private void sendWeWorkRobotAlert(NoticeReceiver receiver, Alert alert) { private void sendWeWorkRobotAlert(NoticeReceiver receiver, Alert alert) {
WeWorkWebHookDto weWorkWebHookDTO = new WeWorkWebHookDto(); WeWorkWebHookDto weWorkWebHookDTO = new WeWorkWebHookDto();
@@ -267,10 +253,8 @@ public class DispatchAlarm {
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");
} }
content.append("内容详情 : ").append(alert.getContent() + "\n"); content.append("内容详情 : ").append(alert.getContent());
content.append("[点击跳转查看详情](" + alerterProperties.getConsoleUrl() + ")");
markdownDTO.setContent(content.toString()); markdownDTO.setContent(content.toString());
//TODO 增加控制台地址登录可控制
weWorkWebHookDTO.setMarkdown(markdownDTO); weWorkWebHookDTO.setMarkdown(markdownDTO);
String webHookUrl = WeWorkWebHookDto.WEBHOOK_URL + receiver.getWechatId(); String webHookUrl = WeWorkWebHookDto.WEBHOOK_URL + receiver.getWechatId();
try { try {
@@ -312,23 +296,23 @@ public class DispatchAlarm {
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探云-监控告警");
//Set sender Email 设置发件人Email //设置发件人Email
messageHelper.setFrom(emailFromUser); messageHelper.setFrom(emailFromUser);
//Set recipient Email 设定收件人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("[Email Alert] ExceptionException information={}", e.getMessage()); log.error("[邮箱告警] errorException information={}", e.getMessage());
} }
} }
private List<NoticeReceiver> matchReceiverByNoticeRules(Alert alert) { private List<NoticeReceiver> matchReceiverByNoticeRules(Alert alert) {
// todo use cache 使用缓存 // todo 使用缓存
return noticeConfigService.getReceiverFilterRule(alert); return noticeConfigService.getReceiverFilterRule(alert);
} }

View File

@@ -1,7 +1,6 @@
package com.usthe.manager.controller; package com.usthe.manager.controller;
import com.usthe.common.entity.dto.Message; import com.usthe.common.entity.dto.Message;
import com.usthe.common.entity.manager.Monitor;
import com.usthe.manager.pojo.dto.MonitorDto; import com.usthe.manager.pojo.dto.MonitorDto;
import com.usthe.manager.service.MonitorService; import com.usthe.manager.service.MonitorService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@@ -24,13 +23,11 @@ import static com.usthe.common.util.CommonConstants.MONITOR_NOT_EXIST_CODE;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/** /**
* Monitoring management API
* 监控管理API * 监控管理API
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 10:57 * @date 2021/11/14 10:57
*/ */
@Api(tags = "en: Monitoring management API,zh: 监控管理API") @Api(tags = "监控管理API")
@RestController @RestController
@RequestMapping(path = "/monitor", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/monitor", produces = {APPLICATION_JSON_VALUE})
public class MonitorController { public class MonitorController {
@@ -39,12 +36,12 @@ public class MonitorController {
private MonitorService monitorService; private MonitorService monitorService;
@PostMapping @PostMapping
@ApiOperation(value = "Add a monitoring application", notes = "新增一个监控应用") @ApiOperation(value = "新增监控", notes = "新增一个监控应用")
public ResponseEntity<Message<Void>> addNewMonitor(@Valid @RequestBody MonitorDto monitorDto) { public ResponseEntity<Message<Void>> addNewMonitor(@Valid @RequestBody MonitorDto monitorDto) {
// Verify request data 校验请求数据 // 校验请求数据
monitorService.validate(monitorDto, false); monitorService.validate(monitorDto, false);
if (monitorDto.isDetected()) { if (monitorDto.isDetected()) {
// Probe 进行探测 // 进行探测
monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams());
} }
monitorService.addMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.addMonitor(monitorDto.getMonitor(), monitorDto.getParams());
@@ -52,12 +49,12 @@ public class MonitorController {
} }
@PutMapping @PutMapping
@ApiOperation(value = "Modify an existing monitoring application", notes = "修改一个已存在监控应用") @ApiOperation(value = "修改监控", notes = "修改一个已存在监控应用")
public ResponseEntity<Message<Void>> modifyMonitor(@Valid @RequestBody MonitorDto monitorDto) { public ResponseEntity<Message<Void>> modifyMonitor(@Valid @RequestBody MonitorDto monitorDto) {
// Verify request data 校验请求数据 // 校验请求数据
monitorService.validate(monitorDto, true); monitorService.validate(monitorDto, true);
if (monitorDto.isDetected()) { if (monitorDto.isDetected()) {
// Probe 进行探测 // 进行探测
monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams());
} }
monitorService.modifyMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.modifyMonitor(monitorDto.getMonitor(), monitorDto.getParams());
@@ -65,10 +62,9 @@ public class MonitorController {
} }
@GetMapping(path = "/{id}") @GetMapping(path = "/{id}")
@ApiOperation(value = "Obtain monitoring information based on monitoring ID", notes = "根据监控ID获取监控信息") @ApiOperation(value = "查询监控", notes = "根据监控ID获取监控信息")
public ResponseEntity<Message<MonitorDto>> getMonitor( public ResponseEntity<Message<MonitorDto>> getMonitor(
@ApiParam(value = "监控ID", example = "6565463543") @PathVariable("id") final long id) { @ApiParam(value = "监控ID", example = "6565463543") @PathVariable("id") final long id) {
// Get monitoring information
// 获取监控信息 // 获取监控信息
MonitorDto monitorDto = monitorService.getMonitorDto(id); MonitorDto monitorDto = monitorService.getMonitorDto(id);
Message.MessageBuilder<MonitorDto> messageBuilder = Message.builder(); Message.MessageBuilder<MonitorDto> messageBuilder = Message.builder();
@@ -81,20 +77,16 @@ public class MonitorController {
} }
@DeleteMapping(path = "/{id}") @DeleteMapping(path = "/{id}")
@ApiOperation(value = "Delete monitoring application based on monitoring ID", notes = "根据监控ID删除监控应用") @ApiOperation(value = "删除监控", notes = "根据监控ID删除监控应用,监控不存在也是删除成功")
public ResponseEntity<Message<Void>> deleteMonitor( public ResponseEntity<Message<Void>> deleteMonitor(
@ApiParam(value = "en: Monitor ID,zh: 监控ID", example = "6565463543") @PathVariable("id") final long id) { @ApiParam(value = "监控ID", example = "6565463543") @PathVariable("id") final long id) {
// delete monitor 删除监控 // 删除监控,监控不存在或删除成功都返回成功
Monitor monitor = monitorService.getMonitor(id);
if (monitor == null) {
return ResponseEntity.ok(new Message<>("The specified monitoring was not queried, please check whether the parameters are correct"));
}
monitorService.deleteMonitor(id); monitorService.deleteMonitor(id);
return ResponseEntity.ok(new Message<>("Delete success")); return ResponseEntity.ok(new Message<>("Delete success"));
} }
@PostMapping(path = "/detect") @PostMapping(path = "/detect")
@ApiOperation(value = "Perform availability detection on this monitoring based on monitoring information", notes = "根据监控信息去对此监控进行可用性探测") @ApiOperation(value = "探测监控", notes = "根据监控信息去对此监控进行可用性探测")
public ResponseEntity<Message<Void>> detectMonitor(@Valid @RequestBody MonitorDto monitorDto) { public ResponseEntity<Message<Void>> detectMonitor(@Valid @RequestBody MonitorDto monitorDto) {
monitorService.validate(monitorDto, null); monitorService.validate(monitorDto, null);
monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams()); monitorService.detectMonitor(monitorDto.getMonitor(), monitorDto.getParams());

View File

@@ -29,13 +29,11 @@ import java.util.List;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/** /**
* Monitor and manage batch API
* 监控管理批量API * 监控管理批量API
*
* @author tom * @author tom
* @date 2021/12/1 20:43 * @date 2021/12/1 20:43
*/ */
@Api(tags = "en: Monitor and manage batch API,zh: 监控列表API") @Api(tags = "监控列表API")
@RestController @RestController
@RequestMapping(path = "/monitors", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/monitors", produces = {APPLICATION_JSON_VALUE})
public class MonitorsController { public class MonitorsController {
@@ -46,23 +44,22 @@ public class MonitorsController {
private MonitorService monitorService; private MonitorService monitorService;
@GetMapping @GetMapping
@ApiOperation(value = "Obtain a list of monitoring information based on query filter items", @ApiOperation(value = "查询监控列表", notes = "根据查询过滤项获取监控信息列表")
notes = "根据查询过滤项获取监控信息列表")
public ResponseEntity<Message<Page<Monitor>>> getMonitors( public ResponseEntity<Message<Page<Monitor>>> getMonitors(
@ApiParam(value = "en: Monitor ID,zh: 监控ID", example = "6565463543") @RequestParam(required = false) final List<Long> ids, @ApiParam(value = "监控ID", example = "6565463543") @RequestParam(required = false) final List<Long> ids,
@ApiParam(value = "en: Monitor Type,zh: 监控类型", example = "linux") @RequestParam(required = false) final String app, @ApiParam(value = "监控类型", example = "linux") @RequestParam(required = false) final String app,
@ApiParam(value = "en: Monitor Name,zh: 监控名称,模糊查询", example = "linux-127.0.0.1") @RequestParam(required = false) final String name, @ApiParam(value = "监控名称,模糊查询", example = "linux-127.0.0.1") @RequestParam(required = false) final String name,
@ApiParam(value = "en: Monitor Host,zh: 监控Host模糊查询", example = "127.0.0.1") @RequestParam(required = false) final String host, @ApiParam(value = "监控Host模糊查询", example = "127.0.0.1") @RequestParam(required = false) final String host,
@ApiParam(value = "en: Monitor Status,zh: 监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起,9:全部状态", example = "1") @RequestParam(required = false) final Byte status, @ApiParam(value = "监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起,9:全部状态", example = "1") @RequestParam(required = false) final Byte status,
@ApiParam(value = "en: Sort Field,default id,zh: 排序字段默认id", example = "name") @RequestParam(defaultValue = "id") final String sort, @ApiParam(value = "排序字段默认id", example = "name") @RequestParam(defaultValue = "id") final String sort,
@ApiParam(value = "en: Sort by,zh: 排序方式asc:升序desc:降序", example = "desc") @RequestParam(defaultValue = "desc") final String order, @ApiParam(value = "排序方式asc:升序desc:降序", example = "desc") @RequestParam(defaultValue = "desc") final String order,
@ApiParam(value = "en: List current page,zh: 列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex, @ApiParam(value = "列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
@ApiParam(value = "en: Number of list pagination,zh: 列表分页数量", example = "8") @RequestParam(defaultValue = "8") int pageSize) { @ApiParam(value = "列表分页数量", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
Specification<Monitor> specification = (root, query, criteriaBuilder) -> { Specification<Monitor> 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);
} }
@@ -98,10 +95,10 @@ public class MonitorsController {
} else if (orPredicate.getExpressions().isEmpty()) { } else if (orPredicate.getExpressions().isEmpty()) {
return query.where(andPredicate).getRestriction(); return query.where(andPredicate).getRestriction();
} else { } else {
return query.where(andPredicate, orPredicate).getRestriction(); return query.where(andPredicate,orPredicate).getRestriction();
} }
}; };
// Pagination is a must 分页是必须的 // 分页是必须的
Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort)); Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort));
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp); PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp);
Page<Monitor> monitorPage = monitorService.getMonitors(specification, pageRequest); Page<Monitor> monitorPage = monitorService.getMonitors(specification, pageRequest);
@@ -110,20 +107,18 @@ public class MonitorsController {
} }
@GetMapping(path = "/{app}") @GetMapping(path = "/{app}")
@ApiOperation(value = "Filter all acquired monitoring information lists of the specified monitoring type according to the query", @ApiOperation(value = "查询指定监控类型的监控列表", notes = "根据查询过滤指定监控类型的所有获取监控信息列表")
notes = "根据查询过滤指定监控类型的所有获取监控信息列表")
public ResponseEntity<Message<List<Monitor>>> getAppMonitors( public ResponseEntity<Message<List<Monitor>>> getAppMonitors(
@ApiParam(value = "en: Monitoring type,zh: 监控类型", example = "linux") @PathVariable(required = false) final String app) { @ApiParam(value = "监控类型", example = "linux") @PathVariable(required = false) final String app) {
List<Monitor> monitors = monitorService.getAppMonitors(app); List<Monitor> monitors = monitorService.getAppMonitors(app);
Message<List<Monitor>> message = new Message<>(monitors); Message<List<Monitor>> message = new Message<>(monitors);
return ResponseEntity.ok(message); return ResponseEntity.ok(message);
} }
@DeleteMapping @DeleteMapping
@ApiOperation(value = "Delete monitoring items in batches according to the monitoring ID list", @ApiOperation(value = "批量删除监控", notes = "根据监控ID列表批量删除监控项")
notes = "根据监控ID列表批量删除监控项")
public ResponseEntity<Message<Void>> deleteMonitors( public ResponseEntity<Message<Void>> deleteMonitors(
@ApiParam(value = "en: Monitoring ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List<Long> ids @ApiParam(value = "监控IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
) { ) {
if (ids != null && !ids.isEmpty()) { if (ids != null && !ids.isEmpty()) {
monitorService.deleteMonitors(new HashSet<>(ids)); monitorService.deleteMonitors(new HashSet<>(ids));
@@ -133,10 +128,9 @@ public class MonitorsController {
} }
@DeleteMapping("manage") @DeleteMapping("manage")
@ApiOperation(value = "Unmanaged monitoring items in batches according to the monitoring ID list", @ApiOperation(value = "批量取消纳管监控", notes = "根据监控ID列表批量取消纳管监控项")
notes = "根据监控ID列表批量取消纳管监控项")
public ResponseEntity<Message<Void>> cancelManageMonitors( public ResponseEntity<Message<Void>> cancelManageMonitors(
@ApiParam(value = "en: Monitoring ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List<Long> ids @ApiParam(value = "监控IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
) { ) {
if (ids != null && !ids.isEmpty()) { if (ids != null && !ids.isEmpty()) {
monitorService.cancelManageMonitors(new HashSet<>(ids)); monitorService.cancelManageMonitors(new HashSet<>(ids));
@@ -146,10 +140,9 @@ public class MonitorsController {
} }
@GetMapping("manage") @GetMapping("manage")
@ApiOperation(value = "Start the managed monitoring items in batches according to the monitoring ID list", @ApiOperation(value = "批量启动纳管监控", notes = "根据监控ID列表批量启动纳管监控项")
notes = "根据监控ID列表批量启动纳管监控项")
public ResponseEntity<Message<Void>> enableManageMonitors( public ResponseEntity<Message<Void>> enableManageMonitors(
@ApiParam(value = "en: Monitor ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List<Long> ids @ApiParam(value = "监控IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
) { ) {
if (ids != null && !ids.isEmpty()) { if (ids != null && !ids.isEmpty()) {
monitorService.enableManageMonitors(new HashSet<>(ids)); monitorService.enableManageMonitors(new HashSet<>(ids));

View File

@@ -28,13 +28,11 @@ 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 = "en: Message Notification Configuration API,zh: 消息通知配置API") @Api(tags = "消息通知配置API")
@RestController() @RestController()
@RequestMapping(value = "/notice", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(value = "/notice", produces = {APPLICATION_JSON_VALUE})
public class NoticeConfigController { public class NoticeConfigController {
@@ -43,36 +41,32 @@ public class NoticeConfigController {
private NoticeConfigService noticeConfigService; private NoticeConfigService noticeConfigService;
@PostMapping(path = "/receiver") @PostMapping(path = "/receiver")
@ApiOperation(value = "Add a recipient", notes = "新增一个接收人") @ApiOperation(value = "新增接收人", 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 = "Modify existing recipient information", notes = "修改已存在的接收人信息") @ApiOperation(value = "修改接收人", 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 = "Delete existing recipient information", notes = "删除已存在的接收人信息") @ApiOperation(value = "删除指定接收人", notes = "删除已存在的接收人信息")
public ResponseEntity<Message<Void>> deleteNoticeReceiver( public ResponseEntity<Message<Void>> deleteNoticeReceiver(
@ApiParam(value = "en: Recipient ID,zh: 接收人ID", example = "6565463543") @PathVariable("id") final Long receiverId) { @ApiParam(value = "接收人ID", example = "6565463543") @PathVariable("id") final Long receiverId) {
NoticeReceiver noticeReceiver = noticeConfigService.getReceiverById(receiverId); // 不存在或删除成功都返回成功
if (noticeReceiver == null) {
return ResponseEntity.ok(new Message<>("The relevant information of the recipient could not be found, please check whether the parameters are correct"));
}
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 = "Get a list of message notification recipients based on query filter items", @ApiOperation(value = "查询消息通知接收人", notes = "根据查询过滤项获取消息通知接收人列表")
notes = "根据查询过滤项获取消息通知接收人列表")
public ResponseEntity<Message<List<NoticeReceiver>>> getReceivers( public ResponseEntity<Message<List<NoticeReceiver>>> getReceivers(
@ApiParam(value = "en: Recipient name,zh: 接收人名称,模糊查询", example = "tom") @RequestParam(required = false) final String name) { @ApiParam(value = "接收人名称,模糊查询", example = "tom") @RequestParam(required = false) final String name) {
Specification<NoticeReceiver> specification = (root, query, criteriaBuilder) -> { Specification<NoticeReceiver> specification = (root, query, criteriaBuilder) -> {
Predicate predicate = criteriaBuilder.conjunction(); Predicate predicate = criteriaBuilder.conjunction();
@@ -89,38 +83,32 @@ public class NoticeConfigController {
@PostMapping(path = "/rule") @PostMapping(path = "/rule")
@ApiOperation(value = "Add a notification policy", notes = "新增一个通知策略") @ApiOperation(value = "新增通知策略", 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 = "Modify existing notification policy information", notes = "修改已存在的通知策略信息") @ApiOperation(value = "修改通知策略", 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 = "Delete existing notification policy information", notes = "删除已存在的通知策略信息") @ApiOperation(value = "删除指定通知策略", notes = "删除已存在的通知策略信息")
public ResponseEntity<Message<Void>> deleteNoticeRule( public ResponseEntity<Message<Void>> deleteNoticeRule(
@ApiParam(value = "en: Notification Policy ID,zh: 通知策略ID", example = "6565463543") @PathVariable("id") final Long ruleId) { @ApiParam(value = "通知策略ID", example = "6565463543") @PathVariable("id") final Long ruleId) {
// Returns success if it does not exist or if the deletion is successful // 不存在或删除成功都返回成功
// todo 不存在或删除成功都返回成功
NoticeRule noticeRule = noticeConfigService.getNoticeRulesById(ruleId);
if (noticeRule == null) {
return ResponseEntity.ok(new Message<>("The specified notification rule could not be queried, please check whether the parameters are correct"));
}
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 = "Get a list of message notification policies based on query filter items", @ApiOperation(value = "查询消息通知策略", notes = "根据查询过滤项获取消息通知策略列表")
notes = "根据查询过滤项获取消息通知策略列表")
public ResponseEntity<Message<List<NoticeRule>>> getRules( public ResponseEntity<Message<List<NoticeRule>>> getRules(
@ApiParam(value = "en: Recipient name,zh: 接收人名称,模糊查询", example = "rule1") @RequestParam(required = false) final String name) { @ApiParam(value = "接收人名称,模糊查询", 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();

View File

@@ -18,13 +18,11 @@ 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 = "en: System Summary Statistics API,zh: 系统摘要统计API") @Api(tags = "系统摘要统计API")
@RestController @RestController
@RequestMapping(path = "/summary", produces = {APPLICATION_JSON_VALUE}) @RequestMapping(path = "/summary", produces = {APPLICATION_JSON_VALUE})
public class SummaryController { public class SummaryController {
@@ -33,7 +31,7 @@ public class SummaryController {
private MonitorService monitorService; private MonitorService monitorService;
@GetMapping @GetMapping
@ApiOperation(value = "Query all application category monitoring statistics", notes = "查询所有应用类别监控统计信息") @ApiOperation(value = "查询应用类别监控统计", 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));

View File

@@ -14,7 +14,6 @@ import java.util.Set;
/** /**
* AuthResources 数据库操作 * AuthResources 数据库操作
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 11:24 * @date 2021/11/14 11:24
*/ */
@@ -22,63 +21,50 @@ public interface MonitorDao extends JpaRepository<Monitor, Long>, JpaSpecificati
/** /**
* Delete monitor based on monitor ID list
* 根据监控ID列表删除监控 * 根据监控ID列表删除监控
* * @param monitorIds 监控ID列表
* @param monitorIds Monitoring ID List 监控ID列表
*/ */
void deleteAllByIdIn(Set<Long> monitorIds); void deleteAllByIdIn(Set<Long> monitorIds);
/** /**
* Query monitoring based on monitoring ID list
* 根据监控ID列表查询监控 * 根据监控ID列表查询监控
* * @param monitorIds 监控ID列表
* @param monitorIds Monitoring ID List 监控ID列表 * @return 监控列表
* @return Monitor List 监控列表
*/ */
List<Monitor> findMonitorsByIdIn(Set<Long> monitorIds); List<Monitor> findMonitorsByIdIn(Set<Long> monitorIds);
/** /**
* Query monitoring by monitoring type
* 根据监控类型查询监控 * 根据监控类型查询监控
* * @param app 监控类型
* @param app Monitor Type 监控类型 * @return 监控列表
* @return Monitor List 监控列表
*/ */
List<Monitor> findMonitorsByAppEquals(String app); List<Monitor> findMonitorsByAppEquals(String app);
/** /**
* Querying Monitoring of Sent Collection Tasks
* 查询已下发采集任务的监控 * 查询已下发采集任务的监控
* * @param status 监控状态
* @param status Monitor Status 监控状态 * @return 监控列表
* @return Monitor List 监控列表
*/ */
List<Monitor> findMonitorsByStatusNotInAndAndJobIdNotNull(List<Byte> status); List<Monitor> findMonitorsByStatusNotInAndAndJobIdNotNull(List<Byte> status);
/** /**
* Query monitoring by monitoring name 根据监控名称查询监控 * 根据监控名称查询监控
* * @param name 监控名称
* @param name monitoring name 监控名称 * @return 监控列表
* @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 id Monitor ID 监控ID * @param status 监控状态
* @param status 监控状态 Monitor Status
*/ */
@Modifying @Modifying
@Query("update Monitor set status = :status where id = :id") @Query("update Monitor set status = :status where id = :id")

View File

@@ -8,34 +8,27 @@ import java.util.Set;
/** /**
* ParamDao 数据库操作 * ParamDao 数据库操作
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 11:26 * @date 2021/11/14 11:26
*/ */
public interface ParamDao extends JpaRepository<Param, Long> { public interface ParamDao extends JpaRepository<Param, Long> {
/** /**
* Query the list of parameters associated with the monitoring ID'
* 根据监控ID查询与之关联的参数列表 * 根据监控ID查询与之关联的参数列表
* * @param monitorId 监控ID
* @param monitorId Monitor ID 监控ID * @return 参数值列表
* @return list of parameter values 参数值列表
*/ */
List<Param> findParamsByMonitorId(long monitorId); List<Param> findParamsByMonitorId(long monitorId);
/** /**
* Remove the parameter list associated with the monitoring ID based on it
* 根据监控ID删除与之关联的参数列表 * 根据监控ID删除与之关联的参数列表
* * @param monitorId 监控ID
* @param monitorId Monitor Id 监控ID
*/ */
void deleteParamsByMonitorId(long monitorId); void deleteParamsByMonitorId(long monitorId);
/** /**
* Remove the parameter list associated with the monitoring ID list based on it
* 根据监控ID列表删除与之关联的参数列表 * 根据监控ID列表删除与之关联的参数列表
* * @param monitorIds 监控ID列表
* @param monitorIds Monitoring ID List 监控ID列表
*/ */
void deleteParamsByMonitorIdIn(Set<Long> monitorIds); void deleteParamsByMonitorIdIn(Set<Long> monitorIds);
} }

View File

@@ -14,18 +14,15 @@ 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;
/** /**
* Monitoring Information External Interaction Entities
* 监控信息对外交互实体 * 监控信息对外交互实体
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 10:13 * @date 2021/11/14 10:13
*/ */
@Data @Data
@ApiModel(description = "en: Monitoring information entities,zh: 监控信息实体") @ApiModel(description = "监控信息实体")
public class MonitorDto { public class MonitorDto {
/** /**
* Monitoring entity
* 监控实体 * 监控实体
*/ */
@ApiModelProperty(value = "监控实体", accessMode = READ_WRITE, position = 0) @ApiModelProperty(value = "监控实体", accessMode = READ_WRITE, position = 0)
@@ -34,22 +31,17 @@ public class MonitorDto {
private Monitor monitor; private Monitor monitor;
/** /**
* Params 参数 * 参数
*/ */
@ApiModelProperty(value = "监控参数", accessMode = READ_WRITE, position = 1) @ApiModelProperty(value = "监控参数", accessMode = READ_WRITE, position = 1)
@NotNull @NotNull
@Valid @Valid
private List<Param> params; private List<Param> params;
/**
* List of indicator groups
* 指标组列表
*/
@ApiModelProperty(value = "指标组列表", accessMode = READ_ONLY, position = 2) @ApiModelProperty(value = "指标组列表", accessMode = READ_ONLY, position = 2)
private List<String> metrics; private List<String> metrics;
/** /**
* Whether to detect
* 是否探测 * 是否探测
*/ */
@ApiModelProperty(value = "是否进行探测", accessMode = READ_WRITE, position = 3) @ApiModelProperty(value = "是否进行探测", accessMode = READ_WRITE, position = 3)

View File

@@ -9,7 +9,6 @@ import java.util.Map;
/** /**
* 监控类型管理接口 * 监控类型管理接口
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 17:12 * @date 2021/11/14 17:12
*/ */
@@ -17,26 +16,21 @@ public interface AppService {
/** /**
* 根据监控类型查询定义的参数结构 * 根据监控类型查询定义的参数结构
*
* @param app 监控类型 * @param app 监控类型
* @return 参数结构列表 * @return 参数结构列表
*/ */
List<ParamDefine> getAppParamDefines(String app); List<ParamDefine> getAppParamDefines(String app);
/** /**
* Get monitor structure definition based on monitor type name
* 根据监控类型名称获取监控结构定义 * 根据监控类型名称获取监控结构定义
* * @param app 监控类型名称
* @param app Monitoring type name 监控类型名称 * @return 监控结构定义
* @return Monitoring Structure Definition 监控结构定义 * @throws IllegalArgumentException 当不存在即不支持对应名称的监控类型时抛出
* @throws IllegalArgumentException Thrown when there is no monitoring type with the corresponding name that is not supported
* 当不存在即不支持对应名称的监控类型时抛出
*/ */
Job getAppDefine(String app) throws IllegalArgumentException; Job getAppDefine(String app) throws IllegalArgumentException;
/** /**
* 获取定义的监控I18N资源 * 获取定义的监控I18N资源
*
* @param lang 语言类型 * @param lang 语言类型
* @return I18N资源 * @return I18N资源
*/ */
@@ -44,7 +38,6 @@ public interface AppService {
/** /**
* 查询所有监控的类型-指标组-指标层级 * 查询所有监控的类型-指标组-指标层级
*
* @param lang 语言 * @param lang 语言
* @return 层级信息 * @return 层级信息
*/ */

View File

@@ -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,11 +15,9 @@ import org.springframework.stereotype.Service;
public interface MailService { public interface MailService {
/** /**
* Build an alert email template
* 构建告警邮件模版 * 构建告警邮件模版
* * @param alert 告警信息
* @param alert Alarm data element information 告警数据元信息 * @return 邮件内容
* @return content of email 邮件内容
*/ */
String buildAlertHtmlTemplate(Alert alert); String buildAlertHtmlTemplate(Alert alert);
} }

View File

@@ -15,7 +15,6 @@ import java.util.Set;
/** /**
* 监控管理服务 * 监控管理服务
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 11:28 * @date 2021/11/14 11:28
*/ */
@@ -23,130 +22,103 @@ public interface MonitorService {
/** /**
* Monitoring Availability Probes
* 监控可用性探测 * 监控可用性探测
* * @param monitor 监控实体信息
* @param monitor Monitoring entity information 监控实体信息 * @param params 参数信息
* @param params Parameter information 参数信息 * @throws MonitorDetectException 探测失败抛出
* @throws MonitorDetectException Probe failure throws 探测失败抛出
*/ */
void detectMonitor(Monitor monitor, List<Param> params) throws MonitorDetectException; void detectMonitor(Monitor monitor, List<Param> params) throws MonitorDetectException;
/** /**
* Add monitoring 新增监控 * 新增监控
* * @param monitor 监控实体
* @param monitor Monitoring Entity 监控实体 * @param params 参数信息
* @param params Parameter information 参数信息 * @throws RuntimeException 新增过程异常抛出
* @throws RuntimeException Add process exception throw 新增过程异常抛出
*/ */
void addMonitor(Monitor monitor, List<Param> params) throws RuntimeException; void addMonitor(Monitor monitor, List<Param> params) throws RuntimeException;
/** /**
* Verify the correctness of request data parameters
* 校验请求数据参数正确性 * 校验请求数据参数正确性
*
* @param monitorDto monitorDto * @param monitorDto monitorDto
* @param isModify Whether it is a modification monitoring 是否是修改监控 * @param isModify 是否是修改监控
* @throws IllegalArgumentException Validation parameter error thrown 校验参数错误抛出 * @throws IllegalArgumentException 校验参数错误抛出
*/ */
void validate(MonitorDto monitorDto, Boolean isModify) throws IllegalArgumentException; void validate(MonitorDto monitorDto, Boolean isModify) throws IllegalArgumentException;
/** /**
* Modify update monitoring
* 修改更新监控 * 修改更新监控
* * @param monitor 监控实体
* @param monitor Monitor Entity 监控实体 * @param params 参数信息
* @param params Parameter information 参数信息 * @throws RuntimeException 修改过程中异常抛出
* @throws RuntimeException Exception thrown during modification 修改过程中异常抛出
*/ */
void modifyMonitor(Monitor monitor, List<Param> params) throws RuntimeException; void modifyMonitor(Monitor monitor, List<Param> params) throws RuntimeException;
/** /**
* Delete Monitor
* 删除监控 * 删除监控
* * @param id 监控ID
* @param id Monitor ID 监控ID * @throws RuntimeException 删除过程中异常抛出
* @throws RuntimeException Exception thrown during deletion 删除过程中异常抛出
*/ */
void deleteMonitor(long id) throws RuntimeException; void deleteMonitor(long id) throws RuntimeException;
/** /**
* Batch delete monitoring
* 批量删除监控 * 批量删除监控
* * @param ids 监控ID
* @param ids Monitoring ID List 监控ID列表 * @throws RuntimeException 删除过程中异常抛出
* @throws RuntimeException Exception thrown during deletion 删除过程中异常抛出
*/ */
void deleteMonitors(Set<Long> ids) throws RuntimeException; void deleteMonitors(Set<Long> ids) throws RuntimeException;
/** /**
* Get monitoring information
* 获取监控信息 * 获取监控信息
* * @param id 监控ID
* @param id Monitor ID 监控ID * @return MonitorDto
* @return MonitorDto Monitor Entity 監控实体 * @throws RuntimeException 查询过程中异常抛出
* @throws RuntimeException Exception thrown during query 查询过程中异常抛出
*/ */
MonitorDto getMonitorDto(long id) throws RuntimeException; MonitorDto getMonitorDto(long id) throws RuntimeException;
/** /**
* Dynamic conditional query
* 动态条件查询 * 动态条件查询
* * @param specification 查询条件
* @param specification Query conditions 查询条件 * @param pageRequest 分页参数
* @param pageRequest Pagination parameters 分页参数 * @return 查询结果
* @return Search Result 查询结果
*/ */
Page<Monitor> getMonitors(Specification<Monitor> specification, PageRequest pageRequest); Page<Monitor> getMonitors(Specification<Monitor> specification, PageRequest pageRequest);
/** /**
* Unmanaged monitoring items in batches according to the monitoring ID list
* 根据监控ID列表批量取消纳管监控项 * 根据监控ID列表批量取消纳管监控项
* * @param ids 监控IDs
* @param ids Monitoring ID List 监控ID列表
*/ */
void cancelManageMonitors(HashSet<Long> ids); void cancelManageMonitors(HashSet<Long> ids);
/** /**
* Start the managed monitoring items in batches according to the monitoring ID list
* 根据监控ID列表批量启动纳管监控项 * 根据监控ID列表批量启动纳管监控项
* * @param ids 监控IDs
* @param ids Monitoring ID List 监控ID列表
*/ */
void enableManageMonitors(HashSet<Long> ids); void enableManageMonitors(HashSet<Long> ids);
/** /**
* Query the monitoring category and its corresponding monitoring quantity
* 查询监控类别及其对应的监控数量 * 查询监控类别及其对应的监控数量
* * @return 监控类别与监控数量映射
* @return Monitoring Category and Monitoring Quantity Mapping 监控类别与监控数量映射
*/ */
List<AppCount> getAllAppMonitorsCount(); List<AppCount> getAllAppMonitorsCount();
/** /**
* Query monitoring
* 查询监控 * 查询监控
* * @param monitorId 监控ID
* @param monitorId Monitor ID 监控ID * @return 监控信息
* @return Monitor information 监控信息
*/ */
Monitor getMonitor(Long monitorId); Monitor getMonitor(Long monitorId);
/** /**
* Update the status of the specified monitor
* 更新指定监控的状态 * 更新指定监控的状态
* * @param monitorId 监控ID
* @param monitorId monitorId 监控ID * @param status 监控状态
* @param status monitor status 监控状态
*/ */
void updateMonitorStatus(Long monitorId, byte status); void updateMonitorStatus(Long monitorId, byte status);
/** /**
* Query the list of all monitoring information under the specified monitoring type
* 查询指定监控类型下的所有监控信息列表 * 查询指定监控类型下的所有监控信息列表
* * @param app 监控类型
* @param app Monitor Type 监控类型 * @return 监控列表
* @return Monitor Entity List 监控列表
*/ */
List<Monitor> getAppMonitors(String app); List<Monitor> getAppMonitors(String app);
} }

View File

@@ -8,104 +8,66 @@ 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 查询条件
* @param specification Query conditions 查询条件 * @return 查询结果
* @return Search result 查询结果
*/ */
List<NoticeReceiver> getNoticeReceivers(Specification<NoticeReceiver> specification); List<NoticeReceiver> getNoticeReceivers(Specification<NoticeReceiver> specification);
/** /**
* Dynamic conditional query
* 动态条件查询 * 动态条件查询
* * @param specification 查询条件
* @param specification Query conditions 查询条件 * @return 查询结果
* @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 告警信息
* @param alert Alarm information 告警信息 * @return 接收人
* @return Receiver 接收人
*/ */
List<NoticeReceiver> getReceiverFilterRule(Alert alert); List<NoticeReceiver> getReceiverFilterRule(Alert alert);
/**
* Query recipient information based on recipient ID (primary key Id)
* 根据接收人ID(主键Id)查询接收人信息
*
* @param receiverId Receiver ID (primary key ID) 接收人ID(主键ID)
* @return Recipient Entity 接收人实体
*/
NoticeReceiver getReceiverById(Long receiverId);
/**
* Query specific notification rules according to the rule ID (primary key ID)
* 根据规则ID(主键ID)查询具体通知规则
*
* @param ruleId Rule ID 规则ID(主键ID)
* @return Notification Rule Entity 通知规则实体
*/
NoticeRule getNoticeRulesById(Long ruleId);
} }

View File

@@ -1,6 +1,5 @@
package com.usthe.manager.service.impl; package com.usthe.manager.service.impl;
import com.usthe.alert.AlerterProperties;
import com.usthe.common.entity.alerter.Alert; import com.usthe.common.entity.alerter.Alert;
import com.usthe.common.util.CommonUtil; import com.usthe.common.util.CommonUtil;
import com.usthe.manager.service.MailService; import com.usthe.manager.service.MailService;
@@ -12,7 +11,6 @@ import org.thymeleaf.context.Context;
import javax.annotation.Resource; import javax.annotation.Resource;
/** /**
* Mailbox sending service interface implementation class
* 邮箱发送服务接口实现类 * 邮箱发送服务接口实现类
* *
* @author 花城 * @author 花城
@@ -25,20 +23,16 @@ public class MailServiceImpl implements MailService {
@Resource @Resource
private TemplateEngine templateEngine; private TemplateEngine templateEngine;
@Resource
private AlerterProperties alerterProperties;
@Override @Override
public String buildAlertHtmlTemplate(final Alert alert) { public String buildAlertHtmlTemplate(final Alert alert) {
// Introduce thymeleaf context parameters to render pages
// 引入thymeleaf上下文参数渲染页面 // 引入thymeleaf上下文参数渲染页面
Context context = new Context(); Context context = new Context();
context.setVariable("target", alert.getTarget()); context.setVariable("target",alert.getTarget());
context.setVariable("monitorId", alert.getMonitorId()); context.setVariable("monitorId",alert.getMonitorId());
context.setVariable("monitorName", alert.getMonitorName()); context.setVariable("monitorName",alert.getMonitorName());
context.setVariable("priority", CommonUtil.transferAlertPriority(alert.getPriority())); context.setVariable("priority", CommonUtil.transferAlertPriority(alert.getPriority()));
context.setVariable("content", alert.getContent()); context.setVariable("content",alert.getContent());
context.setVariable("consoleUrl", alerterProperties.getConsoleUrl());
return templateEngine.process("mailAlarm", context); return templateEngine.process("mailAlarm", context);
} }
} }

View File

@@ -40,7 +40,6 @@ import java.util.stream.Collectors;
/** /**
* 监控管理服务实现 * 监控管理服务实现
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 13:06 * @date 2021/11/14 13:06
*/ */
@@ -80,13 +79,11 @@ 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);
// To detect availability, you only need to collect the set of availability indicators with a priority of 0.
// 探测可用性只需要采集优先级为0的可用性指标集合 // 探测可用性只需要采集优先级为0的可用性指标集合
List<Metrics> availableMetrics = appDefine.getMetrics().stream() List<Metrics> availableMetrics = appDefine.getMetrics().stream()
.filter(item -> item.getPriority() == 0).collect(Collectors.toList()); .filter(item -> item.getPriority() == 0).collect(Collectors.toList());
appDefine.setMetrics(availableMetrics); appDefine.setMetrics(availableMetrics);
List<CollectRep.MetricsData> collectRep = collectJobService.collectSyncJobData(appDefine); List<CollectRep.MetricsData> collectRep = collectJobService.collectSyncJobData(appDefine);
// If the detection result fails, a detection exception is thrown
// 判断探测结果 失败则抛出探测异常 // 判断探测结果 失败则抛出探测异常
if (collectRep == null || collectRep.isEmpty()) { if (collectRep == null || collectRep.isEmpty()) {
throw new MonitorDetectException("No collector response"); throw new MonitorDetectException("No collector response");
@@ -99,9 +96,9 @@ public class MonitorServiceImpl implements MonitorService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void addMonitor(Monitor monitor, List<Param> params) throws RuntimeException { public void addMonitor(Monitor monitor, List<Param> params) throws RuntimeException {
// Apply for monitor id 申请 monitor id // 申请 monitor id
long monitorId = SnowFlakeIdGenerator.generateId(); long monitorId = SnowFlakeIdGenerator.generateId();
// Construct the collection task Job entity 构造采集任务Job实体 // 构造采集任务Job实体
Job appDefine = appService.getAppDefine(monitor.getApp()); Job appDefine = appService.getAppDefine(monitor.getApp());
appDefine.setMonitorId(monitorId); appDefine.setMonitorId(monitorId);
appDefine.setInterval(monitor.getIntervals()); appDefine.setInterval(monitor.getIntervals());
@@ -112,10 +109,8 @@ public class MonitorServiceImpl implements MonitorService {
return new Configmap(param.getField(), param.getValue(), param.getType()); return new Configmap(param.getField(), param.getValue(), param.getType());
}).collect(Collectors.toList()); }).collect(Collectors.toList());
appDefine.setConfigmap(configmaps); appDefine.setConfigmap(configmaps);
// Send the collection task to get the job ID
// 下发采集任务得到jobId // 下发采集任务得到jobId
long jobId = collectJobService.addAsyncCollectJob(appDefine); long jobId = collectJobService.addAsyncCollectJob(appDefine);
// Brush the library after the download is successful
// 下发成功后刷库 // 下发成功后刷库
try { try {
monitor.setId(monitorId); monitor.setId(monitorId);
@@ -125,7 +120,6 @@ public class MonitorServiceImpl implements MonitorService {
paramDao.saveAll(params); paramDao.saveAll(params);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
// Repository brushing abnormally cancels the previously delivered task
// 刷库异常取消之前的下发任务 // 刷库异常取消之前的下发任务
collectJobService.cancelAsyncCollectJob(jobId); collectJobService.cancelAsyncCollectJob(jobId);
throw new MonitorDatabaseException(e.getMessage()); throw new MonitorDatabaseException(e.getMessage());
@@ -135,7 +129,6 @@ public class MonitorServiceImpl implements MonitorService {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public void validate(MonitorDto monitorDto, Boolean isModify) throws IllegalArgumentException { public void validate(MonitorDto monitorDto, Boolean isModify) throws IllegalArgumentException {
// The request monitoring parameter matches the monitoring parameter definition mapping check
// 请求监控参数与监控参数定义映射校验匹配 // 请求监控参数与监控参数定义映射校验匹配
Monitor monitor = monitorDto.getMonitor(); Monitor monitor = monitorDto.getMonitor();
monitor.setHost(monitor.getHost().trim()); monitor.setHost(monitor.getHost().trim());
@@ -148,7 +141,7 @@ public class MonitorServiceImpl implements MonitorService {
param.setValue(value); param.setValue(value);
}) })
.collect(Collectors.toMap(Param::getField, param -> param)); .collect(Collectors.toMap(Param::getField, param -> param));
// Check name uniqueness 校验名称唯一性 // 校验名称唯一性
if (isModify != null) { if (isModify != null) {
Optional<Monitor> monitorOptional = monitorDao.findMonitorByNameEquals(monitor.getName()); Optional<Monitor> monitorOptional = monitorDao.findMonitorByNameEquals(monitor.getName());
if (monitorOptional.isPresent()) { if (monitorOptional.isPresent()) {
@@ -163,7 +156,7 @@ public class MonitorServiceImpl implements MonitorService {
} }
} }
// Parameter definition structure verification 参数定义结构校验 // 参数定义结构校验
List<ParamDefine> paramDefines = appService.getAppParamDefines(monitorDto.getMonitor().getApp()); List<ParamDefine> paramDefines = appService.getAppParamDefines(monitorDto.getMonitor().getApp());
if (paramDefines != null) { if (paramDefines != null) {
for (ParamDefine paramDefine : paramDefines) { for (ParamDefine paramDefine : paramDefines) {
@@ -209,7 +202,6 @@ public class MonitorServiceImpl implements MonitorService {
} }
break; break;
case "password": case "password":
// The plaintext password needs to be encrypted for transmission and storage
// 明文密码需加密传输存储 // 明文密码需加密传输存储
String passwordValue = param.getValue(); String passwordValue = param.getValue();
if (!AesUtil.isCiphertext(passwordValue)) { if (!AesUtil.isCiphertext(passwordValue)) {
@@ -219,7 +211,7 @@ public class MonitorServiceImpl implements MonitorService {
param.setType(CommonConstants.PARAM_TYPE_PASSWORD); param.setType(CommonConstants.PARAM_TYPE_PASSWORD);
break; break;
case "boolean": case "boolean":
// boolean check // boolean校验
String booleanValue = param.getValue(); String booleanValue = param.getValue();
try { try {
Boolean.parseBoolean(booleanValue); Boolean.parseBoolean(booleanValue);
@@ -229,7 +221,7 @@ public class MonitorServiceImpl implements MonitorService {
} }
break; break;
case "radio": case "radio":
// radio single value check radio单选值校验 // radio单选值校验
List<ParamDefine.Option> options = paramDefine.getOptions(); List<ParamDefine.Option> options = paramDefine.getOptions();
boolean invalid = true; boolean invalid = true;
if (options != null) { if (options != null) {
@@ -251,8 +243,7 @@ public class MonitorServiceImpl implements MonitorService {
case "key-value": case "key-value":
// todo key-value校验 // todo key-value校验
break; break;
// todo More parameter definitions and actual value format verification // todo 更多参数定义与实际值格式校验
// 更多参数定义与实际值格式校验
default: default:
throw new IllegalArgumentException("ParamDefine type " + paramDefine.getType() + " is invalid."); throw new IllegalArgumentException("ParamDefine type " + paramDefine.getType() + " is invalid.");
} }
@@ -262,10 +253,8 @@ public class MonitorServiceImpl implements MonitorService {
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void modifyMonitor(Monitor monitor, List<Param> params) throws RuntimeException { public void modifyMonitor(Monitor monitor, List<Param> params) throws RuntimeException {
long monitorId = monitor.getId(); long monitorId = monitor.getId();
// Check to determine whether the monitor corresponding to the monitor Id exists
// 查判断monitorId对应的此监控是否存在 // 查判断monitorId对应的此监控是否存在
Optional<Monitor> queryOption = monitorDao.findById(monitorId); Optional<Monitor> queryOption = monitorDao.findById(monitorId);
if (!queryOption.isPresent()) { if (!queryOption.isPresent()) {
@@ -273,11 +262,9 @@ public class MonitorServiceImpl implements MonitorService {
} }
Monitor preMonitor = queryOption.get(); Monitor preMonitor = queryOption.get();
if (!preMonitor.getApp().equals(monitor.getApp())) { if (!preMonitor.getApp().equals(monitor.getApp())) {
// The type of monitoring cannot be modified
// 监控的类型不能修改 // 监控的类型不能修改
throw new IllegalArgumentException("Can not modify monitor's app type"); throw new IllegalArgumentException("Can not modify monitor's app type");
} }
// Construct the collection task Job entity
// 构造采集任务Job实体 // 构造采集任务Job实体
Job appDefine = appService.getAppDefine(monitor.getApp()); Job appDefine = appService.getAppDefine(monitor.getApp());
appDefine.setId(preMonitor.getJobId()); appDefine.setId(preMonitor.getJobId());
@@ -288,16 +275,14 @@ 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);
// After the update is successfully released, refresh the library // 更新采集任务
collectJobService.updateAsyncCollectJob(appDefine);
// 下发更新成功后刷库 // 下发更新成功后刷库
try { try {
monitor.setJobId(preMonitor.getJobId()); monitor.setJobId(preMonitor.getJobId());
monitor.setStatus(preMonitor.getStatus()); monitor.setStatus(preMonitor.getStatus());
monitorDao.save(monitor); monitorDao.save(monitor);
paramDao.saveAll(params); paramDao.saveAll(params);
// Update the collection task after the storage is completed
// 入库完成后更新采集任务
collectJobService.updateAsyncCollectJob(appDefine);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
throw new MonitorDatabaseException(e.getMessage()); throw new MonitorDatabaseException(e.getMessage());
@@ -358,9 +343,7 @@ public class MonitorServiceImpl implements MonitorService {
@Override @Override
public void cancelManageMonitors(HashSet<Long> ids) { public void cancelManageMonitors(HashSet<Long> ids) {
// Update monitoring status Delete corresponding monitoring periodic task
// 更新监控状态 删除对应的监控周期性任务 // 更新监控状态 删除对应的监控周期性任务
// The jobId is not deleted, and the jobId is reused again after the management is started.
// jobId不删除 待启动纳管之后再次复用jobId // jobId不删除 待启动纳管之后再次复用jobId
List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids) List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids)
.stream().filter(monitor -> .stream().filter(monitor ->
@@ -377,7 +360,6 @@ public class MonitorServiceImpl implements MonitorService {
@Override @Override
public void enableManageMonitors(HashSet<Long> ids) { public void enableManageMonitors(HashSet<Long> ids) {
// Update monitoring status Add corresponding monitoring periodic task
// 更新监控状态 新增对应的监控周期性任务 // 更新监控状态 新增对应的监控周期性任务
List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids) List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids)
.stream().filter(monitor -> .stream().filter(monitor ->
@@ -387,7 +369,6 @@ public class MonitorServiceImpl implements MonitorService {
if (!unManagedMonitors.isEmpty()) { if (!unManagedMonitors.isEmpty()) {
monitorDao.saveAll(unManagedMonitors); monitorDao.saveAll(unManagedMonitors);
for (Monitor monitor : unManagedMonitors) { for (Monitor monitor : unManagedMonitors) {
// Construct the collection task Job entity
// 构造采集任务Job实体 // 构造采集任务Job实体
Job appDefine = appService.getAppDefine(monitor.getApp()); Job appDefine = appService.getAppDefine(monitor.getApp());
appDefine.setMonitorId(monitor.getId()); appDefine.setMonitorId(monitor.getId());
@@ -398,7 +379,7 @@ 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);
// Issue collection tasks 下发采集任务 // 下发采集任务
collectJobService.addAsyncCollectJob(appDefine); collectJobService.addAsyncCollectJob(appDefine);
} }
} }
@@ -410,8 +391,7 @@ 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());
@@ -429,13 +409,10 @@ 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: default: break;
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());

View File

@@ -18,7 +18,6 @@ import java.util.stream.Collectors;
/** /**
* 消息通知配置实现 * 消息通知配置实现
*
* @author tom * @author tom
* @date 2021/12/16 16:16 * @date 2021/12/16 16:16
*/ */
@@ -75,24 +74,13 @@ public class NoticeConfigServiceImpl implements NoticeConfigService {
@Override @Override
public List<NoticeReceiver> getReceiverFilterRule(Alert alert) { public List<NoticeReceiver> getReceiverFilterRule(Alert alert) {
// todo use cache 使用缓存 // todo 使用缓存
List<NoticeRule> rules = noticeRuleDao.findNoticeRulesByEnableTrue(); List<NoticeRule> rules = noticeRuleDao.findNoticeRulesByEnableTrue();
// todo The temporary rule is to forward all, and then implement more matching rules: alarm status selection, monitoring type selection, etc. // todo 暂时规则是全部转发 后面实现更多匹配规则:告警状态选择 监控类型选择等
// 暂时规则是全部转发 后面实现更多匹配规则:告警状态选择 监控类型选择等
Set<Long> receiverIds = rules.stream() Set<Long> receiverIds = rules.stream()
.filter(NoticeRule::isFilterAll) .filter(NoticeRule::isFilterAll)
.map(NoticeRule::getReceiverId) .map(NoticeRule::getReceiverId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
return noticeReceiverDao.findAllById(receiverIds); return noticeReceiverDao.findAllById(receiverIds);
} }
@Override
public NoticeReceiver getReceiverById(Long receiverId) {
return noticeReceiverDao.getOne(receiverId);
}
@Override
public NoticeRule getNoticeRulesById(Long ruleId) {
return noticeRuleDao.getOne(ruleId);
}
} }

View File

@@ -69,8 +69,3 @@ warehouse:
url: jdbc:TAOS-RS://localhost:6041/hertzbeat url: jdbc:TAOS-RS://localhost:6041/hertzbeat
username: root username: root
password: taosdata password: taosdata
#自定义告警控制台地址
alerter:
#这里就是我们的自定义控制台地址
console-url: https://console.tancloud.cn

View File

@@ -2,35 +2,10 @@
# 加载到匹配字典的资源,也就是需要被保护的,设置了所支持角色访问的资源 # 加载到匹配字典的资源,也就是需要被保护的,设置了所支持角色访问的资源
# 没有配置的资源也默认被认证保护,但不鉴权 # 没有配置的资源也默认被认证保护,但不鉴权
# eg: /api/v1/source1===get===[admin] 表示 /api/v2/host===post 这条资源支持 admin 这一种角色访问 # eg: /api/v1/source1===get===[role2] 表示 /api/v2/host===post 这条资源支持 role2 这一种角色访问
# eg: /api/v1/source2===get===[] 表示 /api/v1/source2===get 这条资源不支持任何角色访问 # eg: /api/v1/source2===get===[] 表示 /api/v1/source2===get 这条资源不支持任何角色访问
resourceRole: resourceRole:
- /account/auth/refresh===post===[admin,user,guest] - /account/auth/refresh===post===[role1,role2,role3,role4]
- /apps/**===get===[admin,user,guest]
- /monitor/**===get===[admin,user,guest]
- /monitor/**===post===[admin,user]
- /monitor/**===put===[admin,user]
- /monitor/**===delete==[admin]
- /monitors/**===get===[admin,user,guest]
- /monitors/**===post===[admin,user]
- /monitors/**===put===[admin,user]
- /monitors/**===delete===[admin]
- /alert/**===get===[admin,user,guest]
- /alert/**===post===[admin,user]
- /alert/**===put===[admin,user]
- /alert/**===delete===[admin]
- /alerts/**===get===[admin,user,guest]
- /alerts/**===post===[admin,user]
- /alerts/**===put===[admin,user]
- /alerts/**===delete===[admin]
- /notice/**===get===[admin,user,guest]
- /notice/**===post===[admin,user]
- /notice/**===put===[admin,user]
- /notice/**===delete===[admin]
- /summary/**===get===[admin,user,guest]
- /summary/**===post===[admin,user]
- /summary/**===put===[admin,user]
- /summary/**===delete===[admin]
# 需要被过滤保护的资源,不认证鉴权直接访问 # 需要被过滤保护的资源,不认证鉴权直接访问
# /api/v1/source3===get 表示 /api/v1/source3===get 可以被任何人访问 无需登录认证鉴权 # /api/v1/source3===get 表示 /api/v1/source3===get 可以被任何人访问 无需登录认证鉴权
@@ -56,23 +31,20 @@ excludedResource:
# 用户账户信息 # 用户账户信息
# 下面有 admin tom lili 三个账户 # 下面有 admin tom lili 三个账户
# eg: admin 拥有[admin,user]角色,密码为admin # eg: admin 拥有[role1,role2]角色,密码为admin
# eg: tom 拥有[user],密码为tom@123 # eg: tom 拥有[role1,role2,role3],密码为tom@123
# eg: lili 拥有[guest],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289 # eg: lili 拥有[role1,role2],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289
account: account:
- appId: admin - appId: admin
credential: admin credential: admin
role: [admin,user] role: [role1,role2]
- appId: tom - appId: tom
credential: tom@123 credential: tom@123
role: [user] role: [role1,role2,role3]
- appId: guest
credential: guest
role: [guest]
- appId: lili - appId: lili
# 注意 Digest认证不支持加盐加密的密码账户 # 注意 Digest认证不支持加盐加密的密码账户
# 加盐加密的密码,通过 MD5(password+salt)计算 # 加盐加密的密码,通过 MD5(password+salt)计算
# 此账户的原始密码为 lili # 此账户的原始密码为 lili
credential: 1A676730B0C7F54654B0E09184448289 credential: 1A676730B0C7F54654B0E09184448289
salt: 123 salt: 123
role: [guest] role: [role1,role2]

View File

@@ -700,7 +700,7 @@
<span style="font-family:Arial, Verdana; font-size:14px;color:#FFFFFF;"><a <span style="font-family:Arial, Verdana; font-size:14px;color:#FFFFFF;"><a
target="_blank" target="_blank"
style="color:#FFFFFF;text-decoration:none;" style="color:#FFFFFF;text-decoration:none;"
th:href="${consoleUrl}" href="https://console.tancloud.cn"
data-link-type="web">登入控制台</a></span> data-link-type="web">登入控制台</a></span>
</td> </td>
</tr> </tr>

View File

@@ -2,9 +2,11 @@
@echo off @echo off
setlocal enabledelayedexpansion setlocal enabledelayedexpansion
rem 项目名称
set SERVER_NAME="${project.artifactId}" set SERVER_NAME="${project.artifactId}"
rem 应用的端口号
set SERVER_PORT=1157 set SERVER_PORT=1157
echo Start shutdown HertzBeat %SERVER_NAME% echo Start shutdown HertzBeat %SERVER_NAME%

View File

@@ -2,21 +2,25 @@
@echo off @echo off
setlocal enabledelayedexpansion setlocal enabledelayedexpansion
rem 项目名称
set SERVER_NAME=${project.artifactId} set SERVER_NAME=${project.artifactId}
rem jar名称
set JAR_NAME=${project.build.finalName}.jar set JAR_NAME=${project.build.finalName}.jar
rem enter the bin directory rem 进入bin目录
cd /d %~dp0 cd /d %~dp0
rem 返回到上一级项目根目录路径
cd .. cd ..
rem 打印项目安装根目录绝对路径
set DEPLOY_DIR=%~dp0.. set DEPLOY_DIR=%~dp0..
echo %DEPLOY_DIR% echo %DEPLOY_DIR%
rem 外部配置文件绝对目录,如果是目录需要/结尾,也可以直接指定文件
rem 如果指定的是目录,spring则会读取目录中的所有配置文件
set CONF_DIR=%DEPLOY_DIR%\config set CONF_DIR=%DEPLOY_DIR%\config
echo %CONF_DIR% echo %CONF_DIR%
rem 应用的端口号
set SERVER_PORT=1157 set SERVER_PORT=1157
for /f "tokens=1-5" %%i in ('netstat -ano^|findstr "0.0.0.0:%SERVER_PORT%"') do ( for /f "tokens=1-5" %%i in ('netstat -ano^|findstr "0.0.0.0:%SERVER_PORT%"') do (
@@ -25,6 +29,8 @@ for /f "tokens=1-5" %%i in ('netstat -ano^|findstr "0.0.0.0:%SERVER_PORT%"') do
goto q goto q
) )
rem 项目日志输出绝对路径
set LOGS_DIR=%DEPLOY_DIR%\logs set LOGS_DIR=%DEPLOY_DIR%\logs
rem JVM Configuration rem JVM Configuration
@@ -32,9 +38,9 @@ set JAVA_OPTS= -Duser.timezone=Asia/Shanghai
set JAVA_MEM_OPTS= -server -XX:SurvivorRatio=6 -XX:+UseParallelGC set JAVA_MEM_OPTS= -server -XX:SurvivorRatio=6 -XX:+UseParallelGC
rem 加载外部log文件的配置
set LOGGING_CONFIG=-Dlogging.config=%CONF_DIR%\logback-spring.xml 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%/ set CONFIG_FILES= -Dlogging.path=%LOGS_DIR% %LOGGING_CONFIG% -Dspring.config.location=%CONF_DIR%/
echo Starting the %SERVER_NAME% ... echo Starting the %SERVER_NAME% ...

View File

@@ -2,35 +2,10 @@
# 加载到匹配字典的资源,也就是需要被保护的,设置了所支持角色访问的资源 # 加载到匹配字典的资源,也就是需要被保护的,设置了所支持角色访问的资源
# 没有配置的资源也默认被认证保护,但不鉴权 # 没有配置的资源也默认被认证保护,但不鉴权
# eg: /api/v1/source1===get===[admin] 表示 /api/v2/host===post 这条资源支持 admin 这一种角色访问 # eg: /api/v1/source1===get===[role2] 表示 /api/v2/host===post 这条资源支持 role2 这一种角色访问
# eg: /api/v1/source2===get===[] 表示 /api/v1/source2===get 这条资源不支持任何角色访问 # eg: /api/v1/source2===get===[] 表示 /api/v1/source2===get 这条资源不支持任何角色访问
resourceRole: resourceRole:
- /account/auth/refresh===post===[admin,user,guest] - /account/auth/refresh===post===[role1,role2,role3,role4]
- /apps/**===get===[admin,user,guest]
- /monitor/**===get===[admin,user,guest]
- /monitor/**===post===[admin,user]
- /monitor/**===put===[admin,user]
- /monitor/**===delete==[admin]
- /monitors/**===get===[admin,user,guest]
- /monitors/**===post===[admin,user]
- /monitors/**===put===[admin,user]
- /monitors/**===delete===[admin]
- /alert/**===get===[admin,user,guest]
- /alert/**===post===[admin,user]
- /alert/**===put===[admin,user]
- /alert/**===delete===[admin]
- /alerts/**===get===[admin,user,guest]
- /alerts/**===post===[admin,user]
- /alerts/**===put===[admin,user]
- /alerts/**===delete===[admin]
- /notice/**===get===[admin,user,guest]
- /notice/**===post===[admin,user]
- /notice/**===put===[admin,user]
- /notice/**===delete===[admin]
- /summary/**===get===[admin,user,guest]
- /summary/**===post===[admin,user]
- /summary/**===put===[admin,user]
- /summary/**===delete===[admin]
# 需要被过滤保护的资源,不认证鉴权直接访问 # 需要被过滤保护的资源,不认证鉴权直接访问
# /api/v1/source3===get 表示 /api/v1/source3===get 可以被任何人访问 无需登录认证鉴权 # /api/v1/source3===get 表示 /api/v1/source3===get 可以被任何人访问 无需登录认证鉴权
@@ -56,23 +31,20 @@ excludedResource:
# 用户账户信息 # 用户账户信息
# 下面有 admin tom lili 三个账户 # 下面有 admin tom lili 三个账户
# eg: admin 拥有[admin,user]角色,密码为admin # eg: admin 拥有[role1,role2]角色,密码为admin
# eg: tom 拥有[user],密码为tom@123 # eg: tom 拥有[role1,role2,role3],密码为tom@123
# eg: lili 拥有[guest],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289 # eg: lili 拥有[role1,role2],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289
account: account:
- appId: admin - appId: admin
credential: admin credential: admin
role: [admin,user] role: [role1,role2]
- appId: tom - appId: tom
credential: tom@123 credential: tom
role: [user] role: [role1,role2,role3]
- appId: guest
credential: guest
role: [guest]
- appId: lili - appId: lili
# 注意 Digest认证不支持加盐加密的密码账户 # 注意 Digest认证不支持加盐加密的密码账户
# 加盐加密的密码,通过 MD5(password+salt)计算 # 加盐加密的密码,通过 MD5(password+salt)计算
# 此账户的原始密码为 lili # 此账户的原始密码为 lili
credential: 1A676730B0C7F54654B0E09184448289 credential: 1A676730B0C7F54654B0E09194448289
salt: 123 salt: 123
role: [guest] role: [role1,role2]

View File

@@ -26,8 +26,6 @@ services:
container_name: tdengine container_name: tdengine
hostname: tdengine hostname: tdengine
restart: always restart: always
environment:
TZ: Asia/Shanghai
ports: ports:
- "6030-6049:6030-6049" - "6030-6049:6030-6049"
- "6030-6049:6030-6049/udp" - "6030-6049:6030-6049/udp"

View File

@@ -2,35 +2,10 @@
# 加载到匹配字典的资源,也就是需要被保护的,设置了所支持角色访问的资源 # 加载到匹配字典的资源,也就是需要被保护的,设置了所支持角色访问的资源
# 没有配置的资源也默认被认证保护,但不鉴权 # 没有配置的资源也默认被认证保护,但不鉴权
# eg: /api/v1/source1===get===[admin] 表示 /api/v2/host===post 这条资源支持 admin 这一种角色访问 # eg: /api/v1/source1===get===[role2] 表示 /api/v2/host===post 这条资源支持 role2 这一种角色访问
# eg: /api/v1/source2===get===[] 表示 /api/v1/source2===get 这条资源不支持任何角色访问 # eg: /api/v1/source2===get===[] 表示 /api/v1/source2===get 这条资源不支持任何角色访问
resourceRole: resourceRole:
- /account/auth/refresh===post===[admin,user,guest] - /account/auth/refresh===post===[role1,role2,role3,role4]
- /apps/**===get===[admin,user,guest]
- /monitor/**===get===[admin,user,guest]
- /monitor/**===post===[admin,user]
- /monitor/**===put===[admin,user]
- /monitor/**===delete==[admin]
- /monitors/**===get===[admin,user,guest]
- /monitors/**===post===[admin,user]
- /monitors/**===put===[admin,user]
- /monitors/**===delete===[admin]
- /alert/**===get===[admin,user,guest]
- /alert/**===post===[admin,user]
- /alert/**===put===[admin,user]
- /alert/**===delete===[admin]
- /alerts/**===get===[admin,user,guest]
- /alerts/**===post===[admin,user]
- /alerts/**===put===[admin,user]
- /alerts/**===delete===[admin]
- /notice/**===get===[admin,user,guest]
- /notice/**===post===[admin,user]
- /notice/**===put===[admin,user]
- /notice/**===delete===[admin]
- /summary/**===get===[admin,user,guest]
- /summary/**===post===[admin,user]
- /summary/**===put===[admin,user]
- /summary/**===delete===[admin]
# 需要被过滤保护的资源,不认证鉴权直接访问 # 需要被过滤保护的资源,不认证鉴权直接访问
# /api/v1/source3===get 表示 /api/v1/source3===get 可以被任何人访问 无需登录认证鉴权 # /api/v1/source3===get 表示 /api/v1/source3===get 可以被任何人访问 无需登录认证鉴权
@@ -48,7 +23,7 @@ excludedResource:
- /**/*.ttf===get - /**/*.ttf===get
- /**/*.png===get - /**/*.png===get
- /**/*.gif===get - /**/*.gif===get
- /**/*.png===* - /**/*.png===*
# swagger ui 资源 # swagger ui 资源
- /swagger-resources/**===get - /swagger-resources/**===get
- /v2/api-docs===get - /v2/api-docs===get
@@ -56,23 +31,20 @@ excludedResource:
# 用户账户信息 # 用户账户信息
# 下面有 admin tom lili 三个账户 # 下面有 admin tom lili 三个账户
# eg: admin 拥有[admin,user]角色,密码为admin # eg: admin 拥有[role1,role2]角色,密码为admin
# eg: tom 拥有[user],密码为tom@123 # eg: tom 拥有[role1,role2,role3],密码为tom@123
# eg: lili 拥有[guest],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289 # eg: lili 拥有[role1,role2],明文密码为lili, 加盐密码为1A676730B0C7F54654B0E09184448289
account: account:
- appId: admin - appId: admin
credential: admin credential: admin
role: [admin,user] role: [role1,role2]
- appId: tom - appId: tom
credential: tom@123 credential: tom@123
role: [user] role: [role1,role2,role3]
- appId: guest
credential: guest
role: [guest]
- appId: lili - appId: lili
# 注意 Digest认证不支持加盐加密的密码账户 # 注意 Digest认证不支持加盐加密的密码账户
# 加盐加密的密码,通过 MD5(password+salt)计算 # 加盐加密的密码,通过 MD5(password+salt)计算
# 此账户的原始密码为 lili # 此账户的原始密码为 lili
credential: 1A676730B0C7F54654B0E09184448289 credential: 1A676730B0C7F54654B0E09184448289
salt: 123 salt: 123
role: [guest] role: [role1,role2]

View File

@@ -26,8 +26,8 @@ const CODE_MESSAGE: { [key: number]: string } = {
202: '一个请求已经进入后台排队(异步任务)。', 202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。', 204: '删除数据成功。',
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户认证信息异常。', 401: '用户没有权限(令牌、用户名、密码错误)。',
403: '用户无此操作权限。', 403: '用户无权限访问此资源。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
406: '请求的格式不可得。', 406: '请求的格式不可得。',
409: '请求与服务器端目标资源的当前状态相冲突', 409: '请求与服务器端目标资源的当前状态相冲突',
@@ -65,11 +65,7 @@ export class DefaultInterceptor implements HttpInterceptor {
private checkStatus(ev: HttpResponseBase): void { private checkStatus(ev: HttpResponseBase): void {
const errorText = CODE_MESSAGE[ev.status] || ev.statusText; const errorText = CODE_MESSAGE[ev.status] || ev.statusText;
console.warn(` ${ev.status}: ${ev.url}`, errorText); console.warn(` ${ev.status}: ${ev.url}`, errorText);
if (ev.status == 403) { this.notification.error(` ${ev.status}: ${ev.url}`, errorText);
this.notification.error(` ${ev.status}: ${errorText}`, '');
} else {
this.notification.error(` ${ev.status}: ${ev.url}`, errorText);
}
} }
/** /**

View File

@@ -54,7 +54,7 @@ export class HeaderNotifyComponent implements OnInit {
return; return;
} }
this.loading = true; this.loading = true;
let loadAlerts$ = this.alertSvc.loadAlerts(0, undefined, undefined, 0, 5).subscribe( let loadAlerts$ = this.alertSvc.searchAlerts(0, undefined, undefined, 0, 5).subscribe(
message => { message => {
loadAlerts$.unsubscribe(); loadAlerts$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {

View File

@@ -30,7 +30,7 @@
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="loadAlertsTable()"> <button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchAlerts()">
{{ 'common.search' | i18n }} {{ 'common.search' | i18n }}
</button> </button>
<input <input
@@ -39,7 +39,7 @@
type="text" type="text"
[placeholder]="'alert.center.search' | i18n" [placeholder]="'alert.center.search' | i18n"
nzSize="default" nzSize="default"
(keyup.enter)="loadAlertsTable()" (keyup.enter)="onFilterSearchAlerts()"
[(ngModel)]="filterContent" [(ngModel)]="filterContent"
/> />
<nz-select <nz-select

View File

@@ -36,16 +36,13 @@ export class AlertCenterComponent implements OnInit {
this.loadAlertsTable(); this.loadAlertsTable();
} }
sync() { onFilterSearchAlerts() {
this.loadAlertsTable();
}
loadAlertsTable() {
this.tableLoading = true; this.tableLoading = true;
let alertsInit$ = this.alertSvc let filterAlerts$ = this.alertSvc
.loadAlerts(this.filterStatus, this.filterPriority, this.filterContent, this.pageIndex - 1, this.pageSize) .searchAlerts(this.filterStatus, this.filterPriority, this.filterContent, this.pageIndex - 1, this.pageSize)
.subscribe( .subscribe(
message => { message => {
filterAlerts$.unsubscribe();
this.tableLoading = false; this.tableLoading = false;
this.checkedAll = false; this.checkedAll = false;
this.checkedAlertIds.clear(); this.checkedAlertIds.clear();
@@ -57,16 +54,44 @@ export class AlertCenterComponent implements OnInit {
} else { } else {
console.warn(message.msg); console.warn(message.msg);
} }
alertsInit$.unsubscribe();
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
alertsInit$.unsubscribe(); filterAlerts$.unsubscribe();
console.error(error.msg); console.error(error.msg);
} }
); );
} }
sync() {
this.loadAlertsTable();
}
loadAlertsTable() {
this.tableLoading = true;
let alertsInit$ = this.alertSvc.getAlerts(this.pageIndex - 1, this.pageSize).subscribe(
message => {
this.tableLoading = false;
this.checkedAll = false;
this.checkedAlertIds.clear();
if (message.code === 0) {
let page = message.data;
this.alerts = page.content;
this.pageIndex = page.number + 1;
this.total = page.totalElements;
} else {
console.warn(message.msg);
}
alertsInit$.unsubscribe();
},
error => {
this.tableLoading = false;
alertsInit$.unsubscribe();
console.error(error.msg);
}
);
}
onDeleteAlerts() { onDeleteAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('alert.center.notify.no-delete'), ''); this.notifySvc.warning(this.i18nSvc.fanyi('alert.center.notify.no-delete'), '');

View File

@@ -347,7 +347,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
alertsDealLoading: boolean = true; alertsDealLoading: boolean = true;
refreshAlertContentList(): void { refreshAlertContentList(): void {
let alertsInit$ = this.alertSvc.loadAlerts(undefined, undefined, undefined, 0, 4).subscribe( let alertsInit$ = this.alertSvc.getAlerts(0, 4).subscribe(
message => { message => {
if (message.code === 0) { if (message.code === 0) {
let page = message.data; let page = message.data;

View File

@@ -16,7 +16,22 @@ const alerts_status_uri = '/alerts/status';
export class AlertService { export class AlertService {
constructor(private http: HttpClient) {} constructor(private http: HttpClient) {}
public loadAlerts( public getAlerts(pageIndex: number, pageSize: number): Observable<Message<Page<Alert>>> {
pageIndex = pageIndex ? pageIndex : 0;
pageSize = pageSize ? pageSize : 8;
// 注意HttpParams是不可变对象 需要保存set后返回的对象为最新对象
let httpParams = new HttpParams();
httpParams = httpParams.appendAll({
sort: 'id',
order: 'desc',
pageIndex: pageIndex,
pageSize: pageSize
});
const options = { params: httpParams };
return this.http.get<Message<Page<Alert>>>(alerts_uri, options);
}
public searchAlerts(
status: number | undefined, status: number | undefined,
priority: number | undefined, priority: number | undefined,
content: string | undefined, content: string | undefined,