Compare commits

..

4 Commits

Author SHA1 Message Date
tomsun28
7ca1ae88fd [monitor]feature:remove duplicate port monitor yml 2022-04-05 22:23:44 +08:00
tomsun28
63d1257275 [monitor]feature:all monitors set advanced params 2022-04-05 22:14:39 +08:00
tomsun28
442d4d1dfb [monitor]feature:support hide advanced params define 2022-04-05 22:01:23 +08:00
tomsun28
51266aab87 [collector,alerter]bugfix:monitors always timeout alert (#67) 2022-04-05 20:50:33 +08:00
39 changed files with 570 additions and 457 deletions

View File

@@ -110,7 +110,7 @@ public class CalculateAlarm {
} else {
// 其他异常
alertBuilder.target(CommonConstants.AVAILABLE)
.content("监控紧急可用性告警: " + metricsData.getCode().name());
.content("监控可用性告警: " + metricsData.getCode().name() + " : " + metricsData.getMsg());
triggeredMonitorStateAlertMap.put(monitorId, metricsData.getCode());
dataQueue.addAlertData(alertBuilder.build());
}

View File

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

View File

@@ -12,23 +12,20 @@ import java.util.List;
import java.util.Set;
/**
* Alert Database Operations Alert数据库操作
*
* Alert 数据库操作
* @author tom
* @date 2021/12/9 10:03
*/
public interface AlertDao extends JpaRepository<Alert, Long>, JpaSpecificationExecutor<Alert> {
/**
* Delete alerts based on ID list 根据ID列表删除告警
*
* @param alertIds Alert ID List 告警ID列表
* 根据ID列表删除告警
* @param alertIds 告警ID列表
*/
void deleteAlertsByIdIn(Set<Long> alertIds);
/**
* 根据告警ID-状态值 更新告警状态
*
* @param status 状态值
* @param ids 告警ID列表
*/
@@ -37,10 +34,8 @@ public interface AlertDao extends JpaRepository<Alert, Long>, JpaSpecificationEx
void updateAlertsStatus(@Param(value = "status") Byte status, @Param(value = "ids") List<Long> ids);
/**
* Query the number of unhandled alarms of each alarm severity
* 查询各个告警级别的未处理告警数量
*
* @return Number of alerts 告警数量
* @return 告警数量
*/
@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();

View File

@@ -4,8 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Data;
/**
* Number of monitoring level alarms 监控级别告警数量
*
* 监控级别告警数量
* @author tom
* @date 2022/3/6 19:52
*/
@@ -13,13 +12,7 @@ import lombok.Data;
@AllArgsConstructor
public class AlertPriorityNum {
/**
* Alarm level 告警级别
*/
private byte priority;
/**
* count 数量
*/
private long num;
}

View File

@@ -9,43 +9,31 @@ import lombok.NoArgsConstructor;
import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;
/**
* Alarm Statistics Information 告警统计信息
*
* 告警统计信息
* @author tom
* @date 2022/3/6 19:25
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(description = "en:Alarm Statistics Information,zh: 告警统计信息")
@ApiModel(description = "告警统计信息")
public class AlertSummary {
@ApiModelProperty(value = "Total number of alerts (including processed and unprocessed alerts)",
notes = "告警总数量(包括已处理未处理告警)",
example = "134", accessMode = READ_ONLY, position = 0)
@ApiModelProperty(value = "告警总数量(包括已处理未处理告警)", example = "134", accessMode = READ_ONLY, position = 0)
private long total;
@ApiModelProperty(value = "Number of alerts handled",
notes = "已处理告警数量",
example = "34", accessMode = READ_ONLY, position = 1)
@ApiModelProperty(value = "已处理告警数量", example = "34", accessMode = READ_ONLY, position = 1)
private long dealNum;
@ApiModelProperty(value = "Alarm handling rate",
notes = "告警处理率",
example = "39.34", accessMode = READ_ONLY, position = 2)
@ApiModelProperty(value = "告警处理率", example = "39.34", accessMode = READ_ONLY, position = 2)
private float rate;
@ApiModelProperty(value = "Number of alarms whose alarm severity is warning alarms (referring to unhandled alarms)",
notes = "告警级别为警告告警的告警数量(指未处理告警)",
example = "43", accessMode = READ_ONLY, position = 3)
@ApiModelProperty(value = "告警级别为警告告警的告警数量(指未处理告警)", example = "43", accessMode = READ_ONLY, position = 3)
private long priorityWarningNum;
@ApiModelProperty(value = "Number of alarms whose alarm severity is critical alarms (referring to unhandled alarms)",
notes = "告警级别为严重告警的告警数量(指未处理告警)",
example = "56", accessMode = READ_ONLY, position = 4)
@ApiModelProperty(value = "告警级别为严重告警的告警数量(指未处理告警)", example = "56", accessMode = READ_ONLY, position = 4)
private long priorityCriticalNum;
@ApiModelProperty(value = "Number of alarms whose alarm severity is urgent alarms (referring to unhandled alarms)",
notes = "告警级别为紧急告警的告警数量(指未处理告警)", example = "23", accessMode = READ_ONLY, position = 5)
@ApiModelProperty(value = "告警级别为紧急告警的告警数量(指未处理告警)", example = "23", accessMode = READ_ONLY, position = 5)
private long priorityEmergencyNum;
}

View File

@@ -10,54 +10,43 @@ import java.util.HashSet;
import java.util.List;
/**
* Alarm information management interface
* 告警信息管理接口
*
* @author tom
* @date 2021/12/9 10:06
*/
public interface AlertService {
/**
* Add alarm record
* 新增告警记录
*
* @param alert Alert entity 告警实体
* @throws RuntimeException Add process exception throw 新增过程异常抛出
* 新增告警
* @param alert 告警实体
* @throws RuntimeException 新增过程异常抛出
*/
void addAlert(Alert alert) throws RuntimeException;
/**
* Dynamic conditional query
* 动态条件查询
*
* @param specification Query conditions 查询条件
* @param pageRequest pagination parameters 分页参数
* @return search result 查询结果
* @param specification 查询条件
* @param pageRequest 分页参数
* @return 查询结果
*/
Page<Alert> getAlerts(Specification<Alert> specification, PageRequest pageRequest);
/**
* Delete alarms in batches according to the alarm ID list
* 根据告警ID列表批量删除告警
*
* @param ids Alarm ID List 告警IDS
* @param ids 告警IDs
*/
void deleteAlerts(HashSet<Long> ids);
/**
* Update the alarm status according to the alarm ID-status value
* 根据告警ID-状态值 更新告警状态
*
* @param status Alarm status to be modified 待修改的告警状态
* @param ids Alarm ID List to be modified 待修改的告警ID集合
* @param status 待修改为的告警状态
* @param ids 待修改的告警IDs
*/
void editAlertStatus(Byte status, List<Long> ids);
/**
* Get alarm statistics information 获取告警统计信息
*
* @return Alarm statistics information 告警统计
* 获取告警统计信息
* @return 告警统计
*/
AlertSummary getAlertsSummary();

View File

@@ -20,8 +20,7 @@ import java.util.HashSet;
import java.util.List;
/**
* Realization of Alarm Information Service 告警信息服务实现
*
* 告警信息服务实现
* @author tom
* @date 2021/12/10 15:39
*/
@@ -56,24 +55,18 @@ public class AlertServiceImpl implements AlertService {
@Override
public AlertSummary getAlertsSummary() {
AlertSummary alertSummary = new AlertSummary();
//Statistics on the alarm information in the alarm state
//统计正在告警状态下的告警信息
List<AlertPriorityNum> priorityNums = alertDao.findAlertPriorityNum();
if (priorityNums != null) {
for (AlertPriorityNum priorityNum : priorityNums) {
switch (priorityNum.getPriority()) {
case CommonConstants
.ALERT_PRIORITY_CODE_WARNING:
alertSummary.setPriorityWarningNum(priorityNum.getNum());
break;
alertSummary.setPriorityWarningNum(priorityNum.getNum());break;
case CommonConstants.ALERT_PRIORITY_CODE_CRITICAL:
alertSummary.setPriorityCriticalNum(priorityNum.getNum());
break;
alertSummary.setPriorityCriticalNum(priorityNum.getNum());break;
case CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY:
alertSummary.setPriorityEmergencyNum(priorityNum.getNum());
break;
default:
break;
alertSummary.setPriorityEmergencyNum(priorityNum.getNum());break;
default: break;
}
}
}

View File

@@ -105,9 +105,13 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
.setId(timerJob.getJob().getMonitorId())
.setApp(timerJob.getJob().getApp())
.setMetrics(metricsTime.getMetrics().getName())
.setPriority(metricsTime.getMetrics().getPriority())
.setTime(System.currentTimeMillis())
.setCode(CollectRep.Code.TIMEOUT).setMsg("collect timeout").build();
log.error("[Collect Timeout]: \n{}", metricsData);
if (metricsData.getPriority() == 0) {
dispatchCollectData(metricsTime.timeout, metricsTime.getMetrics(), metricsData);
}
metricsTimeoutMonitorMap.remove(entry.getKey());
}
}
@@ -165,8 +169,8 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
metricsSet.forEach(metricItem -> {
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
jobRequestQueue.addJob(metricsCollect);
metricsTimeoutMonitorMap.put(job.getId() + "-" + metrics.getName(),
new MetricsTime(System.currentTimeMillis(), metrics, timeout));
metricsTimeoutMonitorMap.put(job.getId() + "-" + metricItem.getName(),
new MetricsTime(System.currentTimeMillis(), metricItem, timeout));
});
} else {
// 当前执行级别的指标组列表未全执行完成,
@@ -185,8 +189,8 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
metricsSet.forEach(metricItem -> {
MetricsCollect metricsCollect = new MetricsCollect(metricItem, timeout, this);
jobRequestQueue.addJob(metricsCollect);
metricsTimeoutMonitorMap.put(job.getId() + "-" + metrics.getName(),
new MetricsTime(System.currentTimeMillis(), metrics, timeout));
metricsTimeoutMonitorMap.put(job.getId() + "-" + metricItem.getName(),
new MetricsTime(System.currentTimeMillis(), metricItem, timeout));
});
} else {
// 当前执行级别的指标组列表未全执行完成,

View File

@@ -34,6 +34,10 @@ import java.util.stream.Collectors;
@Slf4j
@Data
public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
/**
* 调度告警阈值时间 100ms
*/
private static final long WARN_DISPATCH_TIME = 100;
/**
* 监控ID
*/
@@ -267,11 +271,15 @@ public class MetricsCollect implements Runnable, Comparable<MetricsCollect> {
private CollectRep.MetricsData validateResponse(CollectRep.MetricsData.Builder builder) {
long endTime = System.currentTimeMillis();
builder.setTime(endTime);
log.debug("[Collect]: newTime: {}, startTime: {}, spendTime: {}.", newTime, startTime, endTime - startTime);
long runningTime = endTime - startTime;
long allTime = endTime - newTime;
if (startTime - newTime >= WARN_DISPATCH_TIME) {
log.warn("[Collector Dispatch Warn, Dispatch Use {}ms.", startTime - newTime);
}
if (builder.getCode() != CollectRep.Code.SUCCESS) {
log.info("[Collect Fail] Reason: {}", builder.getMsg());
log.info("[Collect Failed, Run {}ms, All {}ms] Reason: {}", runningTime, allTime, builder.getMsg());
} else {
log.info("[Collect Success].");
log.info("[Collect Success, Run {}ms, All {}ms].", runningTime, allTime);
}
return builder.build();
}

View File

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

View File

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

View File

@@ -122,6 +122,12 @@ public class ParamDefine {
@ApiModelProperty(value = "当type为key-value时有效,表示value的别名描述", example = "Value", accessMode = READ_WRITE, position = 10)
private String valueAlias;
/**
* 是否是高级隐藏参数 true-是 false-否
*/
@ApiModelProperty(value = "是否是高级隐藏参数 true-是 false-否", example = "true", accessMode = READ_WRITE, position = 11)
private boolean hide = false;
/**
* 此条记录创建者
*/

View File

@@ -30,9 +30,7 @@ import java.util.Date;
import java.util.List;
/**
* Alarm information storage and distribution
* 告警信息入库分发
*
* @author tom
* @date 2021/12/10 12:58
*/
@@ -72,7 +70,7 @@ public class DispatchAlarm {
try {
Alert alert = dataQueue.pollAlertData();
if (alert != null) {
// Determining alarm type storage 判断告警类型入库
// 判断告警类型入库
storeAlertData(alert);
// 通知分发
sendAlertDataListener(alert);
@@ -88,7 +86,7 @@ public class DispatchAlarm {
}
private void storeAlertData(Alert alert) {
// todo Using the cache does not directly manipulate the library 使用缓存不直接操作库
// todo 使用缓存不直接操作库
Monitor monitor = monitorService.getMonitor(alert.getMonitorId());
if (monitor == null) {
log.warn("Dispatch alarm the monitorId: {} not existed, ignored.", alert.getMonitorId());
@@ -96,70 +94,50 @@ public class DispatchAlarm {
}
alert.setMonitorName(monitor.getName());
if (monitor.getStatus() == CommonConstants.UN_MANAGE_CODE) {
// When monitoring is not managed, ignore and silence its alarm messages
// 当监控未管理时 忽略静默其告警信息
return;
}
if (monitor.getStatus() == CommonConstants.AVAILABLE_CODE) {
if (CommonConstants.AVAILABLE.equals(alert.getTarget())) {
// Availability Alarm Need to change the monitoring status to unavailable
// 可用性告警 需变更监控状态为不可用
monitorService.updateMonitorStatus(monitor.getId(), CommonConstants.UN_AVAILABLE_CODE);
} 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);
}
} else {
// If the alarm is restored, the monitoring state needs to be restored
// 若是恢复告警 需对监控状态进行恢复
if (alert.getStatus() == CommonConstants.ALERT_STATUS_CODE_RESTORED) {
monitorService.updateMonitorStatus(alert.getMonitorId(), CommonConstants.AVAILABLE_CODE);
}
}
// Alarm drop library 告警落库
// 告警落库
alertService.addAlert(alert);
}
private void sendAlertDataListener(Alert alert) {
// todo Forward configured email WeChat webhook 转发配置的邮件 微信 webhook
// todo 转发配置的邮件 微信 webhook
List<NoticeReceiver> receivers = matchReceiverByNoticeRules(alert);
// todo Send notification here temporarily single thread 发送通知这里暂时单线程
// todo 发送通知这里暂时单线程
for (NoticeReceiver receiver : receivers) {
switch (receiver.getType()) {
// todo SMS notification 短信通知
case 0:
break;
case 1:
sendEmailAlert(receiver, alert);
break;
case 2:
sendWebHookAlert(receiver, alert);
break;
case 3:
sendWeChatAlert(receiver, alert);
break;
case 4:
sendWeWorkRobotAlert(receiver, alert);
break;
case 5:
sendDingTalkRobotAlert(receiver, alert);
break;
case 6:
sendFlyBookAlert(receiver, alert);
break;
default:
break;
// todo 短信通知
case 0: break;
case 1: sendEmailAlert(receiver, alert); break;
case 2: sendWebHookAlert(receiver, alert); break;
case 3: sendWeChatAlert(receiver, alert); break;
case 4: sendWeWorkRobotAlert(receiver, alert); break;
case 5: sendDingTalkRobotAlert(receiver, alert); break;
case 6: sendFlyBookAlert(receiver,alert); break;
default: break;
}
}
}
/**
* Send alert information through FeiShu
* 通过飞书发送告警信息
*
* @param receiver Notification configuration information 通知配置信息
* @param alert Alarm information 告警信息
* @param receiver 接收人
* @param alert 告警信息
*/
private void sendFlyBookAlert(NoticeReceiver receiver, Alert alert) {
FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto();
@@ -205,11 +183,9 @@ public class DispatchAlarm {
}
/**
* Send alarm information through DingTalk robot
* 通过钉钉机器人发送告警信息
*
* @param receiver Notification configuration information 通知配置信息
* @param alert Alarm information 告警信息
* @param receiver 通知配置信息
* @param alert 告警信息
*/
private void sendDingTalkRobotAlert(NoticeReceiver receiver, Alert alert) {
DingTalkWebHookDto dingTalkWebHookDto = new DingTalkWebHookDto();
@@ -240,11 +216,9 @@ public class DispatchAlarm {
}
/**
* Send alarm information through enterprise WeChat
* 通过企业微信发送告警信息
*
* @param receiver Notification configuration information 通知配置信息
* @param alert Alarm information 告警信息
* @param receiver 通知配置信息
* @param alert 告警信息
*/
private void sendWeWorkRobotAlert(NoticeReceiver receiver, Alert alert) {
WeWorkWebHookDto weWorkWebHookDTO = new WeWorkWebHookDto();
@@ -257,7 +231,7 @@ public class DispatchAlarm {
if (alert.getPriority() < CommonConstants.ALERT_PRIORITY_CODE_WARNING) {
content.append("告警级别 : <font color=\"warning\">")
.append(CommonUtil.transferAlertPriority(alert.getPriority())).append("</font>\n");
} else {
}else {
content.append("告警级别 : <font color=\"comment\">")
.append(CommonUtil.transferAlertPriority(alert.getPriority())).append("</font>\n");
}
@@ -299,28 +273,28 @@ public class DispatchAlarm {
}
private void sendEmailAlert(final NoticeReceiver receiver, final Alert alert) {
try {
private void sendEmailAlert(final NoticeReceiver receiver,final Alert alert){
try{
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage,true,"UTF-8");
messageHelper.setSubject("TanCloud探云-监控告警");
//Set sender Email 设置发件人Email
//设置发件人Email
messageHelper.setFrom(emailFromUser);
//Set recipient Email 设定收件人Email
//设定收件人Email
messageHelper.setTo(receiver.getEmail());
messageHelper.setSentDate(new Date());
//Build email templates 构建邮件模版
//构建邮件模版
String process = mailService.buildAlertHtmlTemplate(alert);
//Set Email Content Template 设置邮件内容模版
messageHelper.setText(process, true);
//设置邮件内容模版
messageHelper.setText(process,true);
javaMailSender.send(mimeMessage);
} catch (Exception e) {
log.error("[Email Alert] ExceptionException information={}", e.getMessage());
}catch (Exception e){
log.error("[邮箱告警] errorException information={}",e.getMessage());
}
}
private List<NoticeReceiver> matchReceiverByNoticeRules(Alert alert) {
// todo use cache 使用缓存
// todo 使用缓存
return noticeConfigService.getReceiverFilterRule(alert);
}

View File

@@ -28,13 +28,11 @@ import java.util.List;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/**
* Message Notification Configuration API
* 消息通知配置API
*
* @author tom
* @date 2021/12/16 16:18
*/
@Api(tags = "en: Message Notification Configuration API,zh: 消息通知配置API")
@Api(tags = "消息通知配置API")
@RestController()
@RequestMapping(value = "/notice", produces = {APPLICATION_JSON_VALUE})
public class NoticeConfigController {
@@ -43,36 +41,33 @@ public class NoticeConfigController {
private NoticeConfigService noticeConfigService;
@PostMapping(path = "/receiver")
@ApiOperation(value = "Add a recipient", notes = "新增一个接收人")
@ApiOperation(value = "新增接收人", notes = "新增一个接收人")
public ResponseEntity<Message<Void>> addNewNoticeReceiver(@Valid @RequestBody NoticeReceiver noticeReceiver) {
noticeConfigService.addReceiver(noticeReceiver);
return ResponseEntity.ok(new Message<>("Add success"));
}
@PutMapping(path = "/receiver")
@ApiOperation(value = "Modify existing recipient information", notes = "修改已存在的接收人信息")
@ApiOperation(value = "修改接收人", notes = "修改已存在的接收人信息")
public ResponseEntity<Message<Void>> editNoticeReceiver(@Valid @RequestBody NoticeReceiver noticeReceiver) {
noticeConfigService.editReceiver(noticeReceiver);
return ResponseEntity.ok(new Message<>("Edit success"));
}
@DeleteMapping(path = "/receiver/{id}")
@ApiOperation(value = "Delete existing recipient information", notes = "删除已存在的接收人信息")
@ApiOperation(value = "删除指定接收人", notes = "删除已存在的接收人信息")
public ResponseEntity<Message<Void>> deleteNoticeReceiver(
@ApiParam(value = "en: Recipient ID,zh: 接收人ID", example = "6565463543") @PathVariable("id") final Long receiverId) {
// Returns success if it does not exist or if the deletion is successful
// todo 不存在或删除成功都返回成功
@ApiParam(value = "接收人ID", example = "6565463543") @PathVariable("id") final Long receiverId) {
// 不存在或删除成功都返回成功
noticeConfigService.deleteReceiver(receiverId);
return ResponseEntity.ok(new Message<>("Delete success"));
}
@GetMapping(path = "/receivers")
@ApiOperation(value = "Get a list of message notification recipients based on query filter items",
notes = "根据查询过滤项获取消息通知接收人列表")
@ApiOperation(value = "查询消息通知接收人", notes = "根据查询过滤项获取消息通知接收人列表")
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) {
//todo Writing can be optimized 写法可优化
Specification<NoticeReceiver> specification = (root, query, criteriaBuilder) -> {
Predicate predicate = criteriaBuilder.conjunction();
if (name != null && !"".equals(name)) {
@@ -88,34 +83,32 @@ public class NoticeConfigController {
@PostMapping(path = "/rule")
@ApiOperation(value = "Add a notification policy", notes = "新增一个通知策略")
@ApiOperation(value = "新增通知策略", notes = "新增一个通知策略")
public ResponseEntity<Message<Void>> addNewNoticeRule(@Valid @RequestBody NoticeRule noticeRule) {
noticeConfigService.addNoticeRule(noticeRule);
return ResponseEntity.ok(new Message<>("Add success"));
}
@PutMapping(path = "/rule")
@ApiOperation(value = "Modify existing notification policy information", notes = "修改已存在的通知策略信息")
@ApiOperation(value = "修改通知策略", notes = "修改已存在的通知策略信息")
public ResponseEntity<Message<Void>> editNoticeRule(@Valid @RequestBody NoticeRule noticeRule) {
noticeConfigService.editNoticeRule(noticeRule);
return ResponseEntity.ok(new Message<>("Edit success"));
}
@DeleteMapping(path = "/rule/{id}")
@ApiOperation(value = "Delete existing notification policy information", notes = "删除已存在的通知策略信息")
@ApiOperation(value = "删除指定通知策略", notes = "删除已存在的通知策略信息")
public ResponseEntity<Message<Void>> deleteNoticeRule(
@ApiParam(value = "en: Notification Policy ID,zh: 通知策略ID", example = "6565463543") @PathVariable("id") final Long ruleId) {
// Returns success if it does not exist or if the deletion is successful
// todo 不存在或删除成功都返回成功
@ApiParam(value = "通知策略ID", example = "6565463543") @PathVariable("id") final Long ruleId) {
// 不存在或删除成功都返回成功
noticeConfigService.deleteNoticeRule(ruleId);
return ResponseEntity.ok(new Message<>("Delete success"));
}
@GetMapping(path = "/rules")
@ApiOperation(value = "Get a list of message notification policies based on query filter items",
notes = "根据查询过滤项获取消息通知策略列表")
@ApiOperation(value = "查询消息通知策略", notes = "根据查询过滤项获取消息通知策略列表")
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) -> {
Predicate predicate = criteriaBuilder.conjunction();

View File

@@ -18,13 +18,11 @@ import java.util.List;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/**
* System Summary Statistics API
* 系统摘要统计API
*
* @author tom
* @date 2021/12/7 15:57
*/
@Api(tags = "en: System Summary Statistics API,zh: 系统摘要统计API")
@Api(tags = "系统摘要统计API")
@RestController
@RequestMapping(path = "/summary", produces = {APPLICATION_JSON_VALUE})
public class SummaryController {
@@ -33,7 +31,7 @@ public class SummaryController {
private MonitorService monitorService;
@GetMapping
@ApiOperation(value = "Query all application category monitoring statistics", notes = "查询所有应用类别监控统计信息")
@ApiOperation(value = "查询应用类别监控统计", notes = "查询所有应用类别监控统计信息")
public ResponseEntity<Message<Dashboard>> appMonitors() {
List<AppCount> appsCount = monitorService.getAllAppMonitorsCount();
Message<Dashboard> message = new Message<>(new Dashboard(appsCount));

View File

@@ -14,7 +14,6 @@ import java.util.Set;
/**
* AuthResources 数据库操作
*
* @author tomsun28
* @date 2021/11/14 11:24
*/
@@ -23,14 +22,12 @@ public interface MonitorDao extends JpaRepository<Monitor, Long>, JpaSpecificati
/**
* 根据监控ID列表删除监控
*
* @param monitorIds 监控ID列表
*/
void deleteAllByIdIn(Set<Long> monitorIds);
/**
* 根据监控ID列表查询监控
*
* @param monitorIds 监控ID列表
* @return 监控列表
*/
@@ -38,7 +35,6 @@ public interface MonitorDao extends JpaRepository<Monitor, Long>, JpaSpecificati
/**
* 根据监控类型查询监控
*
* @param app 监控类型
* @return 监控列表
*/
@@ -46,35 +42,29 @@ public interface MonitorDao extends JpaRepository<Monitor, Long>, JpaSpecificati
/**
* 查询已下发采集任务的监控
*
* @param status 监控状态
* @return 监控列表
*/
List<Monitor> findMonitorsByStatusNotInAndAndJobIdNotNull(List<Byte> status);
/**
* Query monitoring by monitoring name 根据监控名称查询监控
*
* @param name monitoring name 监控名称
* @return monitoring list 监控列表
* 根据监控名称查询监控
* @param name 监控名称
* @return 监控列表
*/
Optional<Monitor> findMonitorByNameEquals(String name);
/**
* Query the monitoring category - the number of monitoring corresponding to the status
* 查询监控类别-状态对应的监控数量
*
* @return Monitoring Category-Status and Monitoring Quantity Mapping 监控类别-状态与监控数量映射
* @return 监控类别-状态与监控数量映射
*/
@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();
/**
* Update the status of the specified monitor
* 更新指定监控的状态
*
* @param id Monitor ID 监控ID
* @param status 监控状态 Monitor Status
* @param id 监控ID
* @param status 监控状态
*/
@Modifying
@Query("update Monitor set status = :status where id = :id")

View File

@@ -7,7 +7,6 @@ import lombok.NoArgsConstructor;
/**
* 企业微信机器人请求消息体
*
* @author 花城
* @version 1.0
* @date 2022/2/21 6:55 下午
@@ -19,14 +18,7 @@ import lombok.NoArgsConstructor;
public class WeWorkWebHookDto {
public static final String WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=";
/**
* markdown格式
*/
private static final String MARKDOWN = "markdown";
/**
* 文本格式
*/
private static final String TEXT = "TEXT";
/**
* 消息类型

View File

@@ -6,7 +6,7 @@ import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
/**
* Email delivery service 邮箱发送服务
* 邮箱发送服务
*
* @author 花城
* @version 1.0
@@ -15,11 +15,9 @@ import org.springframework.stereotype.Service;
public interface MailService {
/**
* Build an alert email template
* 构建告警邮件模版
*
* @param alert Alarm data element information 告警数据元信息
* @return content of email 邮件内容
* @param alert 告警信息
* @return 邮件内容
*/
String buildAlertHtmlTemplate(Alert alert);
}

View File

@@ -15,7 +15,6 @@ import java.util.Set;
/**
* 监控管理服务
*
* @author tomsun28
* @date 2021/11/14 11:28
*/
@@ -24,7 +23,6 @@ public interface MonitorService {
/**
* 监控可用性探测
*
* @param monitor 监控实体信息
* @param params 参数信息
* @throws MonitorDetectException 探测失败抛出
@@ -33,7 +31,6 @@ public interface MonitorService {
/**
* 新增监控
*
* @param monitor 监控实体
* @param params 参数信息
* @throws RuntimeException 新增过程异常抛出
@@ -42,7 +39,6 @@ public interface MonitorService {
/**
* 校验请求数据参数正确性
*
* @param monitorDto monitorDto
* @param isModify 是否是修改监控
* @throws IllegalArgumentException 校验参数错误抛出
@@ -51,7 +47,6 @@ public interface MonitorService {
/**
* 修改更新监控
*
* @param monitor 监控实体
* @param params 参数信息
* @throws RuntimeException 修改过程中异常抛出
@@ -60,7 +55,6 @@ public interface MonitorService {
/**
* 删除监控
*
* @param id 监控ID
* @throws RuntimeException 删除过程中异常抛出
*/
@@ -68,7 +62,6 @@ public interface MonitorService {
/**
* 批量删除监控
*
* @param ids 监控ID
* @throws RuntimeException 删除过程中异常抛出
*/
@@ -76,7 +69,6 @@ public interface MonitorService {
/**
* 获取监控信息
*
* @param id 监控ID
* @return MonitorDto
* @throws RuntimeException 查询过程中异常抛出
@@ -85,7 +77,6 @@ public interface MonitorService {
/**
* 动态条件查询
*
* @param specification 查询条件
* @param pageRequest 分页参数
* @return 查询结果
@@ -94,46 +85,38 @@ public interface MonitorService {
/**
* 根据监控ID列表批量取消纳管监控项
*
* @param ids 监控IDs
*/
void cancelManageMonitors(HashSet<Long> ids);
/**
* 根据监控ID列表批量启动纳管监控项
*
* @param ids 监控IDs
*/
void enableManageMonitors(HashSet<Long> ids);
/**
* 查询监控类别及其对应的监控数量
*
* @return 监控类别与监控数量映射
*/
List<AppCount> getAllAppMonitorsCount();
/**
* Query monitoring
* 查询监控
*
* @param monitorId Monitor ID 监控ID
* @return Monitor information 监控信息
* @param monitorId 监控ID
* @return 监控信息
*/
Monitor getMonitor(Long monitorId);
/**
* Update the status of the specified monitor
* 更新指定监控的状态
*
* @param monitorId monitorId 监控ID
* @param status monitor status 监控状态
* @param monitorId 监控ID
* @param status 监控状态
*/
void updateMonitorStatus(Long monitorId, byte status);
/**
* 查询指定监控类型下的所有监控信息列表
*
* @param app 监控类型
* @return 监控列表
*/

View File

@@ -8,86 +8,66 @@ import org.springframework.data.jpa.domain.Specification;
import java.util.List;
/**
* Message notification configuration interface
* 消息通知配置接口
*
* @author tom
* @date 2021/12/16 16:14
*/
public interface NoticeConfigService {
/**
* Dynamic conditional query
* 动态条件查询
*
* @param specification Query conditions 查询条件
* @return Search result 查询结果
* @param specification 查询条件
* @return 查询结果
*/
List<NoticeReceiver> getNoticeReceivers(Specification<NoticeReceiver> specification);
/**
* Dynamic conditional query
* 动态条件查询
*
* @param specification Query conditions 查询条件
* @return Search result 查询结果
* @param specification 查询条件
* @return 查询结果
*/
List<NoticeRule> getNoticeRules(Specification<NoticeRule> specification);
/**
* Add a notification recipient
* 新增一个通知接收人
*
* @param noticeReceiver recipient information 接收人信息
* @param noticeReceiver 接收人信息
*/
void addReceiver(NoticeReceiver noticeReceiver);
/**
* Modify notification recipients
* 修改通知接收人
*
* @param noticeReceiver recipient information 接收人信息
* @param noticeReceiver 接收人信息
*/
void editReceiver(NoticeReceiver noticeReceiver);
/**
* Delete recipient information based on recipient ID
* 根据接收人ID删除接收人信息
*
* @param receiverId Recipient ID 接收人ID
* @param receiverId 接收人ID
*/
void deleteReceiver(Long receiverId);
/**
* Added notification policy
* 新增通知策略
*
* @param noticeRule Notification strategy 通知策略
* @param noticeRule 通知策略
*/
void addNoticeRule(NoticeRule noticeRule);
/**
* Modify Notification Policy
* 修改通知策略
*
* @param noticeRule Notification strategy 通知策略
* @param noticeRule 通知策略
*/
void editNoticeRule(NoticeRule noticeRule);
/**
* Delete the specified notification policy
* 删除指定的通知策略
*
* @param ruleId Notification Policy ID 通知策略ID
* @param ruleId 通知策略ID
*/
void deleteNoticeRule(Long ruleId);
/**
* According to the alarm information matching all notification policies, filter out the recipients who need to be notified
* 根据告警信息与所有通知策略匹配,过滤出需要通知的接收人
*
* @param alert Alarm information 告警信息
* @return Receiver 接收人
* @param alert 告警信息
* @return 接收人
*/
List<NoticeReceiver> getReceiverFilterRule(Alert alert);
}

View File

@@ -22,7 +22,6 @@ import com.usthe.manager.service.AppService;
import com.usthe.manager.service.MonitorService;
import com.usthe.manager.support.exception.MonitorDatabaseException;
import com.usthe.manager.support.exception.MonitorDetectException;
import jdk.nashorn.internal.runtime.regexp.joni.constants.Traverse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
@@ -41,7 +40,6 @@ import java.util.stream.Collectors;
/**
* 监控管理服务实现
*
* @author tomsun28
* @date 2021/11/14 13:06
*/
@@ -389,8 +387,7 @@ public class MonitorServiceImpl implements MonitorService {
if (appCounts == null) {
return null;
}
//Statistical category information, calculate the number of corresponding states for each monitor
//统计类别信息,计算每个监控分别对应状态的数量
// 关联大类别信息 计算每个状态对应数量
Map<String, AppCount> appCountMap = new HashMap<>(appCounts.size());
for (AppCount item : appCounts) {
AppCount appCount = appCountMap.getOrDefault(item.getApp(), new AppCount());
@@ -408,13 +405,10 @@ public class MonitorServiceImpl implements MonitorService {
case CommonConstants.UN_REACHABLE_CODE:
appCount.setUnReachableSize(appCount.getUnReachableSize() + item.getSize());
break;
default:
break;
default: break;
}
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 -> {
item.setSize(item.getAvailableSize() + item.getUnManageSize()
+ item.getUnReachableSize() + item.getUnAvailableSize());

View File

@@ -1,25 +0,0 @@
category: service
app: telnet
name:
zh-CN: TELNET端口可用性
en-US: PORT TELNET
configmap:
- key: host
type: 1
- key: port
type: 0
- key: timeout
type: 0
metrics:
- name: summary
priority: 0
fields:
- field: responseTime
type: 0
unit: ms
protocol: telnet
# 当protocol为telnet协议时具体的采集配置
telnet:
host: ^_^host^_^
port: ^_^port^_^
timeout: ^_^timeout^_^

View File

@@ -26,10 +26,12 @@ param:
# 当type为text时,用limit表示字符串限制大小
limit: 20
required: false
hide: true
- field: password
name: 密码
type: password
required: false
hide: true
- field: ssl
name: 启动SSL
# 当type为boolean时,前端用switch展示开关

View File

@@ -60,15 +60,18 @@ param:
type: text
placeholder: '请求BODY资源类型'
required: false
hide: true
- field: payload
name: 请求BODY
type: textarea
placeholder: 'POST PUT请求时有效'
required: false
hide: true
- field: authType
name: 认证方式
type: radio
required: false
hide: true
# 当type为radio单选框,checkbox复选框时,option表示可选项值列表 {name1:value1,name2:value2}
options:
- label: Basic Auth
@@ -81,7 +84,9 @@ param:
# 当type为text时,用limit表示字符串限制大小
limit: 20
required: false
hide: true
- field: password
name: 密码
type: password
required: false
hide: true

View File

@@ -17,6 +17,7 @@ param:
required: false
defaultValue: 6000
placeholder: '查询超时时间'
hide: true
- field: database
name: 数据库名称
type: text
@@ -34,3 +35,4 @@ param:
name: URL
type: text
required: false
hide: true

View File

@@ -15,6 +15,7 @@ param:
name: 查询超时时间
type: number
required: false
hide: true
defaultValue: 6000
placeholder: '查询超时时间'
- field: database
@@ -34,3 +35,4 @@ param:
name: URL
type: text
required: false
hide: true

View File

@@ -15,6 +15,7 @@ param:
name: 查询超时时间
type: number
required: false
hide: true
defaultValue: 6000
placeholder: '查询超时时间'
- field: database
@@ -34,3 +35,4 @@ param:
name: URL
type: text
required: false
hide: true

View File

@@ -15,6 +15,7 @@ param:
name: 查询超时时间
type: number
required: false
hide: true
defaultValue: 6000
placeholder: '查询超时时间'
- field: database
@@ -34,3 +35,4 @@ param:
name: URL
type: text
required: false
hide: true

View File

@@ -15,6 +15,7 @@ param:
name: 查询超时时间
type: number
required: false
hide: true
defaultValue: 6000
placeholder: '查询超时时间'
- field: database
@@ -34,3 +35,4 @@ param:
name: URL
type: text
required: false
hide: true

View File

@@ -1,27 +0,0 @@
# 监控应用类型名称(与文件名保持一致) eg: linux windows tomcat mysql aws...
app: telnet
# 强制固定必须参数 - host(ipv4,ipv6,域名)
param:
# field-字段名称标识符
- field: host
# name-参数字段显示名称
name: 主机Host
# type-字段类型,样式(大部分映射input标签type属性)
type: host
# 是否是必输项 true-必填 false-可选
required: true
- field: port
name: 端口
type: number
# 当type为number时,用range表示范围
range: '[0,65535]'
required: true
defaultValue: 80
- field: timeout
name: Telnet超时时间
type: number
# 当type为number时,用range表示范围
range: '[0,100000]'
required: true
placeholder: '请输入超时时间,单位毫秒'
defaultValue: 6000

View File

@@ -33,6 +33,7 @@ param:
name: 认证方式
type: radio
required: false
hide: true
# 当type为radio单选框,checkbox复选框时,option表示可选项值列表 {name1:value1,name2:value2}
options:
- label: Basic Auth
@@ -45,7 +46,9 @@ param:
# 当type为text时,用limit表示字符串限制大小
limit: 20
required: false
hide: true
- field: password
name: 密码
type: password
required: false
hide: true

View File

@@ -12,4 +12,6 @@ export class ParamDefine {
// 当type为key-value时有效,表示别名描述
keyAlias!: string;
valueAlias!: string;
// 此参数是否隐藏 即默认不显示, 在高级设置区显示
hide: boolean = false;
}

View File

@@ -162,11 +162,151 @@
</nz-form-control>
</nz-form-item>
<nz-collapse [nzGhost]="true">
<nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
<nz-form-label
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
nzSpan="8"
[nzErrorTip]="'validation.required' | i18n"
>
<input
nz-input
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
[name]="paramDefine.field"
[type]="paramDefine.type"
[id]="paramDefine.field"
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
/>
</nz-form-control>
<nz-form-label
*ngIf="paramDefine.type === 'textarea'"
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'textarea'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<textarea
nz-input
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
[name]="paramDefine.field"
[id]="paramDefine.field"
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
rows="3"
></textarea>
</nz-form-control>
<nz-form-label
*ngIf="paramDefine.type === 'password'"
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-input-group [nzSuffix]="suffixTemplate" style="width: 100%">
<input
[type]="passwordVisible ? 'text' : 'password'"
nz-input
placeholder="input password"
[required]="paramDefine.required"
[(ngModel)]="advancedParams[i].value"
[id]="paramDefine.field"
[name]="paramDefine.field"
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
/>
</nz-input-group>
<ng-template #suffixTemplate>
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i>
</ng-template>
</nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'number'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-input-number
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
[nzMin]="-1000"
[nzMax]="65535"
[nzStep]="1"
[nzPlaceHolder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
[name]="paramDefine.field"
[id]="paramDefine.field"
></nz-input-number>
</nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'boolean'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-switch
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
[name]="paramDefine.field"
[id]="paramDefine.field"
></nz-switch>
</nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'radio'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-radio-group
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
nzButtonStyle="solid"
[name]="paramDefine.field"
[id]="paramDefine.field"
>
<label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options">
{{ optionItem.label }}
</label>
</nz-radio-group>
</nz-form-control>
<nz-form-label
*ngIf="paramDefine.type === 'key-value'"
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'key-value'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<app-key-value-input
[(value)]="advancedParams[i].value"
[id]="paramDefine.field"
keyAlias="Header Name"
valueAlias="Header Value"
></app-key-value-input>
</nz-form-control>
</nz-form-item>
</nz-collapse-panel>
</nz-collapse>
<ng-template #extraColHeader>
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
<span>高级设置</span>
<i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button>
</ng-template>
<nz-divider></nz-divider>
<nz-form-item>
<nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
<nz-form-control nzSpan="10">
<nz-form-control nzSpan="8">
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="604800" [nzStep]="60" name="intervals" id="intervals">
</nz-input-number>
</nz-form-control>

View File

@@ -0,0 +1,8 @@
.dynamic-button {
font-size: 20px;
margin-left: 45%;
}
.dynamic-button:hover {
font-size: 30px;
}

View File

@@ -16,7 +16,7 @@ import { MonitorService } from '../../../service/monitor.service';
@Component({
selector: 'app-monitor-modify',
templateUrl: './monitor-edit.component.html',
styles: []
styleUrls: ['./monitor-edit.component.less']
})
export class MonitorEditComponent implements OnInit {
constructor(
@@ -30,6 +30,8 @@ export class MonitorEditComponent implements OnInit {
paramDefines!: ParamDefine[];
params!: Param[];
advancedParamDefines!: ParamDefine[];
advancedParams!: Param[];
paramValueMap = new Map<String, Param>();
monitor = new Monitor();
profileForm: FormGroup = new FormGroup({});
@@ -59,7 +61,6 @@ export class MonitorEditComponent implements OnInit {
this.paramValueMap.set(item.field, item);
});
}
this.params = message.data.params;
this.detected = message.data.detected ? message.data.detected : true;
} else {
console.warn(message.msg);
@@ -73,7 +74,10 @@ export class MonitorEditComponent implements OnInit {
if (message.code === 0) {
this.paramDefines = message.data;
this.params = [];
this.paramDefines.forEach(define => {
this.advancedParams = [];
this.paramDefines = [];
this.advancedParamDefines = [];
message.data.forEach(define => {
let param = this.paramValueMap.get(define.field);
if (param === undefined) {
param = new Param();
@@ -100,7 +104,13 @@ export class MonitorEditComponent implements OnInit {
}
}
}
if (define.hide) {
this.advancedParams.push(param);
this.advancedParamDefines.push(define);
} else {
this.params.push(param);
this.paramDefines.push(define);
}
});
} else {
console.warn(message.msg);
@@ -144,10 +154,15 @@ export class MonitorEditComponent implements OnInit {
param.value = (param.value as string).trim();
}
});
this.advancedParams.forEach(param => {
if (param.value != null && typeof param.value == 'string') {
param.value = (param.value as string).trim();
}
});
let addMonitor = {
detected: this.detected,
monitor: this.monitor,
params: this.params
params: this.params.concat(this.advancedParams)
};
this.isSpinning = true;
this.monitorSvc.editMonitor(addMonitor).subscribe(
@@ -188,10 +203,15 @@ export class MonitorEditComponent implements OnInit {
param.value = (param.value as string).trim();
}
});
this.advancedParams.forEach(param => {
if (param.value != null && typeof param.value == 'string') {
param.value = (param.value as string).trim();
}
});
let detectMonitor = {
detected: this.detected,
monitor: this.monitor,
params: this.params
params: this.params.concat(this.advancedParams)
};
this.isSpinning = true;
this.monitorSvc.detectMonitor(detectMonitor).subscribe(

View File

@@ -171,6 +171,146 @@
</nz-form-control>
</nz-form-item>
<nz-collapse [nzGhost]="true">
<nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
<nz-form-label
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
nzSpan="8"
[nzErrorTip]="'validation.required' | i18n"
>
<input
nz-input
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
[name]="paramDefine.field"
[type]="paramDefine.type"
[id]="paramDefine.field"
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
/>
</nz-form-control>
<nz-form-label
*ngIf="paramDefine.type === 'textarea'"
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'textarea'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<textarea
nz-input
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
[name]="paramDefine.field"
[id]="paramDefine.field"
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
rows="3"
></textarea>
</nz-form-control>
<nz-form-label
*ngIf="paramDefine.type === 'password'"
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-input-group [nzSuffix]="suffixTemplate" style="width: 100%">
<input
[type]="passwordVisible ? 'text' : 'password'"
nz-input
placeholder="input password"
[required]="paramDefine.required"
[(ngModel)]="advancedParams[i].value"
[id]="paramDefine.field"
[name]="paramDefine.field"
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
/>
</nz-input-group>
<ng-template #suffixTemplate>
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i>
</ng-template>
</nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'number'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-input-number
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
[nzMin]="-1000"
[nzMax]="65535"
[nzStep]="1"
[nzPlaceHolder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
[name]="paramDefine.field"
[id]="paramDefine.field"
></nz-input-number>
</nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'boolean'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-switch
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
[name]="paramDefine.field"
[id]="paramDefine.field"
></nz-switch>
</nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'radio'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-radio-group
[(ngModel)]="advancedParams[i].value"
[required]="paramDefine.required"
nzButtonStyle="solid"
[name]="paramDefine.field"
[id]="paramDefine.field"
>
<label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options">
{{ optionItem.label }}
</label>
</nz-radio-group>
</nz-form-control>
<nz-form-label
*ngIf="paramDefine.type === 'key-value'"
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'key-value'" nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<app-key-value-input
[(value)]="advancedParams[i].value"
[id]="paramDefine.field"
keyAlias="Header Name"
valueAlias="Header Value"
></app-key-value-input>
</nz-form-control>
</nz-form-item>
</nz-collapse-panel>
</nz-collapse>
<ng-template #extraColHeader>
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
<span>高级设置</span>
<i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button>
</ng-template>
<nz-divider></nz-divider>
<nz-form-item>

View File

@@ -20,6 +20,8 @@ import { MonitorService } from '../../../service/monitor.service';
export class MonitorNewComponent implements OnInit {
paramDefines!: ParamDefine[];
params!: Param[];
advancedParamDefines!: ParamDefine[];
advancedParams!: Param[];
monitor!: Monitor;
detected: boolean = true;
passwordVisible: boolean = false;
@@ -53,9 +55,11 @@ export class MonitorNewComponent implements OnInit {
)
.subscribe(message => {
if (message.code === 0) {
this.paramDefines = message.data;
this.params = [];
this.paramDefines.forEach(define => {
this.advancedParams = [];
this.paramDefines = [];
this.advancedParamDefines = [];
message.data.forEach(define => {
let param = new Param();
param.field = define.field;
if (define.type === 'number') {
@@ -77,7 +81,13 @@ export class MonitorNewComponent implements OnInit {
param.value = define.defaultValue;
}
}
if (define.hide) {
this.advancedParams.push(param);
this.advancedParamDefines.push(define);
} else {
this.params.push(param);
this.paramDefines.push(define);
}
});
} else {
console.warn(message.msg);
@@ -125,10 +135,15 @@ export class MonitorNewComponent implements OnInit {
param.value = (param.value as string).trim();
}
});
this.advancedParams.forEach(param => {
if (param.value != null && typeof param.value == 'string') {
param.value = (param.value as string).trim();
}
});
let addMonitor = {
detected: this.detected,
monitor: this.monitor,
params: this.params
params: this.params.concat(this.advancedParams)
};
this.isSpinning = true;
this.monitorSvc.newMonitor(addMonitor).subscribe(
@@ -169,10 +184,15 @@ export class MonitorNewComponent implements OnInit {
param.value = (param.value as string).trim();
}
});
this.advancedParams.forEach(param => {
if (param.value != null && typeof param.value == 'string') {
param.value = (param.value as string).trim();
}
});
let detectMonitor = {
detected: true,
monitor: this.monitor,
params: this.params
params: this.params.concat(this.advancedParams)
};
this.isSpinning = true;
this.monitorSvc.detectMonitor(detectMonitor).subscribe(

View File

@@ -16,6 +16,7 @@ import { MonitorEditComponent } from './monitor-edit/monitor-edit.component';
import { MonitorListComponent } from './monitor-list/monitor-list.component';
import { MonitorNewComponent } from './monitor-new/monitor-new.component';
import { MonitorRoutingModule } from './monitor-routing.module';
import { NzCollapseModule } from 'ng-zorro-antd/collapse';
const COMPONENTS: Array<Type<void>> = [
MonitorNewComponent,
@@ -37,7 +38,8 @@ const COMPONENTS: Array<Type<void>> = [
NzRadioModule,
NgxEchartsModule,
NzLayoutModule,
NzSpaceModule
NzSpaceModule,
NzCollapseModule
],
declarations: COMPONENTS
})