diff --git a/alerter/src/main/java/com/usthe/alert/controller/AlertsController.java b/alerter/src/main/java/com/usthe/alert/controller/AlertsController.java index 238e9bd..3482efa 100644 --- a/alerter/src/main/java/com/usthe/alert/controller/AlertsController.java +++ b/alerter/src/main/java/com/usthe/alert/controller/AlertsController.java @@ -1,5 +1,6 @@ package com.usthe.alert.controller; +import com.usthe.alert.dto.AlertSummary; import com.usthe.common.entity.alerter.Alert; import com.usthe.alert.service.AlertService; import com.usthe.common.entity.dto.Message; @@ -114,4 +115,11 @@ public class AlertsController { return ResponseEntity.ok(message); } + @GetMapping(path = "/summary") + @ApiOperation(value = "获取告警统计信息", notes = "获取告警统计信息") + public ResponseEntity> getAlertsSummary() { + AlertSummary alertSummary = alertService.getAlertsSummary(); + Message message = new Message<>(alertSummary); + return ResponseEntity.ok(message); + } } diff --git a/alerter/src/main/java/com/usthe/alert/dao/AlertDao.java b/alerter/src/main/java/com/usthe/alert/dao/AlertDao.java index 35cd920..56ac51f 100644 --- a/alerter/src/main/java/com/usthe/alert/dao/AlertDao.java +++ b/alerter/src/main/java/com/usthe/alert/dao/AlertDao.java @@ -1,5 +1,6 @@ package com.usthe.alert.dao; +import com.usthe.alert.dto.AlertPriorityNum; import com.usthe.common.entity.alerter.Alert; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; @@ -32,4 +33,10 @@ public interface AlertDao extends JpaRepository, JpaSpecificationEx @Query("update Alert set status = :status where id in :ids") void updateAlertsStatus(@Param(value = "status") Byte status, @Param(value = "ids") List ids); + /** + * 查询各个告警级别的未处理告警数量 + * @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 findAlertPriorityNum(); } diff --git a/alerter/src/main/java/com/usthe/alert/dto/AlertPriorityNum.java b/alerter/src/main/java/com/usthe/alert/dto/AlertPriorityNum.java new file mode 100644 index 0000000..81d590c --- /dev/null +++ b/alerter/src/main/java/com/usthe/alert/dto/AlertPriorityNum.java @@ -0,0 +1,18 @@ +package com.usthe.alert.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * 监控级别告警数量 + * @author tom + * @date 2022/3/6 19:52 + */ +@Data +@AllArgsConstructor +public class AlertPriorityNum { + + private byte priority; + + private long num; +} diff --git a/alerter/src/main/java/com/usthe/alert/dto/AlertSummary.java b/alerter/src/main/java/com/usthe/alert/dto/AlertSummary.java new file mode 100644 index 0000000..7a21d5c --- /dev/null +++ b/alerter/src/main/java/com/usthe/alert/dto/AlertSummary.java @@ -0,0 +1,39 @@ +package com.usthe.alert.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY; + +/** + * 告警统计信息 + * @author tom + * @date 2022/3/6 19:25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(description = "告警统计信息") +public class AlertSummary { + + @ApiModelProperty(value = "告警总数量(包括已处理未处理告警)", example = "134", accessMode = READ_ONLY, position = 0) + private long total; + + @ApiModelProperty(value = "已处理告警数量", example = "34", accessMode = READ_ONLY, position = 1) + private long dealNum; + + @ApiModelProperty(value = "告警处理率", example = "39.34", accessMode = READ_ONLY, position = 2) + private float rate; + + @ApiModelProperty(value = "告警级别为警告告警的告警数量(指未处理告警)", example = "43", accessMode = READ_ONLY, position = 3) + private long priorityWarningNum; + + @ApiModelProperty(value = "告警级别为严重告警的告警数量(指未处理告警)", example = "56", accessMode = READ_ONLY, position = 4) + private long priorityCriticalNum; + + @ApiModelProperty(value = "告警级别为紧急告警的告警数量(指未处理告警)", example = "23", accessMode = READ_ONLY, position = 5) + private long priorityEmergencyNum; +} diff --git a/alerter/src/main/java/com/usthe/alert/service/AlertService.java b/alerter/src/main/java/com/usthe/alert/service/AlertService.java index c46504b..cca85d1 100644 --- a/alerter/src/main/java/com/usthe/alert/service/AlertService.java +++ b/alerter/src/main/java/com/usthe/alert/service/AlertService.java @@ -1,5 +1,6 @@ package com.usthe.alert.service; +import com.usthe.alert.dto.AlertSummary; import com.usthe.common.entity.alerter.Alert; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -42,4 +43,11 @@ public interface AlertService { * @param ids 待修改的告警IDs */ void editAlertStatus(Byte status, List ids); + + /** + * 获取告警统计信息 + * @return 告警统计 + */ + AlertSummary getAlertsSummary(); + } diff --git a/alerter/src/main/java/com/usthe/alert/service/impl/AlertServiceImpl.java b/alerter/src/main/java/com/usthe/alert/service/impl/AlertServiceImpl.java index 883cf47..6e9bc47 100644 --- a/alerter/src/main/java/com/usthe/alert/service/impl/AlertServiceImpl.java +++ b/alerter/src/main/java/com/usthe/alert/service/impl/AlertServiceImpl.java @@ -1,8 +1,11 @@ package com.usthe.alert.service.impl; import com.usthe.alert.dao.AlertDao; +import com.usthe.alert.dto.AlertPriorityNum; +import com.usthe.alert.dto.AlertSummary; import com.usthe.common.entity.alerter.Alert; import com.usthe.alert.service.AlertService; +import com.usthe.common.util.CommonConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -11,6 +14,8 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.HashSet; import java.util.List; @@ -47,4 +52,37 @@ public class AlertServiceImpl implements AlertService { alertDao.updateAlertsStatus(status, ids); } + @Override + public AlertSummary getAlertsSummary() { + AlertSummary alertSummary = new AlertSummary(); + List priorityNums = alertDao.findAlertPriorityNum(); + if (priorityNums != null) { + for (AlertPriorityNum priorityNum : priorityNums) { + switch (priorityNum.getPriority()) { + case CommonConstants + .ALERT_PRIORITY_CODE_WARNING: + alertSummary.setPriorityWarningNum(priorityNum.getNum());break; + case CommonConstants.ALERT_PRIORITY_CODE_CRITICAL: + alertSummary.setPriorityCriticalNum(priorityNum.getNum());break; + case CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY: + alertSummary.setPriorityEmergencyNum(priorityNum.getNum());break; + default: break; + } + } + } + long total = alertDao.count(); + long dealNum = total - alertSummary.getPriorityCriticalNum() + - alertSummary.getPriorityEmergencyNum() - alertSummary.getPriorityWarningNum(); + alertSummary.setDealNum(dealNum); + try { + float rate = BigDecimal.valueOf(100 * (float) dealNum / total) + .setScale(2, RoundingMode.HALF_UP) + .floatValue(); + alertSummary.setRate(rate); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return alertSummary; + } + } diff --git a/manager/src/main/java/com/usthe/manager/dao/MonitorDao.java b/manager/src/main/java/com/usthe/manager/dao/MonitorDao.java index 4f4a28c..c479242 100644 --- a/manager/src/main/java/com/usthe/manager/dao/MonitorDao.java +++ b/manager/src/main/java/com/usthe/manager/dao/MonitorDao.java @@ -55,11 +55,11 @@ public interface MonitorDao extends JpaRepository, JpaSpecificati Optional findMonitorByNameEquals(String name); /** - * 查询监控类别及其对应的监控数量 - * @return 监控类别与监控数量映射 + * 查询监控类别-状态对应的监控数量 + * @return 监控类别-状态与监控数量映射 */ - @Query("select new com.usthe.manager.pojo.dto.AppCount(mo.app, COUNT(mo.id)) from Monitor mo group by mo.app") - List findAppsCount(); + @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 findAppsStatusCount(); /** * 更新指定监控的状态 diff --git a/manager/src/main/java/com/usthe/manager/pojo/dto/AppCount.java b/manager/src/main/java/com/usthe/manager/pojo/dto/AppCount.java index ac98e90..e83060a 100644 --- a/manager/src/main/java/com/usthe/manager/pojo/dto/AppCount.java +++ b/manager/src/main/java/com/usthe/manager/pojo/dto/AppCount.java @@ -12,8 +12,43 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @Data public class AppCount { - /**监控类型**/ + + public AppCount(String app, byte status, Long size) { + this.app = app; + this.status = status; + this.size = size; + } + + /** + * 监控大类别 + */ + private String category; + /** + * 监控类型 + */ private String app; - /**监控数量**/ - private Long size; + /** + * 监控状态 + */ + private transient byte status; + /** + * 监控数量 + */ + private long size; + /** + * 监控状态可用的数量 + */ + private long availableSize; + /** + * 监控状态未管理的数量 + */ + private long unManageSize; + /** + * 监控状态不可用的数量 + */ + private long unAvailableSize; + /** + * 监控状态不可达的数量 + */ + private long unReachableSize; } diff --git a/manager/src/main/java/com/usthe/manager/service/impl/MonitorServiceImpl.java b/manager/src/main/java/com/usthe/manager/service/impl/MonitorServiceImpl.java index e9e130c..53b229d 100644 --- a/manager/src/main/java/com/usthe/manager/service/impl/MonitorServiceImpl.java +++ b/manager/src/main/java/com/usthe/manager/service/impl/MonitorServiceImpl.java @@ -30,6 +30,7 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -379,8 +380,40 @@ public class MonitorServiceImpl implements MonitorService { @Override public List getAllAppMonitorsCount() { - return monitorDao.findAppsCount(); - + List appCounts = monitorDao.findAppsStatusCount(); + if (appCounts == null) { + return null; + } + // 关联大类别信息 计算每个状态对应数量 + Map appCountMap = new HashMap<>(appCounts.size()); + for (AppCount item : appCounts) { + AppCount appCount = appCountMap.getOrDefault(item.getApp(), new AppCount()); + appCount.setApp(item.getApp()); + switch (item.getStatus()) { + case CommonConstants.AVAILABLE_CODE: + appCount.setAvailableSize(appCount.getAvailableSize() + item.getSize()); + break; + case CommonConstants.UN_AVAILABLE_CODE: + appCount.setUnAvailableSize(appCount.getUnAvailableSize() + item.getSize()); + break; + case CommonConstants.UN_MANAGE_CODE: + appCount.setUnManageSize(appCount.getUnManageSize() + item.getSize()); + break; + case CommonConstants.UN_REACHABLE_CODE: + appCount.setUnReachableSize(appCount.getUnReachableSize() + item.getSize()); + break; + default: break; + } + appCountMap.put(item.getApp(), appCount); + } + return appCountMap.values().stream().peek(item -> { + item.setSize(item.getAvailableSize() + item.getUnManageSize() + + item.getUnReachableSize() + item.getUnAvailableSize()); + Job job = appService.getAppDefine(item.getApp()); + if (job != null) { + item.setCategory(job.getCategory()); + } + }).collect(Collectors.toList()); } @Override diff --git a/web-app/src/app/pojo/AppCount.ts b/web-app/src/app/pojo/AppCount.ts new file mode 100644 index 0000000..4bb9924 --- /dev/null +++ b/web-app/src/app/pojo/AppCount.ts @@ -0,0 +1,9 @@ +export class AppCount { + category!: string; + app!: string; + size: number = 0; + availableSize: number = 0; + unManageSize: number = 0; + unAvailableSize: number = 0; + unReachableSize: number = 0; +} diff --git a/web-app/src/app/routes/dashboard/dashboard.component.html b/web-app/src/app/routes/dashboard/dashboard.component.html index 876a91b..da2f7cf 100644 --- a/web-app/src/app/routes/dashboard/dashboard.component.html +++ b/web-app/src/app/routes/dashboard/dashboard.component.html @@ -1,3 +1,106 @@ +
+
+
+
+
{{ appCountService.size }}
+

+ + {{ 'monitor.category.service' | i18n }} +

+
+
+ + 正常 {{ appCountService.availableSize }} + + + 不可用 {{ appCountService.unAvailableSize }} + + + 不可达 {{ appCountService.unReachableSize }} + + + 未监控 {{ appCountService.unManageSize }} + +
+
+
+
+
+
+
{{ appCountDb.size }}
+

+ + {{ 'monitor.category.db' | i18n }} +

+
+
+ + 正常 {{ appCountDb.availableSize }} + + + 不可用 {{ appCountDb.unAvailableSize }} + + + 不可达 {{ appCountDb.unReachableSize }} + + + 未监控 {{ appCountDb.unManageSize }} + +
+
+
+
+
+
+
{{ appCountOs.size }}
+

+ + {{ 'monitor.category.os' | i18n }} +

+
+
+ + 正常 {{ appCountOs.availableSize }} + + + 不可用 {{ appCountOs.unAvailableSize }} + + + 不可达 {{ appCountOs.unReachableSize }} + + + 未监控 {{ appCountOs.unManageSize }} + +
+
+
+
+
+
+
{{ appCountCustom.size }}
+

+ + {{ 'monitor.category.custom' | i18n }} +

+
+
+ + 正常 {{ appCountCustom.availableSize }} + + + 不可用 {{ appCountCustom.unAvailableSize }} + + + 不可达 {{ appCountCustom.unReachableSize }} + + + 未监控 {{ appCountCustom.unManageSize }} + +
+
+
+
+
+ +
+
+ + + +

+ + + 紧急告警 + + + + 严重告警 + + + + 警告告警 + + [{{ alert.monitorName }}] + {{ alert.content }} +

+
+
+
+
+
+
+
+
+
+
+
+ + + 进入告警中心 + diff --git a/web-app/src/app/routes/dashboard/dashboard.component.less b/web-app/src/app/routes/dashboard/dashboard.component.less index e6bd4b0..5d520e8 100644 --- a/web-app/src/app/routes/dashboard/dashboard.component.less +++ b/web-app/src/app/routes/dashboard/dashboard.component.less @@ -1,3 +1,97 @@ -.demo-chart { - height: auto; +@import '~@delon/theme/index'; +:host ::ng-deep { + .ant-timeline { + .ant-timeline-label { + left: 20%; + width: calc(20% - 12px); + } + .ant-timeline-item-tail { + left: 20%; + } + .ant-timeline-item-head { + left: 20%; + } + .ant-timeline-item-label { + width: calc(20% - 12px); + } + .ant-timeline-item-left { + .ant-timeline-item-content { + left: calc(20% - 4px); + width: calc(80% - 14px); + } + } + } + .ant-card-head-title { + padding-top: 6px; + padding-right: 0; + padding-bottom: 6px; + padding-left: 0; + } + .ant-card-head { + min-height: 24px; + padding: 0 12px; + font-weight: 400; + font-size: 12px; + } + .ant-card-body { + padding-top: 24px; + padding-right: 24px; + padding-bottom: 6px; + padding-left: 24px; + } + .ant-timeline-item { + padding-bottom: 10px; + } + } + +[data-theme='dark'] { + :host ::ng-deep { + .ant-timeline { + .ant-timeline-label { + left: 20%; + width: calc(20% - 12px); + } + .ant-timeline-item-tail { + left: 20%; + } + .ant-timeline-item-head { + left: 20%; + } + .ant-timeline-item-label { + width: calc(20% - 12px); + } + .ant-timeline-item-left { + .ant-timeline-item-content { + left: calc(20% - 4px); + width: calc(80% - 14px); + } + } + } + } +} + +[data-theme='compact'] { + :host ::ng-deep { + .ant-timeline { + .ant-timeline-label { + left: 20%; + width: calc(20% - 12px); + } + .ant-timeline-item-tail { + left: 20%; + } + .ant-timeline-item-head { + left: 20%; + } + .ant-timeline-item-label { + width: calc(20% - 12px); + } + .ant-timeline-item-left { + .ant-timeline-item-content { + left: calc(20% - 4px); + width: calc(80% - 14px); + } + } + } + } } diff --git a/web-app/src/app/routes/dashboard/dashboard.component.ts b/web-app/src/app/routes/dashboard/dashboard.component.ts index 1e836cd..7d0c282 100644 --- a/web-app/src/app/routes/dashboard/dashboard.component.ts +++ b/web-app/src/app/routes/dashboard/dashboard.component.ts @@ -6,6 +6,9 @@ import { EChartsOption } from 'echarts'; import { NzMessageService } from 'ng-zorro-antd/message'; import { fromEvent } from 'rxjs'; +import { Alert } from '../../pojo/Alert'; +import { AppCount } from '../../pojo/AppCount'; +import { AlertService } from '../../service/alert.service'; import { MonitorService } from '../../service/monitor.service'; @Component({ @@ -18,21 +21,31 @@ export class DashboardComponent implements OnInit, OnDestroy { constructor( private msg: NzMessageService, private monitorSvc: MonitorService, + private alertSvc: AlertService, @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService, private router: Router, private cdr: ChangeDetectorRef ) {} + // start 大类别数量信息 + appCountService: AppCount = new AppCount(); + appCountOs: AppCount = new AppCount(); + appCountDb: AppCount = new AppCount(); + appCountCustom: AppCount = new AppCount(); + + // start 数量全局概览 interval$!: number; appsCountLoading: boolean = true; appsCountTableData: any[] = []; appsCountEChartOption!: EChartsOption; appsCountTheme!: EChartsOption; - echartsInstance!: any; + appsCountEchartsInstance!: any; pageResize$!: any; + // 告警列表 + alerts!: Alert[]; + ngOnInit(): void { - this.appsCountLoading = true; this.appsCountTheme = { title: { text: '监控总览', @@ -112,8 +125,86 @@ export class DashboardComponent implements OnInit, OnDestroy { } ] }; + this.alertsTheme = { + title: { + subtext: '告警等级分布', + left: 'center' + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' + } + }, + xAxis: { + type: 'category', + data: ['警告告警', '严重告警', '紧急告警'] + }, + yAxis: { + type: 'value' + }, + series: [ + { + name: '告警数量', + type: 'bar', + data: [ + { + value: 0, + // 设置单个柱子的样式 + itemStyle: { + color: '#ffb72b', + shadowColor: '#91cc75' + } + }, + { + value: 0, + itemStyle: { + color: '#fa6202', + shadowColor: '#91cc75' + } + }, + { + value: 0, + itemStyle: { + color: '#dc1313', + shadowColor: '#91cc75' + } + } + ] + } + ] + }; + this.alertsDealTheme = { + title: { + subtext: '告警处理', + left: 'center' + }, + tooltip: { + formatter: '{b} : {c}%' + }, + series: [ + { + name: '告警处理率', + type: 'gauge', + progress: { + show: true + }, + detail: { + valueAnimation: true, + formatter: '{value}' + }, + data: [ + { + value: 0, + name: '告警处理率' + } + ] + } + ] + }; + this.appsCountLoading = true; + this.alertsLoading = true; this.refresh(); - this.appsCountLoading = false; // https://stackoverflow.com/questions/43908009/why-is-setinterval-in-an-angular-service-only-firing-one-time this.interval$ = setInterval(this.refresh.bind(this), 30000); this.pageResize$ = fromEvent(window, 'resize').subscribe(event => { @@ -129,12 +220,21 @@ export class DashboardComponent implements OnInit, OnDestroy { } refresh(): void { + this.refreshAppsCount(); + this.refreshAlertContentList(); + this.refreshAlertSummary(); + } + refreshAppsCount(): void { + this.appCountService = new AppCount(); + this.appCountOs = new AppCount(); + this.appCountDb = new AppCount(); + this.appCountCustom = new AppCount(); let dashboard$ = this.monitorSvc.getAppsMonitorSummary().subscribe( message => { dashboard$.unsubscribe(); if (message.code === 0 && message.data.apps != undefined) { // {app:'linux',size: 12} - let apps: any[] = message.data.apps; + let apps: AppCount[] = message.data.apps; this.appsCountTableData = []; let total = 0; apps.forEach(app => { @@ -147,6 +247,36 @@ export class DashboardComponent implements OnInit, OnDestroy { value: app.size }); total = total + (app.size ? app.size : 0); + switch (app.category) { + case 'service': + this.appCountService.size += app.size; + this.appCountService.availableSize += app.availableSize; + this.appCountService.unAvailableSize += app.unAvailableSize; + this.appCountService.unManageSize += app.unManageSize; + this.appCountService.unReachableSize += app.unReachableSize; + break; + case 'db': + this.appCountDb.size += app.size; + this.appCountDb.availableSize += app.availableSize; + this.appCountDb.unAvailableSize += app.unAvailableSize; + this.appCountDb.unManageSize += app.unManageSize; + this.appCountDb.unReachableSize += app.unReachableSize; + break; + case 'os': + this.appCountOs.size += app.size; + this.appCountOs.availableSize += app.availableSize; + this.appCountOs.unAvailableSize += app.unAvailableSize; + this.appCountOs.unManageSize += app.unManageSize; + this.appCountOs.unReachableSize += app.unReachableSize; + break; + case 'custom': + this.appCountCustom.size += app.size; + this.appCountCustom.availableSize += app.availableSize; + this.appCountCustom.unAvailableSize += app.unAvailableSize; + this.appCountCustom.unManageSize += app.unManageSize; + this.appCountCustom.unReachableSize += app.unReachableSize; + break; + } }); // @ts-ignore this.appsCountTheme.series[0].data = [{ value: total, name: '监控总量' }]; @@ -158,9 +288,11 @@ export class DashboardComponent implements OnInit, OnDestroy { this.appsCountEChartOption = this.appsCountTheme; this.cdr.detectChanges(); } + this.appsCountLoading = false; }, error => { console.error(error); + this.appsCountLoading = false; dashboard$.unsubscribe(); } ); @@ -175,12 +307,113 @@ export class DashboardComponent implements OnInit, OnDestroy { } } - onChartInit(ec: any) { - this.echartsInstance = ec; + onAppsCountChartInit(ec: any) { + this.appsCountEchartsInstance = ec; + } + onAlertNumChartInit(ec: any) { + this.alertsEchartsInstance = ec; + } + onAlertRateChartInit(ec: any) { + this.alertsDealEchartsInstance = ec; } resizeChart() { - if (this.echartsInstance) { - this.echartsInstance.resize(); + if (this.appsCountEchartsInstance) { + this.appsCountEchartsInstance.resize(); + } + if (this.alertsEchartsInstance) { + this.alertsEchartsInstance.resize(); + } + if (this.alertsDealEchartsInstance) { + this.alertsDealEchartsInstance.resize(); } } + + // start 告警分布 + alertsEChartOption!: EChartsOption; + alertsTheme!: EChartsOption; + alertsEchartsInstance!: any; + alertsLoading: boolean = true; + + refreshAlerts(): void { + this.alertsEChartOption = this.alertsTheme; + this.cdr.detectChanges(); + this.alertsLoading = false; + } + + // start 告警处理率 + alertsDealEChartOption!: EChartsOption; + alertsDealTheme!: EChartsOption; + alertsDealEchartsInstance!: any; + alertsDealLoading: boolean = true; + + refreshAlertContentList(): void { + let alertsInit$ = this.alertSvc.getAlerts(0, 4).subscribe( + message => { + if (message.code === 0) { + let page = message.data; + this.alerts = page.content; + } else { + console.warn(message.msg); + } + alertsInit$.unsubscribe(); + }, + error => { + alertsInit$.unsubscribe(); + console.error(error.msg); + } + ); + } + + refreshAlertSummary(): void { + let alertSummaryInit$ = this.alertSvc.getAlertsSummary().subscribe( + message => { + if (message.code === 0) { + let summary = message.data; + // @ts-ignore + this.alertsTheme.series[0].data = [ + { + value: summary.priorityWarningNum, + itemStyle: { + color: '#ffb72b', + shadowColor: '#91cc75' + } + }, + { + value: summary.priorityCriticalNum, + itemStyle: { + color: '#fa6202', + shadowColor: '#91cc75' + } + }, + { + value: summary.priorityEmergencyNum, + itemStyle: { + color: '#dc1313', + shadowColor: '#91cc75' + } + } + ]; + // @ts-ignore + this.alertsDealTheme.series[0].data = [ + { + value: summary.rate, + name: '告警处理率' + } + ]; + this.alertsEChartOption = this.alertsTheme; + this.alertsDealEChartOption = this.alertsDealTheme; + this.cdr.detectChanges(); + } else { + console.warn(message.msg); + } + alertSummaryInit$.unsubscribe(); + }, + error => { + alertSummaryInit$.unsubscribe(); + this.alertsDealLoading = false; + this.alertsLoading = false; + console.error(error.msg); + } + ); + } } diff --git a/web-app/src/app/routes/routes.module.ts b/web-app/src/app/routes/routes.module.ts index d348c66..c76a06b 100644 --- a/web-app/src/app/routes/routes.module.ts +++ b/web-app/src/app/routes/routes.module.ts @@ -10,6 +10,8 @@ import { UserLockComponent } from './passport/lock/lock.component'; // passport pages import { UserLoginComponent } from './passport/login/login.component'; import { RouteRoutingModule } from './routes-routing.module'; +import { NzTagModule } from 'ng-zorro-antd/tag'; +import { NzTimelineModule } from 'ng-zorro-antd/timeline'; const COMPONENTS: Array> = [ DashboardComponent, @@ -20,7 +22,7 @@ const COMPONENTS: Array> = [ ]; @NgModule({ - imports: [SharedModule, RouteRoutingModule, NgxEchartsModule], + imports: [SharedModule, RouteRoutingModule, NgxEchartsModule, NzTagModule, NzTimelineModule], declarations: COMPONENTS }) export class RoutesModule {} diff --git a/web-app/src/app/service/alert.service.ts b/web-app/src/app/service/alert.service.ts index 38671b7..5280c98 100644 --- a/web-app/src/app/service/alert.service.ts +++ b/web-app/src/app/service/alert.service.ts @@ -7,7 +7,7 @@ import { Message } from '../pojo/Message'; import { Page } from '../pojo/Page'; const alerts_uri = '/alerts'; - +const alerts_summary_uri = '/alerts/summary'; const alerts_status_uri = '/alerts/status'; @Injectable({ @@ -82,4 +82,8 @@ export class AlertService { const options = { params: httpParams }; return this.http.put>(`${alerts_status_uri}/${status}`, null, options); } + + public getAlertsSummary(): Observable> { + return this.http.get>(alerts_summary_uri); + } } diff --git a/web-app/src/assets/app-data.json b/web-app/src/assets/app-data.json index 3a2c19e..717f924 100644 --- a/web-app/src/assets/app-data.json +++ b/web-app/src/assets/app-data.json @@ -44,7 +44,7 @@ { "key": "os", "text": "操作系统", - "hide": true, + "hide": false, "i18n": "menu.monitor.os", "icon": "anticon-windows" }, diff --git a/web-app/src/assets/i18n/zh-CN.json b/web-app/src/assets/i18n/zh-CN.json index 127442a..ede0685 100644 --- a/web-app/src/assets/i18n/zh-CN.json +++ b/web-app/src/assets/i18n/zh-CN.json @@ -44,7 +44,8 @@ "service": "应用服务", "db": "数据库", "os": "操作系统", - "mid": "中间件" + "mid": "中间件", + "custom": "自定义监控" }, "app": { "": "监控类型",