From df5fe15973a74f935b6ba938c49f3a5cce60955e Mon Sep 17 00:00:00 2001 From: tomsun28 Date: Thu, 15 Jun 2023 21:46:20 +0800 Subject: [PATCH] add monitors center and support tag group (#1029) --- .../common/entity/alerter/AlertSilence.java | 1 + .../controller/MonitorsController.java | 323 +++++++++--------- .../layout/basic/widgets/search.component.ts | 2 +- .../alert-center/alert-center.component.html | 6 +- .../routes/dashboard/dashboard.component.html | 4 +- .../monitor-list/monitor-list.component.html | 52 ++- .../monitor-list/monitor-list.component.ts | 45 ++- .../src/app/routes/routes-routing.module.ts | 1 - .../routes/setting/tags/tags.component.html | 17 +- .../app/routes/setting/tags/tags.component.ts | 2 + web-app/src/app/service/monitor.service.ts | 17 +- web-app/src/app/shared/utils/common-util.ts | 9 + web-app/src/assets/app-data.json | 6 + web-app/src/assets/i18n/en-US.json | 7 +- web-app/src/assets/i18n/zh-CN.json | 7 +- web-app/src/assets/i18n/zh-TW.json | 7 +- 16 files changed, 282 insertions(+), 224 deletions(-) create mode 100644 web-app/src/app/shared/utils/common-util.ts diff --git a/common/src/main/java/org/dromara/hertzbeat/common/entity/alerter/AlertSilence.java b/common/src/main/java/org/dromara/hertzbeat/common/entity/alerter/AlertSilence.java index 3230d50db3d..73f1ca717f8 100644 --- a/common/src/main/java/org/dromara/hertzbeat/common/entity/alerter/AlertSilence.java +++ b/common/src/main/java/org/dromara/hertzbeat/common/entity/alerter/AlertSilence.java @@ -98,6 +98,7 @@ public class AlertSilence { @Schema(description = "匹配告警信息标签(monitorId:xxx,monitorName:xxx)", example = "{name: key1, value: value1}", accessMode = READ_WRITE) @Convert(converter = JsonTagListAttributeConverter.class) + @Column(length = 2048) private List tags; @Schema(title = "周期性静默时有效 星期几,多选,全选或空则为每天 7:周日 1:周一 2:周二 3:周三 4:周四 5:周五 6:周六", example = "[0,1]", accessMode = READ_WRITE) diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/controller/MonitorsController.java b/manager/src/main/java/org/dromara/hertzbeat/manager/controller/MonitorsController.java index 7c7786722a9..f9357534b81 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/controller/MonitorsController.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/controller/MonitorsController.java @@ -56,164 +56,167 @@ @RestController @RequestMapping(path = "/api/monitors", produces = {APPLICATION_JSON_VALUE}) public class MonitorsController { - - private static final byte ALL_MONITOR_STATUS = 9; - - @Autowired - private MonitorService monitorService; - - @GetMapping - @Operation(summary = "Obtain a list of monitoring information based on query filter items", - description = "根据查询过滤项获取监控信息列表") - public ResponseEntity>> getMonitors( - @Parameter(description = "Monitor ID | 监控ID", example = "6565463543") @RequestParam(required = false) final List ids, - @Parameter(description = "Monitor Type | 监控类型", example = "linux") @RequestParam(required = false) final String app, - @Parameter(description = "Monitor Name | 监控名称,模糊查询", example = "linux-127.0.0.1") @RequestParam(required = false) final String name, - @Parameter(description = "Monitor Host | 监控Host,模糊查询", example = "127.0.0.1") @RequestParam(required = false) final String host, - @Parameter(description = "Monitor Status | 监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起,9:全部状态", example = "1") @RequestParam(required = false) final Byte status, - @Parameter(description = "Sort Field | 排序字段", example = "name") @RequestParam(defaultValue = "gmtCreate") final String sort, - @Parameter(description = "Sort by | 排序方式,asc:升序,desc:降序", example = "desc") @RequestParam(defaultValue = "desc") final String order, - @Parameter(description = "List current page | 列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex, - @Parameter(description = "Number of list pagination | 列表分页数量", example = "8") @RequestParam(defaultValue = "8") int pageSize, - @Parameter(description = "Monitor tags | 监控标签", example = "") @RequestBody(required = false) final List tags) { - Specification specification = (root, query, criteriaBuilder) -> { - List andList = new ArrayList<>(); - if (ids != null && !ids.isEmpty()) { - CriteriaBuilder.In inPredicate = criteriaBuilder.in(root.get("id")); - for (long id : ids) { - inPredicate.value(id); - } - andList.add(inPredicate); - } - if (StringUtils.hasText(app)) { - Predicate predicateApp = criteriaBuilder.equal(root.get("app"), app); - andList.add(predicateApp); - } - if (status != null && status >= 0 && status < ALL_MONITOR_STATUS) { - Predicate predicateStatus = criteriaBuilder.equal(root.get("status"), status); - andList.add(predicateStatus); - } - - if (tags != null && !tags.isEmpty()) { - tags.stream().forEach(tag->{ - ListJoin monitors = root - .join(root.getModel() - .getList("tags", org.dromara.hertzbeat.common.entity.manager.Tag.class), JoinType.LEFT); - andList.add(criteriaBuilder.equal(monitors.get("id"), tag.getId())); - }); - } - Predicate[] andPredicates = new Predicate[andList.size()]; - Predicate andPredicate = criteriaBuilder.and(andList.toArray(andPredicates)); - - List orList = new ArrayList<>(); - if (StringUtils.hasText(host)) { - Predicate predicateHost = criteriaBuilder.like(root.get("host"), "%" + host + "%"); - orList.add(predicateHost); - } - if (StringUtils.hasText(name)) { - Predicate predicateName = criteriaBuilder.like(root.get("name"), "%" + name + "%"); - orList.add(predicateName); - } - Predicate[] orPredicates = new Predicate[orList.size()]; - Predicate orPredicate = criteriaBuilder.or(orList.toArray(orPredicates)); - - if (andPredicate.getExpressions().isEmpty() && orPredicate.getExpressions().isEmpty()) { - return query.where().getRestriction(); - } else if (andPredicate.getExpressions().isEmpty()) { - return query.where(orPredicate).getRestriction(); - } else if (orPredicate.getExpressions().isEmpty()) { - return query.where(andPredicate).getRestriction(); - } else { - return query.where(andPredicate, orPredicate).getRestriction(); - } - }; - // Pagination is a must 分页是必须的 - Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort)); - PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp); - Page monitorPage = monitorService.getMonitors(specification, pageRequest); - Message> message = new Message<>(monitorPage); - return ResponseEntity.ok(message); - } - - @GetMapping(path = "/{app}") - @Operation(summary = "Filter all acquired monitoring information lists of the specified monitoring type according to the query", - description = "根据查询过滤指定监控类型的所有获取监控信息列表") - public ResponseEntity>> getAppMonitors( - @Parameter(description = "en: Monitoring type,zh: 监控类型", example = "linux") @PathVariable(required = false) final String app) { - List monitors = monitorService.getAppMonitors(app); - Message> message = new Message<>(monitors); - return ResponseEntity.ok(message); - } - - @DeleteMapping - @Operation(summary = "Delete monitoring items in batches according to the monitoring ID list", - description = "根据监控ID列表批量删除监控项") - public ResponseEntity> deleteMonitors( - @Parameter(description = "en: Monitoring ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List ids - ) { - if (ids != null && !ids.isEmpty()) { - monitorService.deleteMonitors(new HashSet<>(ids)); - } - Message message = new Message<>(); - return ResponseEntity.ok(message); - } - - @DeleteMapping("manage") - @Operation(summary = "Unmanaged monitoring items in batches according to the monitoring ID list", - description = "根据监控ID列表批量取消纳管监控项") - public ResponseEntity> cancelManageMonitors( - @Parameter(description = "en: Monitoring ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List ids - ) { - if (ids != null && !ids.isEmpty()) { - monitorService.cancelManageMonitors(new HashSet<>(ids)); - } - Message message = new Message<>(); - return ResponseEntity.ok(message); - } - - @GetMapping("manage") - @Operation(summary = "Start the managed monitoring items in batches according to the monitoring ID list", - description = "根据监控ID列表批量启动纳管监控项") - public ResponseEntity> enableManageMonitors( - @Parameter(description = "Monitor ID List | 监控ID列表", example = "6565463543") @RequestParam(required = false) List ids - ) { - if (ids != null && !ids.isEmpty()) { - monitorService.enableManageMonitors(new HashSet<>(ids)); - } - Message message = new Message<>(); - return ResponseEntity.ok(message); - } - - @GetMapping("/export") - @Operation(summary = "export monitor config", description = "导出监控配置") - public void export( - @Parameter(description = "Monitor ID List | 监控ID列表", example = "6565463543") @RequestParam List ids, - @Parameter(description = "Export Type:JSON,EXCEL,YAML") @RequestParam(defaultValue = "JSON") String type, - HttpServletResponse res) throws Exception { - monitorService.export(ids, type, res); - } - - @PostMapping("/import") - @Operation(summary = "import monitor config", description = "导入监控配置") - public ResponseEntity> export(MultipartFile file) throws Exception { - monitorService.importConfig(file); - return ResponseEntity.ok(new Message<>("Import success")); - } - - - @PostMapping("/copy") - @Operation(summary = "copy monitors by ids", description = "根据id批量复制monitor") - public ResponseEntity> duplicateMonitors( - @Parameter(description = "Monitor ID List | 监控ID列表", example = "6565463543") @RequestParam List ids - ) throws Exception { - if (ids != null && !ids.isEmpty()) { - monitorService.copyMonitors(ids); - } - return ResponseEntity.ok(new Message<>("copy success")); - } - - - - - + + private static final byte ALL_MONITOR_STATUS = 9; + + @Autowired + private MonitorService monitorService; + + @GetMapping + @Operation(summary = "Obtain a list of monitoring information based on query filter items", + description = "根据查询过滤项获取监控信息列表") + public ResponseEntity>> getMonitors( + @Parameter(description = "Monitor ID | 监控ID", example = "6565463543") @RequestParam(required = false) final List ids, + @Parameter(description = "Monitor Type | 监控类型", example = "linux") @RequestParam(required = false) final String app, + @Parameter(description = "Monitor Name | 监控名称,模糊查询", example = "linux-127.0.0.1") @RequestParam(required = false) final String name, + @Parameter(description = "Monitor Host | 监控Host,模糊查询", example = "127.0.0.1") @RequestParam(required = false) final String host, + @Parameter(description = "Monitor Status | 监控状态 0:未监控,1:可用,2:不可用,3:不可达,4:挂起,9:全部状态", example = "1") @RequestParam(required = false) final Byte status, + @Parameter(description = "Sort Field | 排序字段", example = "name") @RequestParam(defaultValue = "gmtCreate") final String sort, + @Parameter(description = "Sort by | 排序方式,asc:升序,desc:降序", example = "desc") @RequestParam(defaultValue = "desc") final String order, + @Parameter(description = "List current page | 列表当前分页", example = "0") @RequestParam(defaultValue = "0") int pageIndex, + @Parameter(description = "Number of list pagination | 列表分页数量", example = "8") @RequestParam(defaultValue = "8") int pageSize, + @Parameter(description = "Monitor tag | 监控标签", example = "env:prod") @RequestParam(required = false) final String tag) { + Specification specification = (root, query, criteriaBuilder) -> { + List andList = new ArrayList<>(); + if (ids != null && !ids.isEmpty()) { + CriteriaBuilder.In inPredicate = criteriaBuilder.in(root.get("id")); + for (long id : ids) { + inPredicate.value(id); + } + andList.add(inPredicate); + } + if (StringUtils.hasText(app)) { + Predicate predicateApp = criteriaBuilder.equal(root.get("app"), app); + andList.add(predicateApp); + } + if (status != null && status >= 0 && status < ALL_MONITOR_STATUS) { + Predicate predicateStatus = criteriaBuilder.equal(root.get("status"), status); + andList.add(predicateStatus); + } + + if (StringUtils.hasText(tag)) { + String[] tagArr = tag.split(":"); + String tagName = tagArr[0]; + String tagValue = tagArr[1]; + ListJoin tagJoin = root + .join(root.getModel() + .getList("tags", org.dromara.hertzbeat.common.entity.manager.Tag.class), JoinType.LEFT); + if (tagArr.length == 2) { + andList.add(criteriaBuilder.equal(tagJoin.get("name"), tagName)); + andList.add(criteriaBuilder.equal(tagJoin.get("value"), tagValue)); + } else { + andList.add(criteriaBuilder.equal(tagJoin.get("name"), tag)); + } + } + Predicate[] andPredicates = new Predicate[andList.size()]; + Predicate andPredicate = criteriaBuilder.and(andList.toArray(andPredicates)); + + List orList = new ArrayList<>(); + if (StringUtils.hasText(host)) { + Predicate predicateHost = criteriaBuilder.like(root.get("host"), "%" + host + "%"); + orList.add(predicateHost); + } + if (StringUtils.hasText(name)) { + Predicate predicateName = criteriaBuilder.like(root.get("name"), "%" + name + "%"); + orList.add(predicateName); + } + Predicate[] orPredicates = new Predicate[orList.size()]; + Predicate orPredicate = criteriaBuilder.or(orList.toArray(orPredicates)); + + if (andPredicate.getExpressions().isEmpty() && orPredicate.getExpressions().isEmpty()) { + return query.where().getRestriction(); + } else if (andPredicate.getExpressions().isEmpty()) { + return query.where(orPredicate).getRestriction(); + } else if (orPredicate.getExpressions().isEmpty()) { + return query.where(andPredicate).getRestriction(); + } else { + return query.where(andPredicate, orPredicate).getRestriction(); + } + }; + // Pagination is a must 分页是必须的 + Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort)); + PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp); + Page monitorPage = monitorService.getMonitors(specification, pageRequest); + Message> message = new Message<>(monitorPage); + return ResponseEntity.ok(message); + } + + @GetMapping(path = "/{app}") + @Operation(summary = "Filter all acquired monitoring information lists of the specified monitoring type according to the query", + description = "根据查询过滤指定监控类型的所有获取监控信息列表") + public ResponseEntity>> getAppMonitors( + @Parameter(description = "en: Monitoring type,zh: 监控类型", example = "linux") @PathVariable(required = false) final String app) { + List monitors = monitorService.getAppMonitors(app); + Message> message = new Message<>(monitors); + return ResponseEntity.ok(message); + } + + @DeleteMapping + @Operation(summary = "Delete monitoring items in batches according to the monitoring ID list", + description = "根据监控ID列表批量删除监控项") + public ResponseEntity> deleteMonitors( + @Parameter(description = "en: Monitoring ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List ids + ) { + if (ids != null && !ids.isEmpty()) { + monitorService.deleteMonitors(new HashSet<>(ids)); + } + Message message = new Message<>(); + return ResponseEntity.ok(message); + } + + @DeleteMapping("manage") + @Operation(summary = "Unmanaged monitoring items in batches according to the monitoring ID list", + description = "根据监控ID列表批量取消纳管监控项") + public ResponseEntity> cancelManageMonitors( + @Parameter(description = "en: Monitoring ID List,zh: 监控ID列表", example = "6565463543") @RequestParam(required = false) List ids + ) { + if (ids != null && !ids.isEmpty()) { + monitorService.cancelManageMonitors(new HashSet<>(ids)); + } + Message message = new Message<>(); + return ResponseEntity.ok(message); + } + + @GetMapping("manage") + @Operation(summary = "Start the managed monitoring items in batches according to the monitoring ID list", + description = "根据监控ID列表批量启动纳管监控项") + public ResponseEntity> enableManageMonitors( + @Parameter(description = "Monitor ID List | 监控ID列表", example = "6565463543") @RequestParam(required = false) List ids + ) { + if (ids != null && !ids.isEmpty()) { + monitorService.enableManageMonitors(new HashSet<>(ids)); + } + Message message = new Message<>(); + return ResponseEntity.ok(message); + } + + @GetMapping("/export") + @Operation(summary = "export monitor config", description = "导出监控配置") + public void export( + @Parameter(description = "Monitor ID List | 监控ID列表", example = "6565463543") @RequestParam List ids, + @Parameter(description = "Export Type:JSON,EXCEL,YAML") @RequestParam(defaultValue = "JSON") String type, + HttpServletResponse res) throws Exception { + monitorService.export(ids, type, res); + } + + @PostMapping("/import") + @Operation(summary = "import monitor config", description = "导入监控配置") + public ResponseEntity> export(MultipartFile file) throws Exception { + monitorService.importConfig(file); + return ResponseEntity.ok(new Message<>("Import success")); + } + + + @PostMapping("/copy") + @Operation(summary = "copy monitors by ids", description = "根据id批量复制monitor") + public ResponseEntity> duplicateMonitors( + @Parameter(description = "Monitor ID List | 监控ID列表", example = "6565463543") @RequestParam List ids + ) throws Exception { + if (ids != null && !ids.isEmpty()) { + monitorService.copyMonitors(ids); + } + return ResponseEntity.ok(new Message<>("copy success")); + } + + } diff --git a/web-app/src/app/layout/basic/widgets/search.component.ts b/web-app/src/app/layout/basic/widgets/search.component.ts index 72277e9e6eb..0e72cdcb2b9 100644 --- a/web-app/src/app/layout/basic/widgets/search.component.ts +++ b/web-app/src/app/layout/basic/widgets/search.component.ts @@ -95,7 +95,7 @@ export class HeaderSearchComponent implements AfterViewInit, OnDestroy { ) .subscribe(value => { // 远程加载搜索数据 - let searchMonitors$ = this.monitorSvc.searchMonitors(null, value, 9, 0, 10).subscribe( + let searchMonitors$ = this.monitorSvc.searchMonitors(undefined, undefined, value, 9, 0, 10).subscribe( message => { this.loading = false; searchMonitors$.unsubscribe(); diff --git a/web-app/src/app/routes/alert/alert-center/alert-center.component.html b/web-app/src/app/routes/alert/alert-center/alert-center.component.html index afc3bb2ac57..c8ee888c3e2 100644 --- a/web-app/src/app/routes/alert/alert-center/alert-center.component.html +++ b/web-app/src/app/routes/alert/alert-center/alert-center.component.html @@ -39,7 +39,7 @@ {{ 'common.search' | i18n }} @@ -159,7 +159,7 @@ [autoResize]="true" [loading]="alertsDealLoading" (chartInit)="onAlertRateChartInit($event)" - style="width: 100%; min-height: 300px" + style="width: 100%; height: 300px" class="ant-card ant-card-bordered ant-card-hoverable" > diff --git a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html index b36bd428c99..00f96e9b457 100644 --- a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html +++ b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html @@ -7,14 +7,32 @@ - - {{ 'monitors.list' | i18n }} - + + + {{ 'monitors.list' | i18n }} + {{ 'menu.monitor.center' | i18n }} + {{ 'monitor.app.' + app | i18n }} - + + + {{ tag }} + + - - {{ 'monitor.name' | i18n }} - {{ 'monitor.status' | i18n }} - {{ 'monitor.host' | i18n }} - {{ 'monitor.app' | i18n }} - {{ 'common.edit-time' | i18n }} - {{ 'common.edit' | i18n }} + {{ 'monitor.name' | i18n }} + {{ 'monitor.status' | i18n }} + {{ 'monitor.host' | i18n }} + {{ 'monitor.app' | i18n }} + {{ 'tag' | i18n }} + {{ 'common.edit-time' | i18n }} + {{ 'common.edit' | i18n }} @@ -174,6 +193,13 @@ + + + + {{ sliceTagName(tag) }} + + + {{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date : 'YYYY-MM-dd HH:mm:ss' }}