Compare commits

..

2 Commits

Author SHA1 Message Date
tomsun28
0e6bf1618a [collector]bugfix: non-supported character set when monitor GBK oracle 2022-04-11 16:20:32 +08:00
会编程的王学长
4f13875e01 [monitor]feature: Alarm and receiving Chinese and English support (#82)
* fix: 代码名称优化 #huacheng

* fix: msgtype更正名称 #huacheng

* fix: 企业微信更正名称 #huacheng

* feat: Alarm and receiving Chinese and English support #huacheng

Co-authored-by: tomsun28 <tomsun28@outlook.com>
2022-04-10 20:51:30 +08:00
53 changed files with 967 additions and 1401 deletions

View File

@@ -6,7 +6,7 @@
[comment]: <> (<img alt="sureness" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/hertzbeat-brand.svg" width="300">) [comment]: <> (<img alt="sureness" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/hertzbeat-brand.svg" width="300">)
## HertzBeat 赫兹跳动 | [English Documentation](README_EN.md) ## HertzBeat 赫兹跳动
> 易用友好的监控告警系统。 > 易用友好的监控告警系统。

View File

@@ -1,148 +0,0 @@
<p align="center">
<a href="https://hertzbeat.com">
<img alt="hertzbeat" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/hertzbeat-brand.svg" width="260">
</a>
</p>
[comment]: <> (<img alt="sureness" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/hertzbeat-brand.svg" width="300">)
## HertzBeat | [中文文档](README.md)
> Friendly cloud monitoring system.
![tan-cloud](https://img.shields.io/badge/web-monitor-4EB1BA)
![tan-cloud](https://img.shields.io/badge/api-monitor-lightgrey)
![tan-cloud](https://img.shields.io/badge/ping-connect-brightgreen)
![tan-cloud](https://img.shields.io/badge/port-available-green)
![tan-cloud](https://img.shields.io/badge/database-monitor-yellowgreen)
![tan-cloud](https://img.shields.io/badge/os-monitor-yellow)
![tan-cloud](https://img.shields.io/badge/custom-monitor-orange)
![tan-cloud](https://img.shields.io/badge/threshold-red)
![tan-cloud](https://img.shields.io/badge/alert-bule)
**Home: [hertzbeat.com](https://hertzbeat.com) | [tancloud.cn](https://tancloud.cn)**
## 🎡 <font color="green">Introduction</font>
> [HertzBeat](https://github.com/dromara/hertzbeat) is an opensource monitoring and alarm project incubated by [Dromara](https://dromara.org) and open sourced by [TanCloud](https://tancloud.cn), which supports Website, API, PING, Port, Database, OS Monitor etc.
> We also provide **[Monitoring Cloud For Saas](https://console.tancloud.cn)**, people no longer need to deploy a cumbersome monitoring system in order to monitor their website resources. **[Sign in to get started for free](https://console.tancloud.cn)**.
> HertzBeat supports more liberal threshold alarm configuration (calculation expression), supports alarm notification, alarm template, email, DingDing, WeChat FeiShu and WebHook.
> Most important is HertzBeat supports [Custom Monitoring](https://hertzbeat.com/docs/advanced/extend-point), just by configuring the YML file, we can customize the monitoring types and metrics what we need.
> HertzBeat is modular, `manager, collector, scheduler, warehouse, alerter` modules are decoupled for easy understanding and custom development.
> Welcome to HertzBeat's [Cloud Environment TanCloud](https://console.tancloud.cn) to try and discover more.
> Welcome to join us to build hertzbeat together.
> `HertzBeat`'s multi-type support, easy expansion, low coupling, hope to help developers and micro teams to quickly build their own monitoring system.
----
[![tancloud](tancloud.gif)](https://www.bilibili.com/video/BV1DY4y1i7ts)
----
## 🥐 Architecture
- **[manager](https://github.com/dromara/hertzbeat/tree/master/manager)** Provide monitoring management, system management basic services.
> Provides monitoring management, monitoring configuration management, system user management, etc.
- **[collector](https://github.com/dromara/hertzbeat/tree/master/collector)** Provide metrics data collection services.
> Use common protocols to remotely collect and obtain peer-to-peer metrics data.
- **[scheduler](https://github.com/dromara/hertzbeat/tree/master/scheduler)** Provide monitoring task scheduling service.
> Collection task management, scheduling and distribution of one-time tasks and periodic tasks.
- **[warehouse](https://github.com/dromara/hertzbeat/tree/master/warehouse)** Provide monitoring data warehousing services.
> Metrics data management, data query, calculation and statistics.
- **[alerter](https://github.com/dromara/hertzbeat/tree/master/alerter)** Provide alert service.
> Alarm calculation trigger, monitoring status linkage, alarm configuration, and alarm notification.
- **[web-app](https://github.com/dromara/hertzbeat/tree/master/web-app)** Provide web ui.
> Angular Web UI.
![hertzBeat](home/static/img/docs/hertzbeat-stru-en.svg)
## 🐕 Quick Start
- If you dont want to deploy but use it directly, we provide [SAAS Monitoring Cloud-TanCloud](https://console.tancloud.cn), **[Log In And Register For Free](https://console.tancloud.cn) **.
- If you want to deploy HertzBeat local, please refer to the following [Deployment Documentation](https://hertzbeat.com/docs/start/quickstart) for operation.
### 🐵 Dependency Service Deployment
> HertzBeat depends at least on relational database [MYSQL5+](https://www.mysql.com/) and time series database [TDengine2+](https://www.taosdata.com/getting-started)
##### Install MYSQL
1. Install mysql with docker
`docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7`
2. Create database names `hertzbeat`
3. Run the database sql script [schema.sql](https://gitee.com/dromara/hertzbeat/raw/master/script/sql/schema.sql) located in the project repository `/script/sql/` directory.
For detailed steps, refer to [MYSQL Installation And Initialization](https://hertzbeat.com/docs/start/mysql-init)
##### Install TDengine
1. Install TDengine with docker
`docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp --name tdengine tdengine/tdengine:2.4.0.12`
2. Create database names `hertzbeat`
For detailed steps, refer to [TDengine Installation And Initialization](https://hertzbeat.com/docs/start/tdengine-init).
### 🍞 Install HertzBeat
> HertzBeat supports installation through source code, docker or package.
##### 1Install quickly via docker
`docker run -d -p 1157:1157 -v /opt/application.yml:/opt/hertzbeat/config/application.yml --name hertzbeat tancloud/hertzbeat:[版本tag]`
Detailed steps refer to [Install HertzBeat via Docker](https://hertzbeat.com/docs/start/docker-deploy)
##### 2Install via package
1. Download the installation package [GITEE Release](https://gitee.com/dromara/hertzbeat/releases) [GITHUB Release](https://github.com/dromara/hertzbeat/releases)
2. Configure the HertzBeat configuration yml file `hertzbeat/config/application.yml`
3. Run shell `$ ./startup.sh `
4. Access `localhost:1157` to start, default account: `admin/admin`
Detailed steps refer to [Install HertzBeat via package](https://hertzbeat.com/docs/start/package-deploy)
##### 3Start via source code
1. Local source code debugging needs to start the back-end project manager and the front-end project web-app.
2. Backendneed `maven3+`, `java8+`, start the manager service.
3. Webneed `nodejs npm angular-cli` environment, Run `ng serve --open` in `web-app` directory after backend startup.
4. Access `localhost:4200` to start, default account: `admin/admin`
Detailed steps refer to [CONTRIBUTING](CONTRIBUTING.md)
##### 4Install All(mysql+tdengine+hertzbeat) via Docker-compose
Install and deploy the mysql database, tdengine database and hertzbeat at one time through [docker-compose deployment script](script/docker-compose).
Detailed steps refer to [docker-compose install](script/docker-compose/README.md)
**HAVE FUN**
## 💬 Join discussion
HertzBeat is an incubation project of [Dromara Open Source Community](https://dromara.org/).
##### WeChat Group
Add WeChat account `tan-cloud` or scan the QR code below to pull you into the WeChat group.
<img alt="tan-cloud" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/docs/help/tan-cloud-wechat.jpg" width="200"/>
##### QQ Group
QQ group number `718618151` or scan the group QR code below, verify code: `tancloud`
<img alt="tan-cloud" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/docs/help/qq-qr.jpg" width="200"/>
##### Github Discussion
Welcome to Discuss in [Github Discussion](https://github.com/dromara/hertzbeat/discussions)
##### Public WeChat
<img alt="tan-cloud" src="https://cdn.jsdelivr.net/gh/dromara/hertzbeat/home/static/img/wechat.png" width="400"/>
##### Sponsor
Thanks [吉实信息(构建全新的微波+光交易网络)](https://www.flarespeed.com) sponsored server node.
Thanks [天上云计算(全新智慧上云)](https://www.tsyvps.com/aff/BZBEGYLX) sponsored server node.
## 🛡️ License
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -115,6 +115,11 @@
<artifactId>ojdbc8</artifactId> <artifactId>ojdbc8</artifactId>
<version>21.5.0.0</version> <version>21.5.0.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.oracle.database.nls</groupId>
<artifactId>orai18n</artifactId>
<version>21.5.0.0</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

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

View File

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

View File

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

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 31 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -40,6 +40,7 @@ import java.util.stream.Collectors;
/** /**
* 监控管理服务实现 * 监控管理服务实现
*
* @author tomsun28 * @author tomsun28
* @date 2021/11/14 13:06 * @date 2021/11/14 13:06
*/ */
@@ -391,7 +392,8 @@ public class MonitorServiceImpl implements MonitorService {
if (appCounts == null) { if (appCounts == null) {
return null; return null;
} }
// 关联大类别信息 计算每个状态对应数量 //Statistical category information, calculate the number of corresponding states for each monitor
//统计类别信息,计算每个监控分别对应状态的数量
Map<String, AppCount> appCountMap = new HashMap<>(appCounts.size()); Map<String, AppCount> appCountMap = new HashMap<>(appCounts.size());
for (AppCount item : appCounts) { for (AppCount item : appCounts) {
AppCount appCount = appCountMap.getOrDefault(item.getApp(), new AppCount()); AppCount appCount = appCountMap.getOrDefault(item.getApp(), new AppCount());
@@ -409,10 +411,13 @@ public class MonitorServiceImpl implements MonitorService {
case CommonConstants.UN_REACHABLE_CODE: case CommonConstants.UN_REACHABLE_CODE:
appCount.setUnReachableSize(appCount.getUnReachableSize() + item.getSize()); appCount.setUnReachableSize(appCount.getUnReachableSize() + item.getSize());
break; break;
default: break; default:
break;
} }
appCountMap.put(item.getApp(), appCount); appCountMap.put(item.getApp(), appCount);
} }
//Traverse the map obtained by statistics and convert it into a List<App Count> result set
//遍历统计得到的map转换成List<App Count>结果集
return appCountMap.values().stream().peek(item -> { return appCountMap.values().stream().peek(item -> {
item.setSize(item.getAvailableSize() + item.getUnManageSize() item.setSize(item.getAvailableSize() + item.getUnManageSize()
+ item.getUnReachableSize() + item.getUnAvailableSize()); + item.getUnReachableSize() + item.getUnAvailableSize());

View File

@@ -4,7 +4,7 @@ category: custom
app: example app: example
name: name:
zh-CN: 模拟应用类型 zh-CN: 模拟应用类型
en-US: EXAMPLE en-US: EXAMPLE APP
# 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串, 3-map映射的json串 # 参数映射map. type是参数类型: 0-number数字, 1-string明文字符串, 2-secret加密字符串, 3-map映射的json串
# 强制固定必须参数 - host # 强制固定必须参数 - host
configmap: configmap:

View File

@@ -2,7 +2,7 @@ category: service
app: fullsite app: fullsite
name: name:
zh-CN: 全站监控 zh-CN: 全站监控
en-US: SITE MAP en-US: FULL WEBSITE MONITOR
configmap: configmap:
- key: host - key: host
type: 1 type: 1

View File

@@ -2,7 +2,7 @@ category: service
app: website app: website
name: name:
zh-CN: 网站监测 zh-CN: 网站监测
en-US: WEBSITE en-US: WEBSITE MONITOR
configmap: configmap:
- key: host - key: host
type: 1 type: 1

View File

@@ -71,9 +71,9 @@ import { environment } from '@env/environment';
<setting-drawer *ngIf="showSettingDrawer"></setting-drawer> <setting-drawer *ngIf="showSettingDrawer"></setting-drawer>
<theme-btn <theme-btn
[types]="[ [types]="[
{ key: 'default', text: 'app.theme.default' | i18n }, { key: 'default', text: '浅色主题' },
{ key: 'dark', text: 'app.theme.dark' | i18n }, { key: 'dark', text: '深色主题' },
{ key: 'compact', text: 'app.theme.compact' | i18n } { key: 'compact', text: '紧凑主题' }
]" ]"
></theme-btn> ></theme-btn>
` `

View File

@@ -1,6 +1,4 @@
import { ChangeDetectionStrategy, Component, HostListener, Inject } from '@angular/core'; import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzMessageService } from 'ng-zorro-antd/message'; import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
@@ -16,19 +14,15 @@ import { NzModalService } from 'ng-zorro-antd/modal';
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class HeaderClearStorageComponent { export class HeaderClearStorageComponent {
constructor( constructor(private modalSrv: NzModalService, private messageSrv: NzMessageService) {}
private modalSrv: NzModalService,
private messageSrv: NzMessageService,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {}
@HostListener('click') @HostListener('click')
_click(): void { _click(): void {
this.modalSrv.confirm({ this.modalSrv.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.clear-cache'), nzTitle: '请确认是否清理缓存?',
nzOnOk: () => { nzOnOk: () => {
localStorage.clear(); localStorage.clear();
this.messageSrv.success(this.i18nSvc.fanyi('common.notify.clear-success')); this.messageSrv.success('清理成功!');
} }
}); });
} }

View File

@@ -26,11 +26,11 @@ import { AlertService } from '../../../service/alert.service';
export class HeaderNotifyComponent implements OnInit { export class HeaderNotifyComponent implements OnInit {
data: NoticeItem[] = [ data: NoticeItem[] = [
{ {
title: this.i18nSvc.fanyi('dashboard.alerts.title-no'), title: '近期未处理告警',
list: [], list: [],
emptyText: this.i18nSvc.fanyi('dashboard.alerts.no'), emptyText: '暂无未处理告警',
emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg', emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
clearText: this.i18nSvc.fanyi('dashboard.alerts.enter') clearText: '进入告警中心'
} }
]; ];
count = 0; count = 0;
@@ -69,10 +69,10 @@ export class HeaderNotifyComponent implements OnInit {
let item = { let item = {
id: alert.id, id: alert.id,
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
title: `${alert.monitorName}--${this.i18nSvc.fanyi(`alert.priority.${alert.priority}`)}`, title: `监控-${alert.monitorName}-发出${this.i18nSvc.fanyi(`alert.priority.${alert.priority}`)}`,
datetime: alert.gmtCreate, datetime: alert.gmtCreate,
color: 'blue', color: 'blue',
type: this.i18nSvc.fanyi('dashboard.alerts.title-no') type: '近期未处理告警'
}; };
this.data[0].list.push(item); this.data[0].list.push(item);
}); });

View File

@@ -40,8 +40,8 @@ import { MonitorService } from '../../../service/monitor.service';
<nz-autocomplete nzBackfill="false" nzDefaultActiveFirstOption #auto> <nz-autocomplete nzBackfill="false" nzDefaultActiveFirstOption #auto>
<nz-auto-option *ngFor="let option of options" [nzValue]="option.id" [nzLabel]="option.name"> <nz-auto-option *ngFor="let option of options" [nzValue]="option.id" [nzLabel]="option.name">
<a [routerLink]="['/monitors/' + option.id]"> <a [routerLink]="['/monitors/' + option.id]">
{{ 'monitor.name' | i18n }} : {{ option.name }} 监控名称: {{ option.name }}
<span style="left:50% ; position: absolute;">{{ 'monitor.host' | i18n }} : {{ option.host }}</span> <span style="left:50% ; position: absolute;">监控Host: {{ option.host }}</span>
<span style="right: 10px; position: absolute;"><i nz-icon nzType="arrow-right" nzTheme="outline"></i></span> <span style="right: 10px; position: absolute;"><i nz-icon nzType="arrow-right" nzTheme="outline"></i></span>
</a> </a>
</nz-auto-option> </nz-auto-option>

View File

@@ -6,15 +6,15 @@
<img class="logo" src="./assets/logo.svg" alt="" /> <img class="logo" src="./assets/logo.svg" alt="" />
<span class="title">HertzBeat</span> <span class="title">HertzBeat</span>
</div> </div>
<div class="desc">{{ 'app.passport.desc' | i18n }}</div> <div class="desc">TanCloud-易用友好的高性能监控云服务</div>
</div> </div>
<router-outlet></router-outlet> <router-outlet></router-outlet>
<global-footer [links]="links"> <global-footer [links]="links">
Copyright Copyright
<i nz-icon nzType="copyright" nzTheme="outline"></i> <i nz-icon nzType="copyright" nzTheme="outline"></i>
2022 2022
<a href="https://tancloud.cn" target="_blank">TanCloud tancloud.cn | </a> <a href="https://tancloud.cn" target="_blank">探云 tancloud.cn | </a>
<a href="https://hertzbeat.com" target="_blank">HertzBeat hertzbeat.com</a> <a href="https://hertzbeat.com" target="_blank">赫兹跳动 hertzbeat.com</a>
</global-footer> </global-footer>
</div> </div>
</div> </div>

View File

@@ -1,7 +1,5 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, Inject, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
@Component({ @Component({
selector: 'layout-passport', selector: 'layout-passport',
@@ -11,12 +9,12 @@ import { ALAIN_I18N_TOKEN } from '@delon/theme';
export class LayoutPassportComponent implements OnInit { export class LayoutPassportComponent implements OnInit {
links = [ links = [
{ {
title: this.i18nSvc.fanyi('app.passport.welcome'), title: '欢迎使用TanCloud探云-监控云服务-tancloud.cn',
href: 'https://tancloud.cn' href: 'https://tancloud.cn'
} }
]; ];
constructor(@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService, @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService) {} constructor(@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService) {}
ngOnInit(): void { ngOnInit(): void {
this.tokenService.clear(); this.tokenService.clear();

View File

@@ -3,12 +3,12 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="alert"></i> <i nz-icon nzType="alert"></i>
<span>{{ 'menu.alert.center' | i18n }}</span> <span>告警中心</span>
</nz-breadcrumb-item> </nz-breadcrumb-item>
</nz-breadcrumb> </nz-breadcrumb>
<nz-divider></nz-divider> <nz-divider></nz-divider>
@@ -16,28 +16,26 @@
<div> <div>
<button nz-button nzType="primary" (click)="onDeleteAlerts()"> <button nz-button nzType="primary" (click)="onDeleteAlerts()">
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
{{ 'alert.center.delete' | i18n }} 删除告警
</button> </button>
<button nz-button nzType="primary" (click)="onMarkReadAlerts()"> <button nz-button nzType="primary" (click)="onMarkReadAlerts()">
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
{{ 'alert.center.deal' | i18n }} 标记已处理
</button> </button>
<button nz-button nzType="primary" (click)="onMarkUnReadAlerts()"> <button nz-button nzType="primary" (click)="onMarkUnReadAlerts()">
<i nz-icon nzType="up-circle" nzTheme="outline"></i> <i nz-icon nzType="up-circle" nzTheme="outline"></i>
{{ 'alert.center.no-deal' | i18n }} 标记未处理
</button> </button>
<button nz-button nzType="primary" (click)="sync()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="sync()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchAlerts()"> <button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchAlerts()"> 搜索 </button>
{{ 'common.search' | i18n }}
</button>
<input <input
style="margin-right: 5px; float: right; width: 150px; border-radius: 9px; text-align: center" style="margin-right: 5px; float: right; width: 150px; border-radius: 9px; text-align: center"
nz-input nz-input
type="text" type="text"
[placeholder]="'alert.center.search' | i18n" placeholder="搜索告警内容"
nzSize="default" nzSize="default"
(keyup.enter)="onFilterSearchAlerts()" (keyup.enter)="onFilterSearchAlerts()"
[(ngModel)]="filterContent" [(ngModel)]="filterContent"
@@ -45,24 +43,23 @@
<nz-select <nz-select
style="margin-right: 10px; float: right; width: 120px" style="margin-right: 10px; float: right; width: 120px"
nzAllowClear nzAllowClear
[nzPlaceHolder]="'alert.center.filter-status' | i18n" [nzPlaceHolder]="'告警状态过滤'"
[(ngModel)]="filterStatus" [(ngModel)]="filterStatus"
> >
<nz-option [nzLabel]="'alert.status.all' | i18n" nzValue="9"></nz-option> <nz-option nzLabel="全部状态" nzValue="9"></nz-option>
<nz-option [nzLabel]="'alert.status.0' | i18n" nzValue="0"></nz-option> <nz-option nzLabel="未处理" nzValue="0"></nz-option>
<nz-option [nzLabel]="'alert.status.2' | i18n" nzValue="2"></nz-option> <nz-option nzLabel="已处理" nzValue="3"></nz-option>
<nz-option [nzLabel]="'alert.status.3' | i18n" nzValue="3"></nz-option>
</nz-select> </nz-select>
<nz-select <nz-select
style="margin-right: 10px; float: right; width: 120px" style="margin-right: 10px; float: right; width: 120px"
nzAllowClear nzAllowClear
[nzPlaceHolder]="'alert.center.filter-priority' | i18n" [nzPlaceHolder]="'告警级别过滤'"
[(ngModel)]="filterPriority" [(ngModel)]="filterPriority"
> >
<nz-option [nzLabel]="'alert.priority.all' | i18n" nzValue="9"></nz-option> <nz-option nzLabel="全部级别" nzValue="9"></nz-option>
<nz-option [nzLabel]="'alert.priority.2' | i18n" nzValue="2"></nz-option> <nz-option nzLabel="警告级别" nzValue="2"></nz-option>
<nz-option [nzLabel]="'alert.priority.1' | i18n" nzValue="1"></nz-option> <nz-option nzLabel="严重级别" nzValue="1"></nz-option>
<nz-option [nzLabel]="'alert.priority.0' | i18n" nzValue="0"></nz-option> <nz-option nzLabel="紧急级别" nzValue="0"></nz-option>
</nz-select> </nz-select>
</div> </div>
@@ -84,13 +81,13 @@
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th> <th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th>
<th nzAlign="center" nzLeft>{{ 'alert.center.target' | i18n }}</th> <th nzAlign="center" nzLeft>告警指标</th>
<th nzAlign="center">{{ 'alert.center.monitor' | i18n }}</th> <th nzAlign="center">所属监控</th>
<th nzAlign="center">{{ 'alert.center.priority' | i18n }}</th> <th nzAlign="center">级别</th>
<th nzAlign="center">{{ 'alert.center.content' | i18n }}</th> <th nzAlign="center">告警内容</th>
<th nzAlign="center">{{ 'alert.center.status' | i18n }}</th> <th nzAlign="center">状态</th>
<th nzAlign="center">{{ 'alert.center.time' | i18n }}</th> <th nzAlign="center">告警时间</th>
<th nzAlign="center">{{ 'common.edit' | i18n }}</th> <th nzAlign="center">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -105,36 +102,30 @@
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.priority == 0" nzColor="red"> <nz-tag *ngIf="data.priority == 0" nzColor="red">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.0' | i18n }}</span> <span>紧急告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.priority == 1" nzColor="orange"> <nz-tag *ngIf="data.priority == 1" nzColor="orange">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.1' | i18n }}</span> <span>严重告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.priority == 2" nzColor="yellow"> <nz-tag *ngIf="data.priority == 2" nzColor="yellow">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.2' | i18n }}</span> <span>警告告警</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ data.content }}</td> <td nzAlign="center">{{ data.content }}</td>
<td nzAlign="center"> <td nzAlign="center">
{{ 'alert.status.' + data.status | i18n }} {{ data.status === 0 ? '未处理' : '已处理' }}
</td> </td>
<td nzAlign="center">{{ data.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ data.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button nz-button nzType="primary" (click)="onDeleteOneAlert(data.id)" nz-tooltip [nzTooltipTitle]="'alert.center.delete' | i18n"> <button nz-button nzType="primary" (click)="onDeleteOneAlert(data.id)" nz-tooltip nzTooltipTitle="删除告警">
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
<button nz-button nzType="primary" (click)="onMarkReadOneAlert(data.id)" nz-tooltip [nzTooltipTitle]="'alert.center.deal' | i18n"> <button nz-button nzType="primary" (click)="onMarkReadOneAlert(data.id)" nz-tooltip nzTooltipTitle="标记已处理">
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onMarkUnReadOneAlert(data.id)" nz-tooltip nzTooltipTitle="标记未处理">
nz-button
nzType="primary"
(click)="onMarkUnReadOneAlert(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.center.no-deal' | i18n"
>
<i nz-icon nzType="up-circle" nzTheme="outline"></i> <i nz-icon nzType="up-circle" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -142,4 +133,4 @@
</tbody> </tbody>
</nz-table> </nz-table>
<ng-template #rangeTemplate> {{ 'common.total' | i18n }} {{ total }} </ng-template> <ng-template #rangeTemplate> 总量 {{ total }} </ng-template>

View File

@@ -1,6 +1,4 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { NzTableQueryParams } from 'ng-zorro-antd/table'; import { NzTableQueryParams } from 'ng-zorro-antd/table';
@@ -14,12 +12,7 @@ import { AlertService } from '../../../service/alert.service';
styles: [] styles: []
}) })
export class AlertCenterComponent implements OnInit { export class AlertCenterComponent implements OnInit {
constructor( constructor(private notifySvc: NzNotificationService, private modal: NzModalService, private alertSvc: AlertService) {}
private notifySvc: NzNotificationService,
private modal: NzModalService,
private alertSvc: AlertService,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {}
pageIndex: number = 1; pageIndex: number = 1;
pageSize: number = 8; pageSize: number = 8;
@@ -94,13 +87,13 @@ export class AlertCenterComponent implements OnInit {
onDeleteAlerts() { onDeleteAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('alert.center.notify.no-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.delete-batch'), nzTitle: '请确认是否批量删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteAlerts(this.checkedAlertIds) nzOnOk: () => this.deleteAlerts(this.checkedAlertIds)
@@ -109,13 +102,13 @@ export class AlertCenterComponent implements OnInit {
onMarkReadAlerts() { onMarkReadAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('alert.center.notify.no-mark'), ''); this.notifySvc.warning('未选中任何待标记项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.mark-done-batch'), nzTitle: '请确认是否批量标记已处理!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 3) nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 3)
@@ -123,13 +116,13 @@ export class AlertCenterComponent implements OnInit {
} }
onMarkUnReadAlerts() { onMarkUnReadAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('alert.center.notify.no-mark'), ''); this.notifySvc.warning('未选中任何待标记项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.mark-no-batch'), nzTitle: '请确认是否批量标记未处理!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 0) nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 0)
@@ -140,9 +133,9 @@ export class AlertCenterComponent implements OnInit {
let alerts = new Set<number>(); let alerts = new Set<number>();
alerts.add(alertId); alerts.add(alertId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteAlerts(alerts) nzOnOk: () => this.deleteAlerts(alerts)
@@ -153,9 +146,9 @@ export class AlertCenterComponent implements OnInit {
let alerts = new Set<number>(); let alerts = new Set<number>();
alerts.add(alertId); alerts.add(alertId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.mark-done'), nzTitle: '请确认是否标记已处理!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(alerts, 3) nzOnOk: () => this.updateAlertsStatus(alerts, 3)
@@ -166,9 +159,9 @@ export class AlertCenterComponent implements OnInit {
let alerts = new Set<number>(); let alerts = new Set<number>();
alerts.add(alertId); alerts.add(alertId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('alert.center.confirm.mark-no'), nzTitle: '请确认是否标记未处理!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(alerts, 0) nzOnOk: () => this.updateAlertsStatus(alerts, 0)
@@ -181,17 +174,17 @@ export class AlertCenterComponent implements OnInit {
message => { message => {
deleteAlerts$.unsubscribe(); deleteAlerts$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadAlertsTable(); this.loadAlertsTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
deleteAlerts$.unsubscribe(); deleteAlerts$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
@@ -202,17 +195,17 @@ export class AlertCenterComponent implements OnInit {
message => { message => {
markAlertsStatus$.unsubscribe(); markAlertsStatus$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.mark-success'), ''); this.notifySvc.success('标记成功!', '');
this.loadAlertsTable(); this.loadAlertsTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.mark-fail'), message.msg); this.notifySvc.error('标记失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
markAlertsStatus$.unsubscribe(); markAlertsStatus$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.mark-fail'), error.msg); this.notifySvc.error('标记失败!', error.msg);
} }
); );
} }

View File

@@ -3,14 +3,14 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="alert"></i> <i nz-icon nzType="alert"></i>
<span>{{ 'menu.alert.dispatch' | i18n }}</span> <span>告警通知配置</span>
<a href="https://tancloud.cn/docs/help/alert_email" target="_blank" style="float: right; margin-right: 5%"> <a href="https://tancloud.cn/docs/help/alert_email" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }}&nbsp;</span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -18,12 +18,12 @@
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-tabset nzSize="large"> <nz-tabset nzSize="large">
<nz-tab [nzTitle]="'alert.notice.receiver' | i18n"> <nz-tab nzTitle="告警接收人">
<button nz-button nzType="primary" (click)="onNewNoticeReceiver()"> <button nz-button nzType="primary" (click)="onNewNoticeReceiver()">
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
{{ 'alert.notice.receiver.new' | i18n }} 新增接收人
</button> </button>
<button nz-button nzType="primary" (click)="syncReceiver()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="syncReceiver()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<nz-table <nz-table
@@ -35,11 +35,11 @@
> >
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzWidth="10%">{{ 'alert.notice.receiver.people' | i18n }}</th> <th nzAlign="center" nzWidth="10%">接收人</th>
<th nzAlign="center" nzWidth="20%">{{ 'alert.notice.receiver.type' | i18n }}</th> <th nzAlign="center" nzWidth="20%">通知方式</th>
<th nzAlign="center" nzWidth="20%">{{ 'alert.notice.receiver.setting' | i18n }}</th> <th nzAlign="center" nzWidth="20%">配置</th>
<th nzAlign="center" nzWidth="20%">{{ 'common.edit-time' | i18n }}</th> <th nzAlign="center" nzWidth="20%">最新修改时间</th>
<th nzAlign="center" nzWidth="30%">{{ 'common.edit' | i18n }}</th> <th nzAlign="center" nzWidth="30%">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -50,11 +50,11 @@
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.type == 0" nzColor="orange"> <nz-tag *ngIf="data.type == 0" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.sms' | i18n }}</span> <span>短信</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 1" nzColor="orange"> <nz-tag *ngIf="data.type == 1" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.email' | i18n }}</span> <span>邮件</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 2" nzColor="orange"> <nz-tag *ngIf="data.type == 2" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
@@ -62,19 +62,19 @@
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 3" nzColor="orange"> <nz-tag *ngIf="data.type == 3" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.wechat' | i18n }}</span> <span>微信公众号</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 4" nzColor="orange"> <nz-tag *ngIf="data.type == 4" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.wework' | i18n }}</span> <span>企业微信机器人</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 5" nzColor="orange"> <nz-tag *ngIf="data.type == 5" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.ding' | i18n }}</span> <span>钉钉机器人</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.type == 6" nzColor="orange"> <nz-tag *ngIf="data.type == 6" nzColor="orange">
<i nz-icon nzType="notification" nzTheme="outline"></i> <i nz-icon nzType="notification" nzTheme="outline"></i>
<span>{{ 'alert.notice.type.fei-shu' | i18n }}</span> <span>飞书机器人</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
@@ -88,22 +88,10 @@
</td> </td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button <button nz-button nzType="primary" (click)="onEditOneNoticeReceiver(data)" nz-tooltip nzTooltipTitle="修改接收人">
nz-button
nzType="primary"
(click)="onEditOneNoticeReceiver(data)"
nz-tooltip
[nzTooltipTitle]="'alert.notice.receiver.edit' | i18n"
>
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onDeleteOneNoticeReceiver(data.id)" nz-tooltip nzTooltipTitle="删除接收人">
nz-button
nzType="primary"
(click)="onDeleteOneNoticeReceiver(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.notice.receiver.delete' | i18n"
>
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -111,12 +99,12 @@
</tbody> </tbody>
</nz-table> </nz-table>
</nz-tab> </nz-tab>
<nz-tab [nzTitle]="'alert.notice.rule' | i18n"> <nz-tab nzTitle="告警通知策略">
<button nz-button nzType="primary" (click)="onNewNoticeRule()"> <button nz-button nzType="primary" (click)="onNewNoticeRule()">
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
{{ 'alert.notice.rule.new' | i18n }} 新增通知策略
</button> </button>
<button nz-button nzType="primary" (click)="syncRule()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="syncRule()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<nz-table <nz-table
@@ -128,12 +116,12 @@
> >
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzWidth="15%">{{ 'alert.notice.rule.name' | i18n }}</th> <th nzAlign="center" nzWidth="15%">策略名称</th>
<th nzAlign="center" nzWidth="12%">{{ 'alert.notice.receiver.people' | i18n }}</th> <th nzAlign="center" nzWidth="12%">接收人</th>
<th nzAlign="center" nzWidth="12%">{{ 'alert.notice.rule.all' | i18n }}</th> <th nzAlign="center" nzWidth="12%">转发所有</th>
<th nzAlign="center" nzWidth="15%">{{ 'alert.notice.rule.enable' | i18n }}</th> <th nzAlign="center" nzWidth="15%">是否启用</th>
<th nzAlign="center" nzWidth="15%">{{ 'common.edit-time' | i18n }}</th> <th nzAlign="center" nzWidth="15%">最新修改时间</th>
<th nzAlign="center" nzWidth="25%">{{ 'common.edit' | i18n }}</th> <th nzAlign="center" nzWidth="25%">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -146,38 +134,26 @@
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.filterAll" nzColor="green"> <nz-tag *ngIf="data.filterAll" nzColor="green">
<span>{{ 'common.yes' | i18n }}</span> <span></span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="!data.filterAll" nzColor="orange"> <nz-tag *ngIf="!data.filterAll" nzColor="orange">
<span>{{ 'common.no' | i18n }}</span> <span></span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.enable" nzColor="green"> <nz-tag *ngIf="data.enable" nzColor="green">
<span>{{ 'common.enable' | i18n }}</span> <span>开启</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="!data.enable" nzColor="orange"> <nz-tag *ngIf="!data.enable" nzColor="orange">
<span>{{ 'common.disable' | i18n }}</span> <span>关闭</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button <button nz-button nzType="primary" (click)="onEditOneNoticeRule(data)" nz-tooltip nzTooltipTitle="修改告警策略">
nz-button
nzType="primary"
(click)="onEditOneNoticeRule(data)"
nz-tooltip
[nzTooltipTitle]="'alert.notice.rule.edit' | i18n"
>
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onDeleteOneNoticeRule(data.id)" nz-tooltip nzTooltipTitle="删除告警策略">
nz-button
nzType="primary"
(click)="onDeleteOneNoticeRule(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.notice.rule.delete' | i18n"
>
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -190,7 +166,7 @@
<!-- 新增或修改通知接收人弹出框 --> <!-- 新增或修改通知接收人弹出框 -->
<nz-modal <nz-modal
[(nzVisible)]="isManageReceiverModalVisible" [(nzVisible)]="isManageReceiverModalVisible"
[nzTitle]="isManageReceiverModalAdd ? ('alert.notice.receiver.new' | i18n) : ('alert.notice.receiver.edit' | i18n)" [nzTitle]="isManageReceiverModalAdd ? '新增接收人' : '修改接收人'"
(nzOnCancel)="onManageReceiverModalCancel()" (nzOnCancel)="onManageReceiverModalCancel()"
(nzOnOk)="onManageReceiverModalOk()" (nzOnOk)="onManageReceiverModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
@@ -200,27 +176,27 @@
<div *nzModalContent class="-inner-content"> <div *nzModalContent class="-inner-content">
<form nz-form #receiverForm="ngForm"> <form nz-form #receiverForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true">{{ 'alert.notice.receiver.people.name' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true">接收人名称</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.name" nz-input required name="name" type="text" id="name" /> <input [(ngModel)]="receiver.name" nz-input required name="name" type="text" id="name" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="type">{{ 'alert.notice.receiver.type' | i18n }} </nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="type">通知方式 </nz-form-label>
<nz-form-control nzSpan="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control nzSpan="12" [nzErrorTip]="'validation.required' | i18n">
<nz-select [(ngModel)]="receiver.type" nzPlaceHolder="Choose" required name="type" id="type"> <nz-select [(ngModel)]="receiver.type" nzPlaceHolder="Choose" required name="type" id="type">
<nz-option [nzValue]="0" nzDisabled [nzLabel]="'alert.notice.type.sms' | i18n"></nz-option> <nz-option [nzValue]="0" nzDisabled nzLabel="短信"></nz-option>
<nz-option [nzValue]="1" [nzLabel]="'alert.notice.type.email' | i18n"></nz-option> <nz-option [nzValue]="1" nzLabel="邮箱"></nz-option>
<nz-option [nzValue]="2" nzLabel="WebHook"></nz-option> <nz-option [nzValue]="2" nzLabel="WebHook"></nz-option>
<nz-option [nzValue]="3" nzDisabled [nzLabel]="'alert.notice.type.wechat' | i18n"></nz-option> <nz-option [nzValue]="3" nzDisabled nzLabel="微信公众号"></nz-option>
<nz-option [nzValue]="4" [nzLabel]="'alert.notice.type.wework' | i18n"></nz-option> <nz-option [nzValue]="4" nzLabel="企业微信机器人"></nz-option>
<nz-option [nzValue]="5" [nzLabel]="'alert.notice.type.ding' | i18n"></nz-option> <nz-option [nzValue]="5" nzLabel="钉钉机器人"></nz-option>
<nz-option [nzValue]="6" [nzLabel]="'alert.notice.type.fei-shu' | i18n"></nz-option> <nz-option [nzValue]="6" nzLabel="飞书机器人"></nz-option>
</nz-select> </nz-select>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 0"> <nz-form-item *ngIf="receiver.type === 0">
<nz-form-label [nzSpan]="7" nzFor="phone" [nzRequired]="receiver.type === 0">{{ 'alert.notice.type.phone' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="phone" [nzRequired]="receiver.type === 0">手机号</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.phone.invalid' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.phone.invalid' | i18n">
<input <input
[(ngModel)]="receiver.phone" [(ngModel)]="receiver.phone"
@@ -234,45 +210,37 @@
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 1"> <nz-form-item *ngIf="receiver.type === 1">
<nz-form-label [nzSpan]="7" nzFor="email" [nzRequired]="receiver.type === 1">{{ 'alert.notice.type.email' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="email" [nzRequired]="receiver.type === 1">邮箱</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.email.invalid' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.email.invalid' | i18n">
<input [(ngModel)]="receiver.email" nz-input [required]="receiver.type === 1" email name="email" type="email" id="email" /> <input [(ngModel)]="receiver.email" nz-input [required]="receiver.type === 1" email name="email" type="email" id="email" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 2"> <nz-form-item *ngIf="receiver.type === 2">
<nz-form-label [nzSpan]="7" nzFor="hookUrl" [nzRequired]="receiver.type === 2">{{ 'alert.notice.type.url' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="hookUrl" [nzRequired]="receiver.type === 2">URL地址</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.hookUrl" nz-input [required]="receiver.type === 2" name="hookUrl" type="url" id="hookUrl" /> <input [(ngModel)]="receiver.hookUrl" nz-input [required]="receiver.type === 2" name="hookUrl" type="url" id="hookUrl" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 3"> <nz-form-item *ngIf="receiver.type === 3">
<nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 3">{{ <nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 3">微信OPENID</nz-form-label>
'alert.notice.type.wechat-id' | i18n
}}</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 3" name="wechatId" type="text" /> <input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 3" name="wechatId" type="text" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 4"> <nz-form-item *ngIf="receiver.type === 4">
<nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 4">{{ <nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 4">企业微信机器人KEY</nz-form-label>
'alert.notice.type.wework-key' | i18n
}}</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 4" name="wechatId" type="text" /> <input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 4" name="wechatId" type="text" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 5"> <nz-form-item *ngIf="receiver.type === 5">
<nz-form-label [nzSpan]="7" nzFor="accessToken" [nzRequired]="receiver.type === 5">{{ <nz-form-label [nzSpan]="7" nzFor="accessToken" [nzRequired]="receiver.type === 5">机器人ACCESS_TOKEN</nz-form-label>
'alert.notice.type.access-token' | i18n
}}</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.accessToken" nz-input [required]="receiver.type === 5" name="accessToken" type="text" /> <input [(ngModel)]="receiver.accessToken" nz-input [required]="receiver.type === 5" name="accessToken" type="text" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 6"> <nz-form-item *ngIf="receiver.type === 6">
<nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 6">{{ <nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 6">飞书机器人KEY</nz-form-label>
'alert.notice.type.fei-shu-key' | i18n
}}</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 6" name="wechatId" type="text" /> <input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 6" name="wechatId" type="text" />
</nz-form-control> </nz-form-control>
@@ -284,7 +252,7 @@
<!-- 新增或修改通知策略弹出框 --> <!-- 新增或修改通知策略弹出框 -->
<nz-modal <nz-modal
[(nzVisible)]="isManageRuleModalVisible" [(nzVisible)]="isManageRuleModalVisible"
[nzTitle]="isManageRuleModalAdd ? ('alert.notice.rule.new' | i18n) : ('alert.notice.rule.edit' | i18n)" [nzTitle]="isManageRuleModalAdd ? '新增策略' : '修改策略'"
(nzOnCancel)="onManageRuleModalCancel()" (nzOnCancel)="onManageRuleModalCancel()"
(nzOnOk)="onManageRuleModalOk()" (nzOnOk)="onManageRuleModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
@@ -294,19 +262,19 @@
<div *nzModalContent class="-inner-content"> <div *nzModalContent class="-inner-content">
<form nz-form #ruleForm="ngForm"> <form nz-form #ruleForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="rule_name" nzRequired="true">{{ 'alert.notice.rule.name' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="rule_name" nzRequired="true">策略名称</nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="rule.name" nz-input required name="rule_name" type="text" id="rule_name" /> <input [(ngModel)]="rule.name" nz-input required name="rule_name" type="text" id="rule_name" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="filterAll">{{ 'alert.notice.rule.all' | i18n }}</nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="filterAll">转发所有</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="rule.filterAll" disabled name="filterAll" id="filterAll"></nz-switch> <nz-switch [(ngModel)]="rule.filterAll" disabled name="filterAll" id="filterAll"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="receiver">{{ 'alert.notice.receiver.people' | i18n }}</nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="receiver">接收人</nz-form-label>
<nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-select <nz-select
[(ngModel)]="rule.receiverId" [(ngModel)]="rule.receiverId"
@@ -323,7 +291,7 @@
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="enable">{{ 'alert.notice.rule.enable' | i18n }}</nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="enable">是否启用</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="rule.enable" name="enable" id="enable"></nz-switch> <nz-switch [(ngModel)]="rule.enable" name="enable" id="enable"></nz-switch>
</nz-form-control> </nz-form-control>

View File

@@ -1,6 +1,4 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
@@ -20,8 +18,7 @@ export class AlertNoticeComponent implements OnInit {
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private noticeReceiverSvc: NoticeReceiverService, private noticeReceiverSvc: NoticeReceiverService,
private modal: NzModalService, private modal: NzModalService,
private noticeRuleSvc: NoticeRuleService, private noticeRuleSvc: NoticeRuleService
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {} ) {}
receivers!: NoticeReceiver[]; receivers!: NoticeReceiver[];
@@ -81,9 +78,9 @@ export class AlertNoticeComponent implements OnInit {
onDeleteOneNoticeReceiver(receiveId: number) { onDeleteOneNoticeReceiver(receiveId: number) {
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteOneNoticeReceiver(receiveId) nzOnOk: () => this.deleteOneNoticeReceiver(receiveId)
@@ -101,23 +98,23 @@ export class AlertNoticeComponent implements OnInit {
.subscribe( .subscribe(
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadReceiversTable(); this.loadReceiversTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
onDeleteOneNoticeRule(ruleId: number) { onDeleteOneNoticeRule(ruleId: number) {
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteOneNoticeRule(ruleId) nzOnOk: () => this.deleteOneNoticeRule(ruleId)
@@ -135,14 +132,14 @@ export class AlertNoticeComponent implements OnInit {
.subscribe( .subscribe(
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadRulesTable(); this.loadRulesTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
@@ -182,14 +179,14 @@ export class AlertNoticeComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageReceiverModalVisible = false; this.isManageReceiverModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.new-success'), ''); this.notifySvc.success('新增成功!', '');
this.loadReceiversTable(); this.loadReceiversTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), message.msg); this.notifySvc.error('新增失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), error.msg); this.notifySvc.error('新增失败!', error.msg);
} }
); );
} else { } else {
@@ -205,14 +202,14 @@ export class AlertNoticeComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageReceiverModalVisible = false; this.isManageReceiverModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.edit-success'), ''); this.notifySvc.success('修改成功!', '');
this.loadReceiversTable(); this.loadReceiversTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), message.msg); this.notifySvc.error('修改失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), error.msg); this.notifySvc.error('修改失败!', error.msg);
} }
); );
} }
@@ -313,14 +310,14 @@ export class AlertNoticeComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageRuleModalVisible = false; this.isManageRuleModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.new-success'), ''); this.notifySvc.success('新增成功!', '');
this.loadRulesTable(); this.loadRulesTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), message.msg); this.notifySvc.error('新增失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), error.msg); this.notifySvc.error('新增失败!', error.msg);
} }
); );
} else { } else {
@@ -336,14 +333,14 @@ export class AlertNoticeComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageRuleModalVisible = false; this.isManageRuleModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.edit-success'), ''); this.notifySvc.success('修改成功!', '');
this.loadRulesTable(); this.loadRulesTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), message.msg); this.notifySvc.error('修改失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), error.msg); this.notifySvc.error('修改失败!', error.msg);
} }
); );
} }

View File

@@ -3,14 +3,14 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="alert"></i> <i nz-icon nzType="alert"></i>
<span>{{ 'menu.alert.setting' | i18n }}</span> <span>告警阈值配置</span>
<a href="https://tancloud.cn/docs/help/alert_threshold" target="_blank" style="float: right; margin-right: 5%"> <a href="https://tancloud.cn/docs/help/alert_threshold" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }}&nbsp;</span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -19,17 +19,17 @@
<button nz-button nzType="primary" (click)="onNewAlertDefine()"> <button nz-button nzType="primary" (click)="onNewAlertDefine()">
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
{{ 'alert.setting.new' | i18n }} 新增阈值
</button> </button>
<button nz-button nzType="primary" (click)="onEditAlertDefine()"> <button nz-button nzType="primary" (click)="onEditAlertDefine()">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
{{ 'common.button.edit' | i18n }} 编辑
</button> </button>
<button nz-button nzType="primary" (click)="onDeleteAlertDefines()"> <button nz-button nzType="primary" (click)="onDeleteAlertDefines()">
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
{{ 'common.button.delete' | i18n }} 删除
</button> </button>
<button nz-button nzType="primary" (click)="sync()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="sync()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
@@ -51,14 +51,14 @@
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th> <th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th>
<th nzAlign="center" nzLeft>{{ 'alert.setting.target' | i18n }}</th> <th nzAlign="center" nzLeft>指标对象</th>
<th nzAlign="center">{{ 'alert.setting.expr' | i18n }}</th> <th nzAlign="center">阈值触发表达式</th>
<th nzAlign="center">{{ 'alert.priority' | i18n }}</th> <th nzAlign="center">告警级别</th>
<th nzAlign="center">{{ 'alert.setting.times' | i18n }}</th> <th nzAlign="center">触发次数</th>
<th nzAlign="center">{{ 'alert.setting.template' | i18n }}</th> <th nzAlign="center">通知模版</th>
<th nzAlign="center">{{ 'alert.setting.default' | i18n }}</th> <th nzAlign="center">全局默认</th>
<th nzAlign="center">{{ 'common.edit-time' | i18n }}</th> <th nzAlign="center">最新修改时间</th>
<th nzAlign="center">{{ 'common.edit' | i18n }}</th> <th nzAlign="center">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -73,54 +73,36 @@
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.priority == 0" nzColor="red"> <nz-tag *ngIf="data.priority == 0" nzColor="red">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.0' | i18n }}</span> <span>紧急告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.priority == 1" nzColor="orange"> <nz-tag *ngIf="data.priority == 1" nzColor="orange">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.1' | i18n }}</span> <span>严重告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.priority == 2" nzColor="yellow"> <nz-tag *ngIf="data.priority == 2" nzColor="yellow">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.2' | i18n }}</span> <span>警告告警</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ data.times }}</td> <td nzAlign="center">{{ data.times }}</td>
<td nzAlign="center">{{ data.template }}</td> <td nzAlign="center">{{ data.template }}</td>
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.preset" nzColor="green"> <nz-tag *ngIf="data.preset" nzColor="green">
<span>{{ 'common.yes' | i18n }}</span> <span></span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="!data.preset" nzColor="orange"> <nz-tag *ngIf="!data.preset" nzColor="orange">
<span>{{ 'common.no' | i18n }}</span> <span></span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button <button nz-button nzType="primary" (click)="onOpenConnectModal(data.id, data.app)" nz-tooltip nzTooltipTitle="配置关联监控">
nz-button
nzType="primary"
(click)="onOpenConnectModal(data.id, data.app)"
nz-tooltip
[nzTooltipTitle]="'alert.setting.connect' | i18n"
>
<i nz-icon nzType="link" nzTheme="outline"></i> <i nz-icon nzType="link" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onEditOneAlertDefine(data.id)" nz-tooltip nzTooltipTitle="修改告警配置">
nz-button
nzType="primary"
(click)="onEditOneAlertDefine(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.setting.edit' | i18n"
>
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onDeleteOneAlertDefine(data.id)" nz-tooltip nzTooltipTitle="删除告警配置">
nz-button
nzType="primary"
(click)="onDeleteOneAlertDefine(data.id)"
nz-tooltip
[nzTooltipTitle]="'alert.setting.delete' | i18n"
>
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -128,12 +110,12 @@
</tbody> </tbody>
</nz-table> </nz-table>
<ng-template #rangeTemplate> {{ 'common.total' | i18n }} {{ total }} </ng-template> <ng-template #rangeTemplate> 总量 {{ total }} </ng-template>
<!-- 新增或修改告警定义弹出框 --> <!-- 新增或修改告警定义弹出框 -->
<nz-modal <nz-modal
[(nzVisible)]="isManageModalVisible" [(nzVisible)]="isManageModalVisible"
[nzTitle]="isManageModalAdd ? ('alert.setting.new' | i18n) : ('alert.setting.edit' | i18n)" [nzTitle]="isManageModalAdd ? '新增告警阈值' : '修改告警阈值'"
(nzOnCancel)="onManageModalCancel()" (nzOnCancel)="onManageModalCancel()"
(nzOnOk)="onManageModalOk()" (nzOnOk)="onManageModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
@@ -143,7 +125,7 @@
<div *nzModalContent class="-inner-content"> <div *nzModalContent class="-inner-content">
<form nz-form #defineForm="ngForm"> <form nz-form #defineForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="target" nzRequired="true">{{ 'alert.setting.target' | i18n }}</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="target" nzRequired="true">指标对象</nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<nz-cascader <nz-cascader
required required
@@ -158,19 +140,19 @@
<nz-form-item> <nz-form-item>
<nz-col [nzSpan]="8" nzOffset="7"> <nz-col [nzSpan]="8" nzOffset="7">
<nz-collapse> <nz-collapse>
<nz-collapse-panel [nzActive]="isManageModalAdd" [nzHeader]="'alert.setting.expr.tip' | i18n"> <nz-collapse-panel [nzActive]="isManageModalAdd" nzHeader="支持的阈值触发表达式环境变量与操作符">
<nz-list nzSize="small" nzSplit="false"> <nz-list nzSize="small" nzSplit="false">
<nz-list-item *ngIf="cascadeValues.length == 3"> <nz-list-item *ngIf="cascadeValues.length == 3">
<code>{{ cascadeValues[2] }} : {{ 'alert.setting.target.tip' | i18n }}</code> <code>{{ cascadeValues[2] }} : 选中的指标对象</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngFor="let item of otherMetrics"> <nz-list-item *ngFor="let item of otherMetrics">
<code>{{ item }} : {{ 'alert.setting.target.other' | i18n }}</code> <code>{{ item }} : 所属行其它指标对象</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngIf="otherMetrics.length != 0"> <nz-list-item *ngIf="otherMetrics.length != 0">
<code>instance : {{ 'alert.setting.target.instance' | i18n }}</code> <code>instance : 所属行实例</code>
</nz-list-item> </nz-list-item>
<nz-list-item> <nz-list-item>
<code>{{ 'alert.setting.operator' | i18n }} : equals(str1,str2), ==, <, <=, >, >=, !=, ( ), +, -, &&, ||</code> <code>支持操作符函数 : equals(str1,str2), ==, <, <=, >, >=, !=, ( ), +, -, &&, ||</code>
</nz-list-item> </nz-list-item>
</nz-list> </nz-list>
</nz-collapse-panel> </nz-collapse-panel>
@@ -178,8 +160,13 @@
</nz-col> </nz-col>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="expr" nzRequired="true" [nzTooltipTitle]="'alert.setting.expr.label' | i18n"> <nz-form-label
{{ 'alert.setting.expr' | i18n }} [nzSpan]="7"
nzFor="expr"
nzRequired="true"
nzTooltipTitle="根据此表达式来计算判断是否触发阈值,表达式环境变量和操作符见上方"
>
阈值触发表达式
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<nz-textarea-count [nzMaxCharacterCount]="100"> <nz-textarea-count [nzMaxCharacterCount]="100">
@@ -190,27 +177,32 @@
nz-input nz-input
name="expr" name="expr"
id="expr" id="expr"
[placeholder]="('alert.setting.expr.example' | i18n) + ': responseTime&gt;40'" placeholder="根据此表达式计算判断是否触发阈值.&#10;示例: responseTime&gt;40"
> >
</textarea> </textarea>
</nz-textarea-count> </nz-textarea-count>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="priority" [nzTooltipTitle]="'alert.setting.priority.tip' | i18n"> <nz-form-label
{{ 'alert.priority' | i18n }} nzSpan="7"
nzRequired="true"
nzFor="priority"
nzTooltipTitle="触发阈值的告警级别,从低到高依次为:警告-warning严重-critical紧急-emergency"
>
告警级别
</nz-form-label> </nz-form-label>
<nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-select [(ngModel)]="define.priority" nzPlaceHolder="Choose" name="priority" id="priority"> <nz-select [(ngModel)]="define.priority" nzPlaceHolder="Choose" name="priority" id="priority">
<nz-option [nzValue]="0" [nzLabel]="'alert.priority.0' | i18n"></nz-option> <nz-option [nzValue]="0" nzLabel="紧急告警"></nz-option>
<nz-option [nzValue]="1" [nzLabel]="'alert.priority.1' | i18n"></nz-option> <nz-option [nzValue]="1" nzLabel="严重告警"></nz-option>
<nz-option [nzValue]="2" [nzLabel]="'alert.priority.2' | i18n"></nz-option> <nz-option [nzValue]="2" nzLabel="警告告警"></nz-option>
</nz-select> </nz-select>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="duration" [nzTooltipTitle]="'alert.setting.times.tip' | i18n"> <nz-form-label nzSpan="7" nzRequired="true" nzFor="duration" nzTooltipTitle="设置触发阈值多少次之后才会发送告警">
{{ 'alert.setting.times' | i18n }} 触发次数
</nz-form-label> </nz-form-label>
<nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control nzSpan="8" [nzErrorTip]="'validation.required' | i18n">
<nz-input-number [(ngModel)]="define.times" [nzMin]="1" [nzMax]="10" [nzStep]="1" required name="duration" id="duration"> <nz-input-number [(ngModel)]="define.times" [nzMin]="1" [nzMax]="10" [nzStep]="1" required name="duration" id="duration">
@@ -220,25 +212,25 @@
<nz-form-item> <nz-form-item>
<nz-col [nzSpan]="8" nzOffset="7"> <nz-col [nzSpan]="8" nzOffset="7">
<nz-collapse> <nz-collapse>
<nz-collapse-panel [nzActive]="isManageModalAdd" [nzHeader]="'alert.setting.template.tip' | i18n"> <nz-collapse-panel [nzActive]="isManageModalAdd" nzHeader="支持的通知模版环境变量">
<nz-list nzSize="small" nzSplit="false"> <nz-list nzSize="small" nzSplit="false">
<nz-list-item> <nz-list-item>
<code>&#36;&#123;app&#125; : {{ 'alert.setting.template.monitor-type' | i18n }}</code> <code>&#36;&#123;app&#125; : 监控类型名称</code>
</nz-list-item> </nz-list-item>
<nz-list-item> <nz-list-item>
<code>&#36;&#123;metrics&#125; : {{ 'alert.setting.template.metrics-name' | i18n }}</code> <code>&#36;&#123;metrics&#125; : 监控指标集合名称</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngIf="cascadeValues.length == 3"> <nz-list-item *ngIf="cascadeValues.length == 3">
<code>&#36;&#123;metric&#125; : {{ 'alert.setting.template.metric-name' | i18n }}</code> <code>&#36;&#123;metric&#125; : 监控指标名称</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngIf="cascadeValues.length == 3"> <nz-list-item *ngIf="cascadeValues.length == 3">
<code>&#36;{{ '{' + cascadeValues[2] + '}' }} : {{ 'alert.setting.template.metric-value' | i18n }}</code> <code>&#36;{{ '{' + cascadeValues[2] + '}' }} : 监控指标对象值</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngFor="let item of otherMetrics"> <nz-list-item *ngFor="let item of otherMetrics">
<code>&#36;{{ '{' + item + '}' }} : {{ 'alert.setting.template.other-value' | i18n }}</code> <code>&#36;{{ '{' + item + '}' }} : 所属行其它指标值</code>
</nz-list-item> </nz-list-item>
<nz-list-item> <nz-list-item>
<code>&#36;&#123;instance&#125; : {{ 'alert.setting.template.instance-value' | i18n }}</code> <code>&#36;&#123;instance&#125; : 所属行实例值</code>
</nz-list-item> </nz-list-item>
</nz-list> </nz-list>
</nz-collapse-panel> </nz-collapse-panel>
@@ -246,8 +238,8 @@
</nz-col> </nz-col>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="template" nzRequired="true" [nzTooltipTitle]="'alert.setting.template.label' | i18n"> <nz-form-label [nzSpan]="7" nzFor="template" nzRequired="true" nzTooltipTitle="告警触发后发送的通知信息模版,模版环境变量见上方">
{{ 'alert.setting.template' | i18n }} 通知模版
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<nz-textarea-count [nzMaxCharacterCount]="200"> <nz-textarea-count [nzMaxCharacterCount]="200">
@@ -258,24 +250,20 @@
required required
name="template" name="template"
id="template" id="template"
[placeholder]="'alert.setting.template.example' | i18n" placeholder="请输入告警的通知模版.&#10;示例: ${app}.${metrics}.${metric}'s value is too high"
> >
</textarea> </textarea>
</nz-textarea-count> </nz-textarea-count>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="preset" [nzTooltipTitle]="'alert.setting.default.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="preset" nzTooltipTitle="此告警阈值配置是否应用于全局所有此类型监控"> 全局默认 </nz-form-label>
{{ 'alert.setting.default' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="define.preset" name="preset" id="preset"></nz-switch> <nz-switch [(ngModel)]="define.preset" name="preset" id="preset"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor="enable" [nzTooltipTitle]="'alert.setting.enable.tip' | i18n"> <nz-form-label nzSpan="7" nzRequired="true" nzFor="enable" nzTooltipTitle="此告警阈值配置开启生效或关闭"> 启用告警 </nz-form-label>
{{ 'alert.setting.enable' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="define.enable" [ngModelOptions]="{ standalone: true }" name="enable" id="enable"></nz-switch> <nz-switch [(ngModel)]="define.enable" [ngModelOptions]="{ standalone: true }" name="enable" id="enable"></nz-switch>
</nz-form-control> </nz-form-control>
@@ -288,7 +276,7 @@
<nz-modal <nz-modal
[(nzVisible)]="isConnectModalVisible" [(nzVisible)]="isConnectModalVisible"
[nzTitle]="'alert.setting.connect' | i18n" nzTitle="告警定义关联监控"
(nzOnCancel)="onConnectModalCancel()" (nzOnCancel)="onConnectModalCancel()"
(nzOnOk)="onConnectModalOk()" (nzOnOk)="onConnectModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
@@ -315,8 +303,8 @@
<thead> <thead>
<tr> <tr>
<th [nzChecked]="stat.checkAll" [nzIndeterminate]="stat.checkHalf" (nzCheckedChange)="onItemSelectAll($event)"></th> <th [nzChecked]="stat.checkAll" [nzIndeterminate]="stat.checkHalf" (nzCheckedChange)="onItemSelectAll($event)"></th>
<th *ngIf="direction == 'left'">{{ 'alert.setting.connect.left' | i18n }}</th> <th *ngIf="direction == 'left'">未关联监控</th>
<th *ngIf="direction == 'right'">{{ 'alert.setting.connect.right' | i18n }}</th> <th *ngIf="direction == 'right'">已关联监控</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@@ -1,6 +1,4 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { NzTableQueryParams } from 'ng-zorro-antd/table'; import { NzTableQueryParams } from 'ng-zorro-antd/table';
@@ -27,8 +25,7 @@ export class AlertSettingComponent implements OnInit {
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private appDefineSvc: AppDefineService, private appDefineSvc: AppDefineService,
private monitorSvc: MonitorService, private monitorSvc: MonitorService,
private alertDefineSvc: AlertDefineService, private alertDefineSvc: AlertDefineService
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {} ) {}
pageIndex: number = 1; pageIndex: number = 1;
@@ -101,7 +98,7 @@ export class AlertSettingComponent implements OnInit {
onEditOneAlertDefine(alertDefineId: number) { onEditOneAlertDefine(alertDefineId: number) {
if (alertDefineId == null) { if (alertDefineId == null) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-edit'), ''); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
this.editAlertDefine(alertDefineId); this.editAlertDefine(alertDefineId);
@@ -110,11 +107,11 @@ export class AlertSettingComponent implements OnInit {
onEditAlertDefine() { onEditAlertDefine() {
// 编辑时只能选中一个 // 编辑时只能选中一个
if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) { if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-edit'), ''); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
if (this.checkedDefineIds.size > 1) { if (this.checkedDefineIds.size > 1) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.one-select-edit'), ''); this.notifySvc.warning('只能对一个选中项进行编辑!', '');
return; return;
} }
let alertDefineId = 0; let alertDefineId = 0;
@@ -141,24 +138,24 @@ export class AlertSettingComponent implements OnInit {
this.cascadeValues = [this.define.app, this.define.metric, this.define.field]; this.cascadeValues = [this.define.app, this.define.metric, this.define.field];
this.cascadeOnChange(this.cascadeValues); this.cascadeOnChange(this.cascadeValues);
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.monitor-fail'), message.msg); this.notifySvc.error('查询此监控定义详情失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.monitor-fail'), error.msg); this.notifySvc.error('查询此监控定义详情失败!', error.msg);
} }
); );
} }
onDeleteAlertDefines() { onDeleteAlertDefines() {
if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) { if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete-batch'), nzTitle: '请确认是否批量删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteAlertDefines(this.checkedDefineIds) nzOnOk: () => this.deleteAlertDefines(this.checkedDefineIds)
@@ -169,9 +166,9 @@ export class AlertSettingComponent implements OnInit {
let defineIds = new Set<number>(); let defineIds = new Set<number>();
defineIds.add(alertDefineId); defineIds.add(alertDefineId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteAlertDefines(defineIds) nzOnOk: () => this.deleteAlertDefines(defineIds)
@@ -180,7 +177,7 @@ export class AlertSettingComponent implements OnInit {
deleteAlertDefines(defineIds: Set<number>) { deleteAlertDefines(defineIds: Set<number>) {
if (defineIds == null || defineIds.size == 0) { if (defineIds == null || defineIds.size == 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.tableLoading = true; this.tableLoading = true;
@@ -188,17 +185,17 @@ export class AlertSettingComponent implements OnInit {
message => { message => {
deleteDefines$.unsubscribe(); deleteDefines$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
deleteDefines$.unsubscribe(); deleteDefines$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
@@ -245,7 +242,7 @@ export class AlertSettingComponent implements OnInit {
} }
this.appHierarchies.forEach(hierarchy => { this.appHierarchies.forEach(hierarchy => {
if (hierarchy.value == values[0]) { if (hierarchy.value == values[0]) {
hierarchy.children.forEach((metrics: { value: string; children: any[] }) => { hierarchy.children.forEach((metrics: { value: string; children: any[]}) => {
if (metrics.value == values[1]) { if (metrics.value == values[1]) {
this.otherMetrics = []; this.otherMetrics = [];
metrics.children.forEach(item => { metrics.children.forEach(item => {
@@ -279,14 +276,14 @@ export class AlertSettingComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageModalVisible = false; this.isManageModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.new-success'), ''); this.notifySvc.success('新增成功!', '');
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), message.msg); this.notifySvc.error('新增失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), error.msg); this.notifySvc.error('新增失败!', error.msg);
} }
); );
} else { } else {
@@ -302,14 +299,14 @@ export class AlertSettingComponent implements OnInit {
message => { message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageModalVisible = false; this.isManageModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.edit-success'), ''); this.notifySvc.success('修改成功!', '');
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), message.msg); this.notifySvc.error('修改失败!', message.msg);
} }
}, },
error => { error => {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), error.msg); this.notifySvc.error('修改失败!', error.msg);
} }
); );
} }
@@ -376,16 +373,16 @@ export class AlertSettingComponent implements OnInit {
message => { message => {
this.isConnectModalOkLoading = false; this.isConnectModalOkLoading = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.apply-success'), ''); this.notifySvc.success('应用成功!', '');
this.isConnectModalVisible = false; this.isConnectModalVisible = false;
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.apply-fail'), message.msg); this.notifySvc.error('应用失败!', message.msg);
} }
}, },
error => { error => {
this.isConnectModalOkLoading = false; this.isConnectModalOkLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.apply-fail'), error.msg); this.notifySvc.error('应用失败!', error.msg);
} }
); );
} }

View File

@@ -10,19 +10,16 @@
</div> </div>
<div nz-col nzSpan="14" class="p-md text-white"> <div nz-col nzSpan="14" class="p-md text-white">
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.available' | i18n }} </span <span>正常 </span><span style="font-weight: bolder">{{ appCountService.availableSize }}</span>
><span style="font-weight: bolder">{{ appCountService.availableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unavailable' | i18n }} </span <span>不可用 </span><span style="font-weight: bolder">{{ appCountService.unAvailableSize }}</span>
><span style="font-weight: bolder">{{ appCountService.unAvailableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unreachable' | i18n }} </span <span>不可达 </span><span style="font-weight: bolder">{{ appCountService.unReachableSize }}</span>
><span style="font-weight: bolder">{{ appCountService.unReachableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.un-manage' | i18n }} </span><span style="font-weight: bolder">{{ appCountService.unManageSize }}</span> <span>未监控 </span><span style="font-weight: bolder">{{ appCountService.unManageSize }}</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
@@ -38,16 +35,16 @@
</div> </div>
<div nz-col nzSpan="14"> <div nz-col nzSpan="14">
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.available' | i18n }} </span><span style="font-weight: bolder">{{ appCountDb.availableSize }}</span> <span>正常 </span><span style="font-weight: bolder">{{ appCountDb.availableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unavailable' | i18n }} </span><span style="font-weight: bolder">{{ appCountDb.unAvailableSize }}</span> <span>不可用 </span><span style="font-weight: bolder">{{ appCountDb.unAvailableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unreachable' | i18n }} </span><span style="font-weight: bolder">{{ appCountDb.unReachableSize }}</span> <span>不可达 </span><span style="font-weight: bolder">{{ appCountDb.unReachableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.un-manage' | i18n }} </span><span style="font-weight: bolder">{{ appCountDb.unManageSize }}</span> <span>未监控 </span><span style="font-weight: bolder">{{ appCountDb.unManageSize }}</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
@@ -63,16 +60,16 @@
</div> </div>
<div nz-col nzSpan="14"> <div nz-col nzSpan="14">
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.available' | i18n }} </span><span style="font-weight: bolder">{{ appCountOs.availableSize }}</span> <span>正常 </span><span style="font-weight: bolder">{{ appCountOs.availableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unavailable' | i18n }} </span><span style="font-weight: bolder">{{ appCountOs.unAvailableSize }}</span> <span>不可用 </span><span style="font-weight: bolder">{{ appCountOs.unAvailableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unreachable' | i18n }} </span><span style="font-weight: bolder">{{ appCountOs.unReachableSize }}</span> <span>不可达 </span><span style="font-weight: bolder">{{ appCountOs.unReachableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.un-manage' | i18n }} </span><span style="font-weight: bolder">{{ appCountOs.unManageSize }}</span> <span>未监控 </span><span style="font-weight: bolder">{{ appCountOs.unManageSize }}</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
@@ -88,16 +85,16 @@
</div> </div>
<div nz-col nzSpan="14"> <div nz-col nzSpan="14">
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.available' | i18n }} </span><span style="font-weight: bolder">{{ appCountCustom.availableSize }}</span> <span>正常 </span><span style="font-weight: bolder">{{ appCountCustom.availableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unavailable' | i18n }} </span><span style="font-weight: bolder">{{ appCountCustom.unAvailableSize }}</span> <span>不可用 </span><span style="font-weight: bolder">{{ appCountCustom.unAvailableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.unreachable' | i18n }} </span><span style="font-weight: bolder">{{ appCountCustom.unReachableSize }}</span> <span>不可达 </span><span style="font-weight: bolder">{{ appCountCustom.unReachableSize }}</span>
</nz-tag> </nz-tag>
<nz-tag class="mb-xs"> <nz-tag class="mb-xs">
<span>{{ 'monitor.status.un-manage' | i18n }} </span><span style="font-weight: bolder">{{ appCountCustom.unManageSize }}</span> <span>未监控 </span><span style="font-weight: bolder">{{ appCountCustom.unManageSize }}</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
@@ -117,21 +114,21 @@
<div nz-row nzGutter="16" style="margin-top: 10px"> <div nz-row nzGutter="16" style="margin-top: 10px">
<div nz-col nzXs="24" nzSm="24" nzMd="12" class="mb-md"> <div nz-col nzXs="24" nzSm="24" nzMd="12" class="mb-md">
<nz-card nzHoverable [nzTitle]="'dashboard.alerts.title' | i18n" [nzExtra]="extraTemplate"> <nz-card nzHoverable nzTitle="最近告警列表" [nzExtra]="extraTemplate">
<nz-timeline nzMode="left"> <nz-timeline nzMode="left">
<nz-timeline-item *ngFor="let alert of alerts; let i = index" [nzLabel]="(alert.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss')?.trim()"> <nz-timeline-item *ngFor="let alert of alerts; let i = index" [nzLabel]="(alert.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss')?.trim()">
<p style="font-weight: 400"> <p style="font-weight: 400">
<nz-tag *ngIf="alert.priority == 0" nzColor="red"> <nz-tag *ngIf="alert.priority == 0" nzColor="red">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.0' | i18n }}</span> <span>紧急告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="alert.priority == 1" nzColor="orange"> <nz-tag *ngIf="alert.priority == 1" nzColor="orange">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.1' | i18n }}</span> <span>严重告警</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="alert.priority == 2" nzColor="yellow"> <nz-tag *ngIf="alert.priority == 2" nzColor="yellow">
<i nz-icon nzType="bell" nzTheme="outline"></i> <i nz-icon nzType="bell" nzTheme="outline"></i>
<span>{{ 'alert.priority.2' | i18n }}</span> <span>警告告警</span>
</nz-tag> </nz-tag>
<span>[{{ alert.monitorName }}] </span> <span>[{{ alert.monitorName }}] </span>
{{ alert.content }} {{ alert.content }}
@@ -165,5 +162,5 @@
</div> </div>
<ng-template #extraTemplate> <ng-template #extraTemplate>
<a [routerLink]="['/alert/center']">{{ 'dashboard.alerts.enter' | i18n }}</a> <a [routerLink]="['/alert/center']">进入告警中心</a>
</ng-template> </ng-template>

View File

@@ -48,13 +48,13 @@ export class DashboardComponent implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
this.appsCountTheme = { this.appsCountTheme = {
title: { title: {
text: this.i18nSvc.fanyi('dashboard.monitors.title'), text: '监控总览',
subtext: this.i18nSvc.fanyi('dashboard.monitors.sub-title'), subtext: '监控类型纳管数量分布',
left: 'center' left: 'center'
}, },
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
formatter: `{a} <br/>{b} : {c}${this.i18nSvc.fanyi('dashboard.monitors.formatter')}({d}%)` formatter: '{a} <br/>{b} : {c}个监控 占比({d}%)'
}, },
legend: { legend: {
show: false, show: false,
@@ -66,7 +66,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
calculable: true, calculable: true,
series: [ series: [
{ {
name: this.i18nSvc.fanyi('dashboard.monitors.total'), name: '总量',
type: 'pie', type: 'pie',
selectedMode: 'single', selectedMode: 'single',
color: '#722ED1', color: '#722ED1',
@@ -81,10 +81,10 @@ export class DashboardComponent implements OnInit, OnDestroy {
labelLine: { labelLine: {
show: false show: false
}, },
data: [{ value: 0, name: this.i18nSvc.fanyi('dashboard.monitors.total') }] data: [{ value: 0, name: '监控总量' }]
}, },
{ {
name: this.i18nSvc.fanyi('dashboard.monitors.distribute'), name: '纳管数量分布',
type: 'pie', type: 'pie',
radius: ['45%', '65%'], radius: ['45%', '65%'],
labelLine: { labelLine: {
@@ -127,7 +127,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
}; };
this.alertsTheme = { this.alertsTheme = {
title: { title: {
subtext: this.i18nSvc.fanyi('dashboard.alerts.distribute'), subtext: '告警分布',
left: 'center' left: 'center'
}, },
tooltip: { tooltip: {
@@ -138,14 +138,14 @@ export class DashboardComponent implements OnInit, OnDestroy {
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
data: [this.i18nSvc.fanyi('alert.priority.2'), this.i18nSvc.fanyi('alert.priority.1'), this.i18nSvc.fanyi('alert.priority.0')] data: ['警告告警', '严重告警', '紧急告警']
}, },
yAxis: { yAxis: {
type: 'value' type: 'value'
}, },
series: [ series: [
{ {
name: this.i18nSvc.fanyi('dashboard.alerts.num'), name: '告警数量',
type: 'bar', type: 'bar',
data: [ data: [
{ {
@@ -176,7 +176,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
}; };
this.alertsDealTheme = { this.alertsDealTheme = {
title: { title: {
subtext: this.i18nSvc.fanyi('dashboard.alerts.deal'), subtext: '告警处理',
left: 'center' left: 'center'
}, },
tooltip: { tooltip: {
@@ -184,7 +184,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
}, },
series: [ series: [
{ {
name: this.i18nSvc.fanyi('dashboard.alerts.deal-percent'), name: '告警处理率',
type: 'gauge', type: 'gauge',
progress: { progress: {
show: true show: true
@@ -196,7 +196,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
data: [ data: [
{ {
value: 100, value: 100,
name: this.i18nSvc.fanyi('dashboard.alerts.deal-percent') name: '告警处理率'
} }
] ]
} }
@@ -279,7 +279,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
} }
}); });
// @ts-ignore // @ts-ignore
this.appsCountTheme.series[0].data = [{ value: total, name: this.i18nSvc.fanyi('dashboard.monitors.total') }]; this.appsCountTheme.series[0].data = [{ value: total, name: '监控总量' }];
// @ts-ignore // @ts-ignore
this.appsCountTheme.series[1].data = this.appsCountTableData; this.appsCountTheme.series[1].data = this.appsCountTableData;
this.appsCountEChartOption = this.appsCountTheme; this.appsCountEChartOption = this.appsCountTheme;
@@ -397,7 +397,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
this.alertsDealTheme.series[0].data = [ this.alertsDealTheme.series[0].data = [
{ {
value: summary.rate, value: summary.rate,
name: this.i18nSvc.fanyi('dashboard.alerts.deal-percent') name: '告警处理率'
} }
]; ];
this.alertsEChartOption = this.alertsTheme; this.alertsEChartOption = this.alertsTheme;

View File

@@ -1,6 +1,4 @@
import { Component, Inject, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { EChartsOption } from 'echarts'; import { EChartsOption } from 'echarts';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
@@ -34,7 +32,7 @@ export class MonitorDataChartComponent implements OnInit {
echartsInstance!: any; echartsInstance!: any;
// 查询历史数据时间段 默认最近6小时 // 查询历史数据时间段 默认最近6小时
timePeriod: string = '6h'; timePeriod: string = '6h';
constructor(private monitorSvc: MonitorService, @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService) {} constructor(private monitorSvc: MonitorService) {}
ngOnInit(): void { ngOnInit(): void {
this.lineHistoryTheme = { this.lineHistoryTheme = {
@@ -53,8 +51,8 @@ export class MonitorDataChartComponent implements OnInit {
dataZoom: { dataZoom: {
yAxisIndex: 'none', yAxisIndex: 'none',
title: { title: {
zoom: this.i18nSvc.fanyi('monitors.detail.chart.zoom'), zoom: '区域缩放',
back: this.i18nSvc.fanyi('monitors.detail.chart.back') back: '缩放还原'
}, },
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -63,7 +61,7 @@ export class MonitorDataChartComponent implements OnInit {
} }
}, },
saveAsImage: { saveAsImage: {
title: this.i18nSvc.fanyi('monitors.detail.chart.save'), title: '保存图片',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
textPosition: 'left' textPosition: 'left'
@@ -72,7 +70,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod1h: { myPeriod1h: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-1h'), title: '查询近1小时',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -85,7 +83,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod6h: { myPeriod6h: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-6h'), title: '查询近6小时',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -98,7 +96,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod1d: { myPeriod1d: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-1d'), title: '查询近1天',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -111,7 +109,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod1w: { myPeriod1w: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-1w'), title: '查询近1周',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -124,7 +122,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myPeriod4w: { myPeriod4w: {
show: true, show: true,
title: this.i18nSvc.fanyi('monitors.detail.chart.query-1m'), title: '查询近1月',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z', icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -137,7 +135,7 @@ export class MonitorDataChartComponent implements OnInit {
}, },
myRefresh: { myRefresh: {
show: true, show: true,
title: this.i18nSvc.fanyi('common.refresh'), title: '刷新',
icon: 'path://M663.881 339.763l274.021-0.742 0.058-13.271 0.699 0c-0.204-0.48-0.495-0.945-0.699-1.426L938.658 65l-23.776 0.044L914.3 280.41C835.9 151.374 694.321 65 532.342 65c-246.869 0-447 200.132-447 447 0 246.84 200.131 447 447 447 180.343 0 335.657-106.919 406.316-260.75l-33.176 0C836.948 835.027 695.456 929.2 532.342 929.2c-230.048 0-417.2-187.152-417.2-417.2s187.152-417.2 417.2-417.2c158.895 0 297.068 89.487 367.466 220.547l-235.868 0.64L663.881 339.763z', icon: 'path://M663.881 339.763l274.021-0.742 0.058-13.271 0.699 0c-0.204-0.48-0.495-0.945-0.699-1.426L938.658 65l-23.776 0.044L914.3 280.41C835.9 151.374 694.321 65 532.342 65c-246.869 0-447 200.132-447 447 0 246.84 200.131 447 447 447 180.343 0 335.657-106.919 406.316-260.75l-33.176 0C836.948 835.027 695.456 929.2 532.342 929.2c-230.048 0-417.2-187.152-417.2-417.2s187.152-417.2 417.2-417.2c158.895 0 297.068 89.487 367.466 220.547l-235.868 0.64L663.881 339.763z',
emphasis: { emphasis: {
iconStyle: { iconStyle: {
@@ -185,7 +183,7 @@ export class MonitorDataChartComponent implements OnInit {
}; };
if (this.unit != undefined || this.unit != null) { if (this.unit != undefined || this.unit != null) {
// @ts-ignore // @ts-ignore
this.lineHistoryTheme.title?.subtext = `${this.i18nSvc.fanyi('monitors.detail.chart.unit')} ${this.unit}`; this.lineHistoryTheme.title?.subtext = `单位 ${this.unit}`;
} }
this.loadData(); this.loadData();
} }
@@ -253,7 +251,7 @@ export class MonitorDataChartComponent implements OnInit {
} else { } else {
this.eChartOption = this.lineHistoryTheme; this.eChartOption = this.lineHistoryTheme;
this.eChartOption.title = { this.eChartOption.title = {
text: `${`${this.metrics}.${this.metric}` + '\n\n\n'}${this.i18nSvc.fanyi('monitors.detail.chart.no-data')}`, text: `${this.metrics}.${this.metric}` + '\n\n\n' + '暂无数据',
textStyle: { textStyle: {
fontSize: 16, fontSize: 16,
fontFamily: 'monospace', fontFamily: 'monospace',

View File

@@ -17,8 +17,8 @@
<nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows"> <nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows">
<thead> <thead>
<tr> <tr>
<th style="text-align: center">{{ 'common.name' | i18n }}</th> <th style="text-align: center">属性</th>
<th style="text-align: center">{{ 'common.value' | i18n }}</th> <th style="text-align: center"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -33,11 +33,17 @@
<ng-template #monitor_metrics_card_title> <ng-template #monitor_metrics_card_title>
<p style="font-size: small; text-align: center; margin-bottom: 3px">{{ metrics }}</p> <p style="font-size: small; text-align: center; margin-bottom: 3px">{{ metrics }}</p>
<div> <div>
<a nz-popover [nzPopoverContent]="'Last Collect Time ' + (time | _date: 'yyyy-MM-dd HH:mm:ss')"> <a nz-popover [nzPopoverContent]="'最近采集时间 ' + (time | _date: 'yyyy-MM-dd HH:mm:ss')">
<i nz-icon nzType="field-time" nzTheme="outline"></i <i nz-icon nzType="field-time" nzTheme="outline"></i
></a> ></a>
<i style="font-size: 0.3px; font-weight: normal; color: rgba(112, 112, 112, 0.89)"> <i style="font-size: 0.3px; font-weight: normal; color: rgba(112,112,112,0.89)">采集时间:{{ time | _date: 'HH:mm:ss' }}</i>
{{ 'monitors.collect.time' | i18n }}:{{ time | _date: 'HH:mm:ss' }}
</i>
</div> </div>
</ng-template> </ng-template>
<!--<nz-card *ngIf="!isTable" nzHoverable style="height:auto;margin-left: 14px;" [nzBordered]="true"-->
<!-- [nzTitle]="monitor_metrics_card_title" >-->
<!-- <div *ngFor="let field of fields;let i = index;" nz-row nzGutter="16">-->
<!-- <div nz-col nzSpan="10"><p style="text-align: right">{{field.name}}</p></div>-->
<!-- <div nz-col nzSpan="14"><p style="text-align: left">{{rowValues[i].origin}}</p></div>-->
<!-- </div>-->
<!--</nz-card>-->

View File

@@ -3,20 +3,20 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/monitors']" [queryParams]="{ app: app ? app : '' }"> <a [routerLink]="['/monitors']" [queryParams]="{ app: app ? app : '' }">
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>{{ 'monitors.list' | i18n }}</span> <span>监控列表</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="pie-chart"></i> <i nz-icon nzType="pie-chart"></i>
<span>{{ 'monitor.app.' + app | i18n }} {{ 'monitors.detail' | i18n }}</span> <span>{{ 'monitor.app.' + app | i18n }} 监控详情</span>
<a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%"> <a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }} </span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -33,9 +33,7 @@
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">名称</p></div>
><p style="text-align: right">{{ 'monitors.detail.name' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.name }}</p></div ><p style="text-align: left">{{ monitor?.name }}</p></div
> >
@@ -47,64 +45,56 @@
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">端口</p></div>
><p style="text-align: right">{{ 'monitors.detail.port' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ port }}</p></div ><p style="text-align: left">{{ port }}</p></div
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">描述</p></div>
><p style="text-align: right">{{ 'monitors.detail.description' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.description }}</p></div ><p style="text-align: left">{{ monitor?.description }}</p></div
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">状态</p></div>
><p style="text-align: right">{{ 'monitors.detail.status' | i18n }}</p></div
>
<div nz-col nzSpan="16"> <div nz-col nzSpan="16">
<nz-tag *ngIf="monitor?.status == 0" nzColor="default"> <nz-tag *ngIf="monitor?.status == 0" nzColor="default">
<i nz-icon nzType="robot" nzTheme="outline"></i> <i nz-icon nzType="robot" nzTheme="outline"></i>
<span>{{ 'monitor.status.un-manage' | i18n }}</span> <span>未监控</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="monitor?.status == 1" nzColor="success"> <nz-tag *ngIf="monitor?.status == 1" nzColor="success">
<i nz-icon nzType="smile" nzTheme="outline"></i> <i nz-icon nzType="smile" nzTheme="outline"></i>
<span>{{ 'monitor.status.available' | i18n }}</span> <span>正常监控</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="monitor?.status == 2" nzColor="warning"> <nz-tag *ngIf="monitor?.status == 2" nzColor="warning">
<i nz-icon nzType="meh" nzTheme="outline"></i> <i nz-icon nzType="meh" nzTheme="outline"></i>
<span>{{ 'monitor.status.unavailable' | i18n }}</span> <span>监控不可用</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="monitor?.status == 3" nzColor="error"> <nz-tag *ngIf="monitor?.status == 3" nzColor="error">
<i nz-icon nzType="frown" nzTheme="outline"></i> <i nz-icon nzType="frown" nzTheme="outline"></i>
<span>{{ 'monitor.status.unreachable' | i18n }}</span> <span>监控不可达</span>
</nz-tag>
<nz-tag *ngIf="monitor?.status == 4" nzColor="default">
<i nz-icon nzType="sync"></i>
<span>监控已挂起</span>
</nz-tag> </nz-tag>
</div> </div>
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">采集间隔</p></div>
><p style="text-align: right">{{ 'monitor.intervals' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.intervals }}s</p></div ><p style="text-align: left">{{ monitor?.intervals }}s</p></div
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">创建时间</p></div>
><p style="text-align: right">{{ 'common.new-time' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss' }}</p></div ><p style="text-align: left">{{ monitor?.gmtCreate | date: 'YYYY-MM-dd HH:mm:ss' }}</p></div
> >
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8" <div nz-col nzSpan="8"><p style="text-align: right">更新时间</p></div>
><p style="text-align: right">{{ 'common.edit-time' | i18n }}</p></div
>
<div nz-col nzSpan="16" <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.gmtUpdate | date: 'YYYY-MM-dd HH:mm:ss' }}</p></div ><p style="text-align: left">{{ monitor?.gmtUpdate | date: 'YYYY-MM-dd HH:mm:ss' }}</p></div
> >
@@ -117,7 +107,7 @@
<nz-tab [nzTitle]="titleTemplate"> <nz-tab [nzTitle]="titleTemplate">
<ng-template #titleTemplate> <ng-template #titleTemplate>
<i nz-icon nzType="pic-right" style="margin-left: 10px"></i> <i nz-icon nzType="pic-right" style="margin-left: 10px"></i>
{{ 'monitors.detail.realtime' | i18n }} 监控实时数据详情
</ng-template> </ng-template>
<div style="display: flex; justify-content: flex-start; flex-wrap: wrap"> <div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
<div *ngFor="let metric of metrics; let i = index"> <div *ngFor="let metric of metrics; let i = index">
@@ -128,7 +118,7 @@
<nz-tab [nzTitle]="title2Template" (nzClick)="initMetricChart()"> <nz-tab [nzTitle]="title2Template" (nzClick)="initMetricChart()">
<ng-template #title2Template> <ng-template #title2Template>
<i nz-icon nzType="pic-right" style="margin-left: 10px"></i> <i nz-icon nzType="pic-right" style="margin-left: 10px"></i>
{{ 'monitors.detail.history' | i18n }} 监控历史图表详情
</ng-template> </ng-template>
<div style="display: flex; justify-content: flex-start; flex-wrap: wrap"> <div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
<div *ngFor="let item of chartMetrics; let i = index"> <div *ngFor="let item of chartMetrics; let i = index">
@@ -148,5 +138,5 @@
</nz-layout> </nz-layout>
<ng-template #monitor_basic_card_title> <ng-template #monitor_basic_card_title>
<p style="font-size: small; text-align: left; margin-bottom: 3px">{{ 'monitors.detail.basic' | i18n }}</p> <p style="font-size: small; text-align: left; margin-bottom: 3px">监控基本属性</p>
</ng-template> </ng-template>

View File

@@ -3,20 +3,20 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }"> <a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }">
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>{{ 'monitors.list' | i18n }}</span> <span>监控列表</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="edit"></i> <i nz-icon nzType="edit"></i>
<span>{{ 'monitors.edit' | i18n }} {{ 'monitor.app.' + monitor.app | i18n }} {{ 'monitor' | i18n }}</span> <span>修改 {{ 'monitor.app.' + monitor.app | i18n }} 监控</span>
<a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%"> <a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }} </span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -27,19 +27,17 @@
<div class="-inner-content"> <div class="-inner-content">
<form nz-form #editForm="ngForm"> <form nz-form #editForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" [nzTooltipTitle]="'monitor.host.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" nzTooltipTitle="被监控的对端IP或域名"> 监控Host </nz-form-label>
{{ 'monitor.host' | i18n }}
</nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="monitor.host" nz-input name="host" type="text" id="host" required [placeholder]="'monitor.host.tip' | i18n" /> <input [(ngModel)]="monitor.host" nz-input name="host" type="text" id="host" required placeholder="请输入域名或IP" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" [nzTooltipTitle]="'monitor.name.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" nzTooltipTitle="标识此监控的名称,名称需要保证唯一性">
{{ 'monitor.name' | i18n }} 监控名称
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="monitor.name" nz-input required name="name" type="text" id="name" [placeholder]="'monitor.name.tip' | i18n" /> <input [(ngModel)]="monitor.name" nz-input required name="name" type="text" id="name" placeholder="监控名称需要保证唯一性" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
@@ -165,7 +163,7 @@
</nz-form-item> </nz-form-item>
<nz-collapse [nzGhost]="true"> <nz-collapse [nzGhost]="true">
<nz-collapse-panel [nzHeader]="extraColHeader" [nzShowArrow]="false"> <nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index"> <nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
<nz-form-label <nz-form-label
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'" *ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
@@ -298,8 +296,8 @@
</nz-collapse-panel> </nz-collapse-panel>
</nz-collapse> </nz-collapse>
<ng-template #extraColHeader> <ng-template #extraColHeader>
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip [nzTooltipTitle]="'monitors.advanced.tip' | i18n"> <button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
<span>{{ 'monitors.advanced' | i18n }}</span> <span>高级设置</span>
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button> </button>
</ng-template> </ng-template>
@@ -307,9 +305,7 @@
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="intervals" [nzTooltipTitle]="'monitor.intervals.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
{{ 'monitor.intervals' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="604800" [nzStep]="60" name="intervals" id="intervals"> <nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="604800" [nzStep]="60" name="intervals" id="intervals">
</nz-input-number> </nz-input-number>
@@ -317,18 +313,14 @@
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="detect" [nzTooltipTitle]="'monitors.detect.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="detect" nzTooltipTitle="新增监控前是否先探测检查监控可用性"> 测试连接 </nz-form-label>
{{ 'monitors.detect' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch> <nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="description" [nzTooltipTitle]="'monitor.description.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="description" nzTooltipTitle="更多标识和描述此监控的备注信息"> 描述备注 </nz-form-label>
{{ 'monitor.description' | i18n }}
</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<nz-textarea-count [nzMaxCharacterCount]="100"> <nz-textarea-count [nzMaxCharacterCount]="100">
<textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea> <textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea>
@@ -338,9 +330,9 @@
<div nz-row> <div nz-row>
<div nz-col nzSpan="8" nzOffset="9"> <div nz-col nzSpan="8" nzOffset="9">
<button nz-button nzType="primary" type="submit" (click)="onDetect(editForm.form)"> {{ 'common.button.detect' | i18n }} </button> <button nz-button nzType="primary" type="submit" (click)="onDetect(editForm.form)"> 测试 </button>
<button nz-button nzType="primary" type="submit" (click)="onSubmit(editForm.form)"> {{ 'common.button.ok' | i18n }} </button> <button nz-button nzType="primary" type="submit" (click)="onSubmit(editForm.form)"> 确定 </button>
<button nz-button nzType="primary" type="reset" (click)="onCancel()"> {{ 'common.button.cancel' | i18n }} </button> <button nz-button nzType="primary" type="reset" (click)="onCancel()"> 取消 </button>
</div> </div>
</div> </div>
</form> </form>

View File

@@ -1,8 +1,7 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { ActivatedRoute, ParamMap, Router } from '@angular/router'; import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { I18NService } from '@core'; import { TitleService } from '@delon/theme';
import { ALAIN_I18N_TOKEN, TitleService } from '@delon/theme';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { throwError } from 'rxjs'; import { throwError } from 'rxjs';
import { switchMap } from 'rxjs/operators'; import { switchMap } from 'rxjs/operators';
@@ -26,8 +25,7 @@ export class MonitorEditComponent implements OnInit {
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private titleSvc: TitleService, private titleSvc: TitleService,
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {} ) {}
paramDefines!: ParamDefine[]; paramDefines!: ParamDefine[];
@@ -66,8 +64,8 @@ export class MonitorEditComponent implements OnInit {
this.detected = message.data.detected ? message.data.detected : true; this.detected = message.data.detected ? message.data.detected : true;
} else { } else {
console.warn(message.msg); console.warn(message.msg);
this.notifySvc.error(this.i18nSvc.fanyi('monitors.not-found'), message.msg); this.notifySvc.error('查询异常,此监控不存在', message.msg);
return throwError(this.i18nSvc.fanyi('monitors.not-found')); return throwError('查询此监控异常');
} }
return this.appDefineSvc.getAppParamsDefine(this.monitor.app); return this.appDefineSvc.getAppParamsDefine(this.monitor.app);
}) })
@@ -170,15 +168,15 @@ export class MonitorEditComponent implements OnInit {
message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('monitors.edit.success'), ''); this.notifySvc.success('修改监控成功', '');
this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`); this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`);
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('monitors.edit.failed'), message.msg); this.notifySvc.error('修改监控失败', message.msg);
} }
}, },
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error(this.i18nSvc.fanyi('monitors.edit.failed'), error.error.msg); this.notifySvc.error('修改监控失败', error.error.msg);
} }
); );
} }
@@ -219,14 +217,14 @@ export class MonitorEditComponent implements OnInit {
message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('monitors.detect.success'), ''); this.notifySvc.success('探测成功', '');
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('monitors.detect.failed'), message.msg); this.notifySvc.error('探测失败', message.msg);
} }
}, },
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error(this.i18nSvc.fanyi('monitors.detect.failed'), error.error.msg); this.notifySvc.error('探测异常', error.error.msg);
} }
); );
} }

View File

@@ -3,12 +3,12 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>{{ 'monitor.app.' + app | i18n }} {{ 'monitors.list' | i18n }}</span> <span>{{ 'monitor.app.' + app | i18n }} 监控列表</span>
</nz-breadcrumb-item> </nz-breadcrumb-item>
</nz-breadcrumb> </nz-breadcrumb>
<nz-divider></nz-divider> <nz-divider></nz-divider>
@@ -17,37 +17,35 @@
<button nz-button nzType="primary"> <button nz-button nzType="primary">
<a routerLink="/monitors/new" [queryParams]="{ app: app }"> <a routerLink="/monitors/new" [queryParams]="{ app: app }">
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
{{ 'monitors.new' | i18n }} {{ 'monitor.app.' + app | i18n }} 新增 {{ 'monitor.app.' + app | i18n }}
</a> </a>
</button> </button>
<button nz-button nzType="primary" (click)="onEditMonitor()"> <button nz-button nzType="primary" (click)="onEditMonitor()">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
{{ 'monitors.edit' | i18n }} 编辑
</button> </button>
<button nz-button nzType="primary" (click)="onDeleteMonitors()"> <button nz-button nzType="primary" (click)="onDeleteMonitors()">
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
{{ 'monitors.delete' | i18n }} 删除
</button> </button>
<button nz-button nzType="primary" (click)="onEnableManageMonitors()"> <button nz-button nzType="primary" (click)="onEnableManageMonitors()">
<i nz-icon nzType="up-circle" nzTheme="outline"></i> <i nz-icon nzType="up-circle" nzTheme="outline"></i>
{{ 'monitors.enable' | i18n }} 启用监控
</button> </button>
<button nz-button nzType="primary" (click)="onCancelManageMonitors()"> <button nz-button nzType="primary" (click)="onCancelManageMonitors()">
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
{{ 'monitors.cancel' | i18n }} 取消监控
</button> </button>
<button nz-button nzType="primary" (click)="sync()" nz-tooltip [nzTooltipTitle]="'common.refresh' | i18n"> <button nz-button nzType="primary" (click)="sync()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchMonitors()"> <button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchMonitors()"> 搜索 </button>
{{ 'common.search' | i18n }}
</button>
<input <input
style="margin-right: 5px; float: right; width: 150px; border-radius: 9px; text-align: center" style="margin-right: 5px; float: right; width: 150px; border-radius: 9px; text-align: center"
nz-input nz-input
type="text" type="text"
[placeholder]="'monitors.search.placeholder' | i18n" placeholder="搜索监控"
nzSize="default" nzSize="default"
(keyup.enter)="onFilterSearchMonitors()" (keyup.enter)="onFilterSearchMonitors()"
[(ngModel)]="filterContent" [(ngModel)]="filterContent"
@@ -55,14 +53,14 @@
<nz-select <nz-select
style="margin-right: 10px; float: right; width: 120px" style="margin-right: 10px; float: right; width: 120px"
nzAllowClear nzAllowClear
[nzPlaceHolder]="'monitors.search.filter' | i18n" [nzPlaceHolder]="'监控状态过滤'"
[(ngModel)]="filterStatus" [(ngModel)]="filterStatus"
> >
<nz-option [nzLabel]="'monitor.status.all' | i18n" nzValue="9"></nz-option> <nz-option nzLabel="全部状态" nzValue="9"></nz-option>
<nz-option [nzLabel]="'monitor.status.available' | i18n" nzValue="1"></nz-option> <nz-option nzLabel="监控正常" nzValue="1"></nz-option>
<nz-option [nzLabel]="'monitor.status.unavailable' | i18n" nzValue="2"></nz-option> <nz-option nzLabel="不可用" nzValue="2"></nz-option>
<nz-option [nzLabel]="'monitor.status.unreachable' | i18n" nzValue="3"></nz-option> <nz-option nzLabel="不可达" nzValue="3"></nz-option>
<nz-option [nzLabel]="'monitor.status.un-manage' | i18n" nzValue="0"></nz-option> <nz-option nzLabel="未监控" nzValue="0"></nz-option>
</nz-select> </nz-select>
</div> </div>
@@ -84,12 +82,12 @@
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th> <th nzAlign="center" nzLeft nzWidth="4%" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th>
<th nzAlign="center" nzLeft>{{ 'monitor.name' | i18n }}</th> <th nzAlign="center" nzLeft>监控名称</th>
<th nzAlign="center">{{ 'monitor.status' | i18n }}</th> <th nzAlign="center">监控状态</th>
<th nzAlign="center">{{ 'monitor.host' | i18n }}</th> <th nzAlign="center">监控Host</th>
<th nzAlign="center">{{ 'monitor.app' | i18n }}</th> <th nzAlign="center">监控类型</th>
<th nzAlign="center">{{ 'common.edit-time' | i18n }}</th> <th nzAlign="center">最新修改时间</th>
<th nzAlign="center">{{ 'common.edit' | i18n }}</th> <th nzAlign="center">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -103,19 +101,23 @@
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.status == 0" nzColor="default"> <nz-tag *ngIf="data.status == 0" nzColor="default">
<i nz-icon nzType="robot" nzTheme="outline"></i> <i nz-icon nzType="robot" nzTheme="outline"></i>
<span>{{ 'monitor.status.un-manage' | i18n }}</span> <span>未监控</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.status == 1" nzColor="success"> <nz-tag *ngIf="data.status == 1" nzColor="success">
<i nz-icon nzType="smile" nzTheme="outline"></i> <i nz-icon nzType="smile" nzTheme="outline"></i>
<span>{{ 'monitor.status.available' | i18n }}</span> <span>正常监控</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.status == 2" nzColor="warning"> <nz-tag *ngIf="data.status == 2" nzColor="warning">
<i nz-icon nzType="meh" nzTheme="outline"></i> <i nz-icon nzType="meh" nzTheme="outline"></i>
<span>{{ 'monitor.status.unavailable' | i18n }}</span> <span>监控不可用</span>
</nz-tag> </nz-tag>
<nz-tag *ngIf="data.status == 3" nzColor="error"> <nz-tag *ngIf="data.status == 3" nzColor="error">
<i nz-icon nzType="frown" nzTheme="outline"></i> <i nz-icon nzType="frown" nzTheme="outline"></i>
<span>{{ 'monitor.status.unreachable' | i18n }}</span> <span>监控不可达</span>
</nz-tag>
<nz-tag *ngIf="data.status == 4" nzColor="default">
<i nz-icon nzType="sync"></i>
<span>监控已挂起</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ data.host }}</td> <td nzAlign="center">{{ data.host }}</td>
@@ -127,34 +129,16 @@
</td> </td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td> <td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date: 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center"> <td nzAlign="center">
<button nz-button nzType="primary" (click)="onEditOneMonitor(data.id)" nz-tooltip [nzTooltipTitle]="'monitors.edit-monitor' | i18n"> <button nz-button nzType="primary" (click)="onEditOneMonitor(data.id)" nz-tooltip nzTooltipTitle="修改监控">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onDeleteOneMonitor(data.id)" nz-tooltip nzTooltipTitle="删除监控">
nz-button
nzType="primary"
(click)="onDeleteOneMonitor(data.id)"
nz-tooltip
[nzTooltipTitle]="'monitors.delete-monitor' | i18n"
>
<i nz-icon nzType="delete" nzTheme="outline"></i> <i nz-icon nzType="delete" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onEnableManageOneMonitor(data.id)" nz-tooltip nzTooltipTitle="启用监控">
nz-button
nzType="primary"
(click)="onEnableManageOneMonitor(data.id)"
nz-tooltip
[nzTooltipTitle]="'monitors.enable' | i18n"
>
<i nz-icon nzType="up-circle" nzTheme="outline"></i> <i nz-icon nzType="up-circle" nzTheme="outline"></i>
</button> </button>
<button <button nz-button nzType="primary" (click)="onCancelManageOneMonitor(data.id)" nz-tooltip nzTooltipTitle="取消监控">
nz-button
nzType="primary"
(click)="onCancelManageOneMonitor(data.id)"
nz-tooltip
[nzTooltipTitle]="'monitors.cancel' | i18n"
>
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button> </button>
</td> </td>
@@ -162,4 +146,4 @@
</tbody> </tbody>
</nz-table> </nz-table>
<ng-template #rangeTemplate> {{ 'common.total' | i18n }} {{ total }} </ng-template> <ng-template #rangeTemplate> 总量 {{ total }} </ng-template>

View File

@@ -1,7 +1,5 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzMessageService } from 'ng-zorro-antd/message'; import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalService } from 'ng-zorro-antd/modal'; import { NzModalService } from 'ng-zorro-antd/modal';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
@@ -22,8 +20,7 @@ export class MonitorListComponent implements OnInit {
private modal: NzModalService, private modal: NzModalService,
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private msg: NzMessageService, private msg: NzMessageService,
private monitorSvc: MonitorService, private monitorSvc: MonitorService
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
) {} ) {}
app!: string; app!: string;
@@ -105,7 +102,7 @@ export class MonitorListComponent implements OnInit {
onEditOneMonitor(monitorId: number) { onEditOneMonitor(monitorId: number) {
if (monitorId == null) { if (monitorId == null) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-edit'), ''); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
this.router.navigateByUrl(`/monitors/${monitorId}/edit`); this.router.navigateByUrl(`/monitors/${monitorId}/edit`);
@@ -116,11 +113,11 @@ export class MonitorListComponent implements OnInit {
onEditMonitor() { onEditMonitor() {
// 编辑时只能选中一个监控 // 编辑时只能选中一个监控
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-edit'), ''); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
if (this.checkedMonitorIds.size > 1) { if (this.checkedMonitorIds.size > 1) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.one-select-edit'), ''); this.notifySvc.warning('只能对一个选中项进行编辑!', '');
return; return;
} }
let monitorId = 0; let monitorId = 0;
@@ -132,9 +129,9 @@ export class MonitorListComponent implements OnInit {
let monitors = new Set<number>(); let monitors = new Set<number>();
monitors.add(monitorId); monitors.add(monitorId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), nzTitle: '请确认是否删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteMonitors(monitors) nzOnOk: () => this.deleteMonitors(monitors)
@@ -143,13 +140,13 @@ export class MonitorListComponent implements OnInit {
onDeleteMonitors() { onDeleteMonitors() {
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.delete-batch'), nzTitle: '请确认是否批量删除!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.deleteMonitors(this.checkedMonitorIds) nzOnOk: () => this.deleteMonitors(this.checkedMonitorIds)
@@ -158,7 +155,7 @@ export class MonitorListComponent implements OnInit {
deleteMonitors(monitors: Set<number>) { deleteMonitors(monitors: Set<number>) {
if (monitors == null || monitors.size == 0) { if (monitors == null || monitors.size == 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-delete'), ''); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.tableLoading = true; this.tableLoading = true;
@@ -166,30 +163,30 @@ export class MonitorListComponent implements OnInit {
message => { message => {
deleteMonitors$.unsubscribe(); deleteMonitors$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); this.notifySvc.success('删除成功!', '');
this.loadMonitorTable(); this.loadMonitorTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
deleteMonitors$.unsubscribe(); deleteMonitors$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
onCancelManageMonitors() { onCancelManageMonitors() {
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-cancel'), ''); this.notifySvc.warning('未选中任何待取消项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.cancel-batch'), nzTitle: '请确认是否批量取消监控!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.cancelManageMonitors(this.checkedMonitorIds) nzOnOk: () => this.cancelManageMonitors(this.checkedMonitorIds)
@@ -200,9 +197,9 @@ export class MonitorListComponent implements OnInit {
let monitors = new Set<number>(); let monitors = new Set<number>();
monitors.add(monitorId); monitors.add(monitorId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.cancel'), nzTitle: '请确认是否取消监控!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.cancelManageMonitors(monitors) nzOnOk: () => this.cancelManageMonitors(monitors)
@@ -215,30 +212,30 @@ export class MonitorListComponent implements OnInit {
message => { message => {
cancelManage$.unsubscribe(); cancelManage$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.cancel-success'), ''); this.notifySvc.success('取消监控成功!', '');
this.loadMonitorTable(); this.loadMonitorTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.cancel-fail'), message.msg); this.notifySvc.error('取消监控失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
cancelManage$.unsubscribe(); cancelManage$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.cancel-fail'), error.msg); this.notifySvc.error('取消监控失败!', error.msg);
} }
); );
} }
onEnableManageMonitors() { onEnableManageMonitors() {
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-enable'), ''); this.notifySvc.warning('未选中任何待启用监控项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.enable-batch'), nzTitle: '请确认是否批量启用监控!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.enableManageMonitors(this.checkedMonitorIds) nzOnOk: () => this.enableManageMonitors(this.checkedMonitorIds)
@@ -249,9 +246,9 @@ export class MonitorListComponent implements OnInit {
let monitors = new Set<number>(); let monitors = new Set<number>();
monitors.add(monitorId); monitors.add(monitorId);
this.modal.confirm({ this.modal.confirm({
nzTitle: this.i18nSvc.fanyi('common.confirm.enable'), nzTitle: '请确认是否启用监控!',
nzOkText: this.i18nSvc.fanyi('common.button.ok'), nzOkText: '确定',
nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: 'primary', nzOkType: 'primary',
nzOnOk: () => this.enableManageMonitors(monitors) nzOnOk: () => this.enableManageMonitors(monitors)
@@ -264,17 +261,17 @@ export class MonitorListComponent implements OnInit {
message => { message => {
enableManage$.unsubscribe(); enableManage$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.enable-success'), ''); this.notifySvc.success('启用监控成功!', '');
this.loadMonitorTable(); this.loadMonitorTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.enable-fail'), message.msg); this.notifySvc.error('启用监控失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
enableManage$.unsubscribe(); enableManage$.unsubscribe();
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.enable-fail'), error.msg); this.notifySvc.error('启用监控失败!', error.msg);
} }
); );
} }

View File

@@ -3,20 +3,20 @@
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/']"> <a [routerLink]="['/']">
<i nz-icon nzType="home"></i> <i nz-icon nzType="home"></i>
<span>{{ 'menu.dashboard' | i18n }}</span> <span>仪表盘</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }"> <a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }">
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>{{ 'monitors.list' | i18n }}</span> <span>监控列表</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="plus-circle"></i> <i nz-icon nzType="plus-circle"></i>
<span>{{ 'monitors.new' | i18n }} {{ 'monitor.app.' + monitor.app | i18n }} {{ 'monitor' | i18n }}</span> <span>新增 {{ 'monitor.app.' + monitor.app | i18n }} 监控</span>
<a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%"> <a [href]="'https://tancloud.cn/docs/help/' + monitor.app" target="_blank" style="float: right; margin-right: 5%">
<span>{{ 'common.button.help' | i18n }} </span> <span>帮助&nbsp;</span>
<i nz-icon nzType="question-circle" nzTheme="outline"></i> <i nz-icon nzType="question-circle" nzTheme="outline"></i>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
@@ -27,9 +27,7 @@
<div class="-inner-content"> <div class="-inner-content">
<form nz-form #newForm="ngForm"> <form nz-form #newForm="ngForm">
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" [nzTooltipTitle]="'monitor.host.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" nzTooltipTitle="被监控的对端IP或域名"> 监控Host </nz-form-label>
{{ 'monitor.host' | i18n }}
</nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input <input
[(ngModel)]="monitor.host" [(ngModel)]="monitor.host"
@@ -38,17 +36,17 @@
type="text" type="text"
id="host" id="host"
required required
[placeholder]="'monitor.host.tip' | i18n" placeholder="请输入域名或IP"
(ngModelChange)="onHostChange($event)" (ngModelChange)="onHostChange($event)"
/> />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" [nzTooltipTitle]="'monitor.name.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" nzTooltipTitle="标识此监控的名称,名称需要保证唯一性">
{{ 'monitor.name' | i18n }} 监控名称
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n"> <nz-form-control [nzSpan]="8" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="monitor.name" nz-input required name="name" type="text" id="name" [placeholder]="'monitor.name.tip' | i18n" /> <input [(ngModel)]="monitor.name" nz-input required name="name" type="text" id="name" placeholder="监控名称需要保证唯一性" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
@@ -174,7 +172,7 @@
</nz-form-item> </nz-form-item>
<nz-collapse [nzGhost]="true"> <nz-collapse [nzGhost]="true">
<nz-collapse-panel [nzHeader]="extraColHeader" [nzShowArrow]="false"> <nz-collapse-panel nzHeader="高级" [nzHeader]="extraColHeader" [nzShowArrow]="false">
<nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index"> <nz-form-item *ngFor="let paramDefine of advancedParamDefines; let i = index">
<nz-form-label <nz-form-label
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'" *ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
@@ -307,8 +305,8 @@
</nz-collapse-panel> </nz-collapse-panel>
</nz-collapse> </nz-collapse>
<ng-template #extraColHeader> <ng-template #extraColHeader>
<button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip [nzTooltipTitle]="'monitors.advanced.tip' | i18n"> <button style="top: -10px; margin-left: 40%" nz-button nzType="dashed" nz-tooltip nzTooltipTitle="设置高级可选参数">
<span>{{ 'monitors.advanced' | i18n }}</span> <span>高级设置</span>
<i nz-icon nzType="down-circle" nzTheme="outline"></i> <i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button> </button>
</ng-template> </ng-template>
@@ -316,9 +314,7 @@
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="intervals" [nzTooltipTitle]="'monitor.intervals.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
{{ 'monitor.intervals' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="604800" [nzStep]="60" name="intervals" id="intervals"> <nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="604800" [nzStep]="60" name="intervals" id="intervals">
</nz-input-number> </nz-input-number>
@@ -326,18 +322,14 @@
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor="detect" [nzTooltipTitle]="'monitors.detect.tip' | i18n"> <nz-form-label nzSpan="7" nzFor="detect" nzTooltipTitle="新增监控前是否先探测检查监控可用性"> 测试连接 </nz-form-label>
{{ 'monitors.detect' | i18n }}
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch> <nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="description" [nzTooltipTitle]="'monitor.description.tip' | i18n"> <nz-form-label [nzSpan]="7" nzFor="description" nzTooltipTitle="更多标识和描述此监控的备注信息"> 描述备注 </nz-form-label>
{{ 'monitor.description' | i18n }}
</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<nz-textarea-count [nzMaxCharacterCount]="100"> <nz-textarea-count [nzMaxCharacterCount]="100">
<textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea> <textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea>
@@ -347,9 +339,9 @@
<div nz-row> <div nz-row>
<div nz-col nzSpan="8" nzOffset="9"> <div nz-col nzSpan="8" nzOffset="9">
<button nz-button nzType="primary" type="submit" (click)="onDetect(newForm.form)"> {{ 'common.button.detect' | i18n }} </button> <button nz-button nzType="primary" type="submit" (click)="onDetect(newForm.form)"> 测试 </button>
<button nz-button nzType="primary" type="submit" (click)="onSubmit(newForm.form)"> {{ 'common.button.ok' | i18n }} </button> <button nz-button nzType="primary" type="submit" (click)="onSubmit(newForm.form)"> 确定 </button>
<button nz-button nzType="primary" type="reset" (click)="onCancel()"> {{ 'common.button.cancel' | i18n }} </button> <button nz-button nzType="primary" type="reset" (click)="onCancel()"> 取消 </button>
</div> </div>
</div> </div>
</form> </form>

View File

@@ -1,8 +1,8 @@
import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core'; import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute, ParamMap, Router } from '@angular/router'; import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { I18NService } from '@core'; import { I18NService } from '@core';
import { ALAIN_I18N_TOKEN, TitleService } from '@delon/theme'; import { TitleService } from '@delon/theme';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { switchMap } from 'rxjs/operators'; import { switchMap } from 'rxjs/operators';
@@ -34,7 +34,7 @@ export class MonitorNewComponent implements OnInit {
private router: Router, private router: Router,
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService, private i18n: I18NService,
private titleSvc: TitleService, private titleSvc: TitleService,
private formBuilder: FormBuilder private formBuilder: FormBuilder
) { ) {
@@ -150,15 +150,15 @@ export class MonitorNewComponent implements OnInit {
message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('monitors.new.success'), ''); this.notifySvc.success('新增监控成功', '');
this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`); this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`);
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('monitors.new.failed'), message.msg); this.notifySvc.error('新增监控失败', message.msg);
} }
}, },
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error(this.i18nSvc.fanyi('monitors.new.failed'), error.error.msg); this.notifySvc.error('新增监控失败', error.error.msg);
} }
); );
} }
@@ -199,14 +199,14 @@ export class MonitorNewComponent implements OnInit {
message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('monitors.detect.success'), ''); this.notifySvc.success('探测成功', '');
} else { } else {
this.notifySvc.error(this.i18nSvc.fanyi('monitors.detect.failed'), message.msg); this.notifySvc.error('探测失败', message.msg);
} }
}, },
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error(this.i18nSvc.fanyi('monitors.detect.failed'), error.error.msg); this.notifySvc.error('探测异常', error.error.msg);
} }
); );
} }

View File

@@ -1,7 +1,6 @@
import { NgModule, Type } from '@angular/core'; import { NgModule, Type } from '@angular/core';
import { SharedModule } from '@shared'; import { SharedModule } from '@shared';
import { NzBreadCrumbModule } from 'ng-zorro-antd/breadcrumb'; import { NzBreadCrumbModule } from 'ng-zorro-antd/breadcrumb';
import { NzCollapseModule } from 'ng-zorro-antd/collapse';
import { NzDividerModule } from 'ng-zorro-antd/divider'; import { NzDividerModule } from 'ng-zorro-antd/divider';
import { NzLayoutModule } from 'ng-zorro-antd/layout'; import { NzLayoutModule } from 'ng-zorro-antd/layout';
import { NzRadioModule } from 'ng-zorro-antd/radio'; import { NzRadioModule } from 'ng-zorro-antd/radio';
@@ -17,6 +16,7 @@ import { MonitorEditComponent } from './monitor-edit/monitor-edit.component';
import { MonitorListComponent } from './monitor-list/monitor-list.component'; import { MonitorListComponent } from './monitor-list/monitor-list.component';
import { MonitorNewComponent } from './monitor-new/monitor-new.component'; import { MonitorNewComponent } from './monitor-new/monitor-new.component';
import { MonitorRoutingModule } from './monitor-routing.module'; import { MonitorRoutingModule } from './monitor-routing.module';
import { NzCollapseModule } from 'ng-zorro-antd/collapse';
const COMPONENTS: Array<Type<void>> = [ const COMPONENTS: Array<Type<void>> = [
MonitorNewComponent, MonitorNewComponent,

View File

@@ -7,11 +7,11 @@
<nz-form-item> <nz-form-item>
<nz-form-control [nzErrorTip]="'validation.password.required' | i18n"> <nz-form-control [nzErrorTip]="'validation.password.required' | i18n">
<nz-input-group nzSuffixIcon="lock"> <nz-input-group nzSuffixIcon="lock">
<input type="text" nz-input formControlName="password" [placeholder]="'app.lock.placeholder' | i18n" /> <input type="text" nz-input formControlName="password" placeholder="输入任意解锁" />
</nz-input-group> </nz-input-group>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-row nzAlign="middle"> <nz-row nzType="flex" nzAlign="middle">
<nz-col [nzOffset]="12" [nzSpan]="12" style="text-align: right"> <nz-col [nzOffset]="12" [nzSpan]="12" style="text-align: right">
<button nz-button [disabled]="!f.valid" nzType="primary">{{ 'app.lock' | i18n }}</button> <button nz-button [disabled]="!f.valid" nzType="primary">{{ 'app.lock' | i18n }}</button>
</nz-col> </nz-col>

View File

@@ -3,16 +3,16 @@
<nz-tab [nzTitle]="'app.login.tab-login-credentials' | i18n"> <nz-tab [nzTitle]="'app.login.tab-login-credentials' | i18n">
<nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert> <nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert>
<nz-form-item> <nz-form-item>
<nz-form-control [nzErrorTip]="'app.login.message-need-identifier' | i18n"> <nz-form-control nzErrorTip="请输入用户名">
<nz-input-group nzSize="large" nzPrefixIcon="user"> <nz-input-group nzSize="large" nzPrefixIcon="user">
<input nz-input formControlName="userName" [placeholder]="'app.login.message-need-identifier' | i18n" /> <input nz-input formControlName="userName" placeholder="请输入用户名" />
</nz-input-group> </nz-input-group>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-control [nzErrorTip]="'app.login.message-need-credential' | i18n"> <nz-form-control nzErrorTip="请输入密码">
<nz-input-group nzSize="large" nzPrefixIcon="lock"> <nz-input-group nzSize="large" nzPrefixIcon="lock">
<input nz-input type="password" formControlName="password" [placeholder]="'app.login.message-need-credential' | i18n" /> <input nz-input type="password" formControlName="password" placeholder="请输入密码" />
</nz-input-group> </nz-input-group>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>

View File

@@ -1,10 +1,10 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnDestroy, Optional } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnDestroy, Optional } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { I18NService, StartupService } from '@core'; import { StartupService } from '@core';
import { ReuseTabService } from '@delon/abc/reuse-tab'; import { ReuseTabService } from '@delon/abc/reuse-tab';
import { DA_SERVICE_TOKEN, ITokenService, SocialService } from '@delon/auth'; import { DA_SERVICE_TOKEN, ITokenService, SocialOpenType, SocialService } from '@delon/auth';
import { SettingsService, _HttpClient, ALAIN_I18N_TOKEN } from '@delon/theme'; import { SettingsService, _HttpClient } from '@delon/theme';
import { User } from '@delon/theme/src/services/settings/types'; import { User } from '@delon/theme/src/services/settings/types';
import { NzTabChangeEvent } from 'ng-zorro-antd/tabs'; import { NzTabChangeEvent } from 'ng-zorro-antd/tabs';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
@@ -29,7 +29,6 @@ export class UserLoginComponent implements OnDestroy {
@Inject(ReuseTabService) @Inject(ReuseTabService)
private reuseTabService: ReuseTabService, private reuseTabService: ReuseTabService,
@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService, @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService,
private startupSrv: StartupService, private startupSrv: StartupService,
private http: _HttpClient, private http: _HttpClient,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
@@ -126,7 +125,7 @@ export class UserLoginComponent implements OnDestroy {
let user: User = { let user: User = {
name: this.userName.value, name: this.userName.value,
avatar: './assets/img/avatar.svg', avatar: './assets/img/avatar.svg',
email: this.i18nSvc.fanyi('app.role.admin') email: '管理员'
}; };
this.settingsService.setUser(user); this.settingsService.setUser(user);
// 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响 // 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响

View File

@@ -1,296 +1,138 @@
{ {
"menu": { "menu.search.placeholder": "Search for people, file, photos...",
"main": "Main", "menu.fullscreen": "Fullscreen",
"lang": "Language", "menu.fullscreen.exit": "Exit Fullscreen",
"dashboard": "DashBoard", "menu.clear.local.storage": "Clear Local Storage",
"search.placeholder": "SearchMonitor Name、IP", "menu.lang": "Language",
"fullscreen": "Full Screen", "menu.main": "Main Navigation",
"fullscreen.exit": "Exit", "menu.dashboard": "Dashboard",
"clear.local.storage": "Clear Local Storage", "menu.dashboard.v1": "Default",
"monitor": { "menu.dashboard.analysis": "Analysis",
"": "Monitor", "menu.dashboard.monitor": "Monitor",
"service": "Service Monitor", "menu.dashboard.workplace": "Workplace",
"db": "DB Monitor", "menu.shortcut": "Shortcut",
"os": "OS Monitor", "menu.widgets": "Widgets",
"mid": "Mid Monitor", "menu.alain": "Alain",
"custom": "Custom Monitor" "menu.style": "Style",
}, "menu.style.typography": "Typography",
"account": { "menu.style.gridmasonry": "Grid Masonry",
"": "Personal", "menu.style.colors": "Colors",
"center": "Personal Center", "menu.delon": "Delon Lib",
"settings": "Account Setting", "menu.delon.form": "Dynamic Form",
"security": "Security Setting", "menu.delon.table": "Simple table",
"binding": "Account Binding", "menu.delon.util": "Util",
"trigger": "Trigger Error", "menu.delon.print": "Print",
"logout": "Logout" "menu.delon.guard": "Route Guard",
}, "menu.delon.cache": "Cache",
"alert": { "menu.delon.qr": "QR",
"": "Alert", "menu.delon.acl": "ACL",
"center": "Alert Center", "menu.delon.downfile": "Download File",
"setting": "Alert Setting", "menu.delon.xlsx": "Excel",
"dispatch": "Alert Notify" "menu.delon.zip": "Zip",
}, "menu.pro": "Antd Pro",
"extras": { "menu.form": "Form",
"": "More", "menu.form.basicform": "Basic Form",
"help": "Help Center", "menu.form.stepform": "Step Form",
"setting": "Setting" "menu.form.stepform.info": "Step Form(write transfer information)",
}, "menu.form.stepform.confirm": "Step Form(confirm transfer information)",
"more": "More" "menu.form.stepform.result": "Step Form(finished)",
}, "menu.form.advancedform": "Advanced Form",
"monitor": { "menu.list": "List",
"": "Monitor", "menu.list.searchtable": "Search Table",
"name": "Monitor Name", "menu.list.basiclist": "Basic List",
"name.tip": "Monitor name, the name needs to be unique", "menu.list.cardlist": "Card List",
"host": "Monitor Host", "menu.list.searchlist": "Search List",
"host.tip": "The monitored peer IP or domain name", "menu.list.searchlist.articles": "Search List(articles)",
"description": "Description", "menu.list.searchlist.projects": "Search List(projects)",
"description.tip": "Description and remarks", "menu.list.searchlist.applications": "Search List(applications)",
"intervals": "Intervals", "menu.profile": "Profile",
"intervals.tip": "Monitor the interval time of periodic collection of data, second", "menu.profile.basic": "Basic Profile",
"category": { "menu.profile.advanced": "Advanced Profile",
"": "Category", "menu.result": "Result",
"service": "Service", "menu.result.success": "Success",
"db": "Database", "menu.result.fail": "Fail",
"os": "OS", "menu.exception": "Exception",
"mid": "Middleware", "menu.exception.not-permission": "403",
"custom": "Custom" "menu.exception.not-find": "404",
}, "menu.exception.server-error": "500",
"app": { "menu.account": "Account",
"": "Monitor Type", "menu.account.center": "Account Center",
"website": "Website Monitor", "menu.account.settings": "Account Settings",
"api": "HTTP API", "menu.account.trigger": "Trigger Error",
"http": "HTTP API", "menu.account.logout": "Logout",
"ping": "PING Connect", "menu.more": "More",
"port": "Port Available", "menu.report": "Report",
"mysql": "Mysql", "menu.report.relation": "Relation Map",
"oracle": "Oracle", "menu.extras": "Extra",
"redis": "Redis", "menu.extras.helpcenter": "Help Center",
"fullsite": "SiteMap Monitor" "menu.extras.settings": "Settings",
}, "menu.extras.poi": "Poi",
"status": { "app.analysis.test": "Gongzhuan No.{{no}} shop",
"": "Monitor Status", "app.analysis.introduce": "Introduce",
"all": "All Status", "app.analysis.total-sales": "Total Sales",
"available": "Available", "app.analysis.day-sales": "Day Sales",
"unavailable": "UnAvailable", "app.analysis.visits": "Visits",
"unreachable": "UnReachable", "app.analysis.visits-trend": "Visits Trend",
"un-manage": "UnManaged" "app.analysis.visits-ranking": "Visits Ranking",
} "app.analysis.day-visits": "Day Visits",
}, "app.analysis.week": "Week Ratio",
"alert": { "app.analysis.day": "Day Ratio",
"": "Alert", "app.analysis.payments": "Payments",
"status": { "app.analysis.conversion-rate": "Conversion Rate",
"": "Alert Status", "app.analysis.operational-effect": "Operational Effect",
"all": "All Status", "app.analysis.sales-trend": "Stores Sales Trend",
"0": "Pending", "app.analysis.sales-ranking": "Sales Ranking",
"2": "Restored", "app.analysis.all-year": "All Year",
"3": "Processed" "app.analysis.all-month": "All Month",
}, "app.analysis.all-week": "All Week",
"priority": { "app.analysis.all-today": "All day",
"": "Alarm Priority", "app.analysis.search-users": "Search Users",
"all": "All Priority", "app.analysis.per-capita-search": "Per Capita Search",
"0": "Emergency", "app.analysis.online-top-search": "Online Top Search",
"1": "Critical", "app.analysis.the-proportion-of-sales": "The Proportion Of Sales",
"2": "Warning" "app.analysis.channel.all": "ALL",
} "app.analysis.channel.online": "Online",
}, "app.analysis.channel.stores": "Stores",
"alert.setting.new": "New Threshold", "app.analysis.sales": "Sales",
"alert.setting.edit": "Edit Threshold", "app.analysis.traffic": "Traffic",
"alert.setting.delete": "Delete Threshold", "app.analysis.table.rank": "Rank",
"alert.setting.target": "Metric Target", "app.analysis.table.search-keyword": "Keyword",
"alert.setting.expr": "Threshold Trigger Expr", "app.analysis.table.users": "Users",
"alert.setting.times": "Trigger Times", "app.analysis.table.weekly-range": "Weekly Range",
"alert.setting.times.tip": "Set how many times the threshold is triggered before sending an alert", "app.monitor.trading-activity": "Real-Time Trading Activity",
"alert.setting.template": "Notice Template", "app.monitor.total-transactions": "Total transactions today",
"alert.setting.template.tip": "Supported notification template environment variables", "app.monitor.sales-target": "Sales target completion rate",
"alert.setting.template.label": "The notification information template sent after the alarm is triggered, see the template environment variable above", "app.monitor.remaining-time": "Remaining time of activity",
"alert.setting.template.example": "Please input notice template.Eg: ${app}.${metrics}.${metric}'s value is too high", "app.monitor.total-transactions-per-second": "Total transactions per second",
"alert.setting.template.monitor-type": "Monitor Type Name", "app.monitor.activity-forecast": "Activity forecast",
"alert.setting.template.metrics-name": "Metrics Name", "app.monitor.efficiency": "Efficiency",
"alert.setting.template.metric-name": "Metric Name", "app.monitor.ratio": "Ratio",
"alert.setting.template.metric-value": "Metric Target Value", "app.monitor.proportion-per-category": "Proportion Per Category",
"alert.setting.template.other-value": "Other Metric Value", "app.monitor.fast-food": "Fast food",
"alert.setting.template.instance-value": "Instance Value", "app.monitor.western-food": "Western food",
"alert.setting.default": "Global Default", "app.monitor.hot-pot": "Hot pot",
"alert.setting.default.tip": "Whether this alarm threshold configuration applies to all this type of monitoring globally", "app.monitor.waiting-for-implementation": "Waiting for implementation",
"alert.setting.enable": "Enable Alert", "app.monitor.popular-searches": "Popular Searches",
"alert.setting.enable.tip": "This alarm threshold configuration is enabled or disabled", "app.monitor.resource-surplus": "Resource Surplus",
"alert.setting.connect": "Alert Associate Monitors", "app.monitor.fund-surplus": "Fund Surplus",
"alert.setting.connect.left": "No Associate",
"alert.setting.connect.right": "Associated",
"alert.setting.expr.tip": "Supported Threshold Trigger Expression Environment Variables and Operators",
"alert.setting.expr.label": "Calculate and judge whether the threshold is triggered according to this expression. The expression environment variables and operators are shown above.",
"alert.setting.expr.example": "Calculate whether to trigger the threshold according to this expression.Eg",
"alert.setting.priority.tip": "The alarm level that triggers the threshold, from low to high:WarningCriticalEmergency",
"alert.setting.target.tip": "The selected metric object",
"alert.setting.target.other": "Other metric objects of the row",
"alert.setting.target.instance": "Instance of the row",
"alert.setting.operator": "Supported operator functions",
"alert.center.delete": "Delete Alerts",
"alert.center.deal": "Mark Processed",
"alert.center.no-deal": "Mark Pending",
"alert.center.search": "Search Alert Content",
"alert.center.filter-status": "Filter Alert Status",
"alert.center.filter-priority": "Filter Alert Priority",
"alert.center.target": "Metric Target",
"alert.center.monitor": "Belong Monitor",
"alert.center.priority": "Priority",
"alert.center.content": "Alert Content",
"alert.center.status": "Status",
"alert.center.time": "Alert Time",
"alert.center.notify.no-delete": "No items selected for deletion!",
"alert.center.confirm.delete": "Please confirm whether to delete!",
"alert.center.confirm.delete-batch": "Please confirm whether to delete in batch!",
"alert.center.notify.no-mark": "No items selected for mark!",
"alert.center.confirm.mark-done-batch": "Please confirm whether to mark processed in batch!",
"alert.center.confirm.mark-done": "Please confirm whether to mark processed!",
"alert.center.confirm.mark-no-batch": "Please confirm whether to mark Pending in batch!",
"alert.center.confirm.mark-no": "Please confirm whether to mark Pending!",
"alert.notice.receiver": "Alert Receiver",
"alert.notice.receiver.new": "New Receiver",
"alert.notice.receiver.edit": "Edit Receiver",
"alert.notice.receiver.delete": "Delete Receiver",
"alert.notice.receiver.people": "Receiver",
"alert.notice.receiver.people.name": "Receiver Name",
"alert.notice.receiver.type": "Notice Type",
"alert.notice.receiver.setting": "Setting",
"alert.notice.type.sms": "SMS",
"alert.notice.type.phone": "Phone",
"alert.notice.type.email": "Email",
"alert.notice.type.url": "URL",
"alert.notice.type.wechat": "Open WeChat",
"alert.notice.type.wechat-id": "WeChat OPENID",
"alert.notice.type.wework": "WeWork Robot",
"alert.notice.type.wework-key": "WeWork Robot KEY",
"alert.notice.type.access-token": "Robot ACCESS_TOKEN",
"alert.notice.type.ding": "DingDing Robot",
"alert.notice.type.fei-shu": "FeiShu Robot",
"alert.notice.type.fei-shu-key": "FeiShu Robot KEY",
"alert.notice.rule": "Alert Notice Rule",
"alert.notice.rule.new": "New Notice Rule",
"alert.notice.rule.edit": "Edit Notice Rule",
"alert.notice.rule.delete": "Delete Notice Rule",
"alert.notice.rule.name": "Rule Name",
"alert.notice.rule.all": "Dispatch ALl",
"alert.notice.rule.enable": "Enable",
"dashboard.alerts.title": "Recently Alerts List",
"dashboard.alerts.title-no": "Recently Pending Alerts",
"dashboard.alerts.no": "No Pending Alerts",
"dashboard.alerts.enter": "Go Alert Center",
"dashboard.alerts.distribute": "The Distribution Of Alerts",
"dashboard.alerts.num": "Alerts Num",
"dashboard.alerts.deal": "Alerts Dealing",
"dashboard.alerts.deal-percent": "Dealing Rate",
"dashboard.monitors.total": "Monitor Total",
"dashboard.monitors.title": "Monitoring Overview",
"dashboard.monitors.sub-title": "The Distribution Of Monitors",
"dashboard.monitors.formatter": " Monitors ",
"dashboard.monitors.distribute": "Monitor Distribution",
"monitors.list": "Monitor List",
"monitors.new": "New",
"monitors.new.success": "New Monitor Success",
"monitors.new.failed": "New Monitor Failed",
"monitors.edit": "Edit",
"monitors.edit.success": "Update Monitor Success",
"monitors.edit.failed": "Update Monitor Failed",
"monitors.not-found": "This Monitor Not Found",
"monitors.delete": "Delete",
"monitors.edit-monitor": "Edit Monitor",
"monitors.delete-monitor": "Delete Monitor",
"monitors.enable": "Enable Monitor",
"monitors.cancel": "Cancel Monitor",
"monitors.search.placeholder": "Search Monitor",
"monitors.search.filter": "Filter Monitor Status",
"monitors.total": "Total",
"monitors.advanced": "Advanced",
"monitors.advanced.tip": "Setting Advanced Param",
"monitors.detect": "Detect",
"monitors.detect.success": "Detect Success",
"monitors.detect.failed": "Detect Failed",
"monitors.detect.tip": "Detect monitor available before apply",
"monitors.detail": "Monitor Detail",
"monitors.detail.name": "Name",
"monitors.detail.port": "Port",
"monitors.detail.description": "Desc",
"monitors.detail.status": "Status",
"monitors.detail.basic": "Monitor Basic",
"monitors.detail.realtime": "Monitor Real-Time Detail",
"monitors.detail.history": "Monitor Historical Chart Detail",
"monitors.collect.time": "Collect Time",
"monitors.collect.time.tip": "Last collect time",
"monitors.detail.chart.zoom": "Zoom In",
"monitors.detail.chart.back": "Zoom restore",
"monitors.detail.chart.save": "Save as Image",
"monitors.detail.chart.query-1h": "Query 1 Hour",
"monitors.detail.chart.query-6h": "Query 6 Hours",
"monitors.detail.chart.query-1d": "Query 1 Day",
"monitors.detail.chart.query-1w": "Query 1 Week",
"monitors.detail.chart.query-1m": "Query 1 Month",
"monitors.detail.chart.no-data": "No Metrics Data",
"monitors.detail.chart.unit": "Unit",
"common.name": "Name",
"common.value": "Value",
"common.search": "Search",
"common.refresh": "Refresh",
"common.edit-time": "Last Update Time",
"common.new-time": "Create Time",
"common.edit": "Operate",
"common.total": "Total",
"common.yes": "Yes",
"common.no": "No",
"common.enable": "Enable",
"common.disable": "Disable",
"common.notify.no-select-edit": "No items selected for editing!",
"common.notify.one-select-edit": "Only one selection can be edited!",
"common.confirm.delete": "Please confirm whether to delete!",
"common.notify.no-select-delete": "No items selected for deletion!",
"common.confirm.delete-batch": "Please confirm whether to delete in batches!",
"common.notify.delete-success": "Delete Success!",
"common.notify.delete-fail": "Delete Failed!",
"common.notify.new-success": "Add Success!",
"common.notify.new-fail": "Add Failed!",
"common.notify.apply-success": "Apply Success!",
"common.notify.apply-fail": "Apply Failed!",
"common.notify.monitor-fail": "Query Monitor Failed!",
"common.notify.edit-success": "Edit Success!",
"common.notify.edit-fail": "Edit Failed!",
"common.notify.no-select-cancel": "No items selected for cancel!",
"common.confirm.cancel-batch": "Please confirm whether to cancel monitor in batches!",
"common.confirm.cancel": "Please confirm whether to cancel monitor!",
"common.notify.cancel-success": "Cancel Success!",
"common.notify.cancel-fail": "Cancel Failed!",
"common.notify.mark-success": "Mark Success!",
"common.notify.mark-fail": "Mark Failed!",
"common.notify.no-select-enable": "No items selected for enable!",
"common.confirm.enable-batch": "Please confirm whether to enable monitor in batches!",
"common.confirm.enable": "Please confirm whether to enable monitor!",
"common.notify.enable-success": "Enable Success!",
"common.notify.enable-fail": "Enable Failed!",
"common.confirm.clear-cache": "Please confirm whether to clear cache!",
"common.notify.clear-success": "Clear Success!",
"common.button.ok": "OK",
"common.button.cancel": "Cancel",
"common.button.help": "Help",
"common.button.edit": "Edit",
"common.button.delete": "Delete",
"common.button.detect": "Detect",
"validation.email.invalid": "Invalid email",
"validation.phone.invalid": "Invalid phone number",
"validation.verification-code.invalid": "Invalid verification code, should be 6 digits",
"validation.required": "Please fill in the required fields! ",
"app.theme.default": "Light Theme",
"app.theme.dark": "Dark Theme",
"app.theme.compact": "Compact Theme",
"app.role.admin": "Administrator",
"app.lock": "Lock", "app.lock": "Lock",
"app.lock.placeholder": "Enter Any To Unlock", "app.login.message-invalid-credentials": "Invalid username or passwordadmin/ant.design",
"app.passport.desc": "TanCloud-Friendly High Performance Monitoring Cloud Service", "app.login.message-invalid-verification-code": "Invalid verification code",
"app.passport.welcome": "Welcome To Use TanCloud-Monitoring Cloud Service-tancloud.cn",
"app.login.message-need-identifier": "Please enter your username",
"app.login.message-need-credential": "Please enter password",
"app.login.message-invalid-credentials": "Invalid username or password",
"app.login.tab-login-credentials": "Credentials", "app.login.tab-login-credentials": "Credentials",
"app.login.tab-login-mobile": "Mobile number",
"app.login.remember-me": "Remember me", "app.login.remember-me": "Remember me",
"app.login.forgot-password": "Forgot your password?",
"app.login.sign-in-with": "Sign in with",
"app.login.signup": "Sign up",
"app.login.login": "Login", "app.login.login": "Login",
"app.register.register": "Register",
"app.register.get-verification-code": "Get code",
"app.register.sign-in": "Already have an account?",
"app.register-result.msg": "Accountregistered at {{email}}",
"app.register-result.activation-email":
"The activation email has been sent to your email address and is valid for 24 hours. Please log in to the email in time and click on the link in the email to activate the account.",
"app.register-result.back-home": "Back to home",
"app.register-result.view-mailbox": "View mailbox",
"validation.email.required": "Please enter your email!", "validation.email.required": "Please enter your email!",
"validation.email.wrong-format": "The email address is in the wrong format!", "validation.email.wrong-format": "The email address is in the wrong format!",
"validation.password.required": "Please enter your password!", "validation.password.required": "Please enter your password!",

View File

@@ -27,7 +27,7 @@
"alert": { "alert": {
"": "告警", "": "告警",
"center": "告警中心", "center": "告警中心",
"setting": "告警阈值", "setting": "告警配置",
"dispatch": "告警通知" "dispatch": "告警通知"
}, },
"extras": { "extras": {
@@ -39,14 +39,6 @@
}, },
"monitor": { "monitor": {
"": "监控", "": "监控",
"name": "监控名称",
"name.tip": "标识监控的名称,名称需要保证唯一性",
"host": "监控Host",
"host.tip": "被监控的对端IP或域名",
"description": "描述备注",
"description.tip": "更多标识和描述此监控的备注信息",
"intervals": "采集间隔",
"intervals.tip": "监控周期性采集数据间隔时间,单位秒",
"category": { "category": {
"": "监控类别", "": "监控类别",
"service": "应用服务", "service": "应用服务",
@@ -66,227 +58,46 @@
"oracle": "Oracle", "oracle": "Oracle",
"redis": "Redis", "redis": "Redis",
"fullsite": "全站监控" "fullsite": "全站监控"
},
"status": {
"": "监控状态",
"all": "全部状态",
"available": "正常监控",
"unavailable": "不可用",
"unreachable": "不可达",
"un-manage": "未管理"
} }
}, },
"alert": { "alert": {
"": "告警", "": "告警",
"status": { "status": {
"": "告警状态", "": "告警状态",
"all": "全部状态", "0": "待处理",
"0": "未处理",
"2": "已恢复", "2": "已恢复",
"3": "已处理" "3": "已处理"
}, },
"priority": { "priority": {
"": "告警级别", "": "告警级别",
"all": "全部级别",
"0": "紧急告警", "0": "紧急告警",
"1": "严重告警", "1": "严重告警",
"2": "警告告警" "2": "警告告警"
} }
}, },
"alert.setting.new": "新增阈值",
"alert.setting.edit": "编辑阈值",
"alert.setting.delete": "删除阈值",
"alert.setting.target": "指标对象",
"alert.setting.expr": "阈值触发表达式",
"alert.setting.times": "触发次数",
"alert.setting.times.tip": "设置触发阈值多少次之后才会发送告警",
"alert.setting.template": "通知模版",
"alert.setting.template.tip": "支持的通知模版环境变量",
"alert.setting.template.label": "告警触发后发送的通知信息模版,模版环境变量见上方",
"alert.setting.template.example": "请输入告警的通知模版.示例: ${app}.${metrics}.${metric}'s value is too high",
"alert.setting.template.monitor-type": "监控类型名称",
"alert.setting.template.metrics-name": "监控指标集合名称",
"alert.setting.template.metric-name": "监控指标名称",
"alert.setting.template.metric-value": "监控指标对象值",
"alert.setting.template.other-value": "所属行其它指标值",
"alert.setting.template.instance-value": "所属行实例值",
"alert.setting.default": "全局默认",
"alert.setting.default.tip": "此告警阈值配置是否应用于全局所有此类型监控",
"alert.setting.enable": "启用告警",
"alert.setting.enable.tip": "此告警阈值配置开启生效或关闭",
"alert.setting.connect": "告警定义关联监控",
"alert.setting.connect.left": "未关联监控",
"alert.setting.connect.right": "已关联监控",
"alert.setting.expr.tip": "支持的阈值触发表达式环境变量与操作符",
"alert.setting.expr.label": "根据此表达式来计算判断是否触发阈值,表达式环境变量和操作符见上方",
"alert.setting.expr.example": "根据此表达式计算判断是否触发阈值.示例",
"alert.setting.priority.tip": "触发阈值的告警级别,从低到高依次为:警告-warning严重-critical紧急-emergency",
"alert.setting.target.tip": "选中的指标对象",
"alert.setting.target.other": "所属行其它指标对象",
"alert.setting.target.instance": "所属行实例",
"alert.setting.operator": "支持操作符函数",
"alert.center.delete": "删除告警",
"alert.center.deal": "标记已处理",
"alert.center.no-deal": "标记未处理",
"alert.center.search": "搜索告警内容",
"alert.center.filter-status": "告警状态过滤",
"alert.center.filter-priority": "告警级别过滤",
"alert.center.target": "告警指标",
"alert.center.monitor": "所属监控",
"alert.center.priority": "级别",
"alert.center.content": "告警内容",
"alert.center.status": "状态",
"alert.center.time": "告警时间",
"alert.center.notify.no-delete": "未选中任何待删除项!",
"alert.center.confirm.delete": "请确认是否删除!",
"alert.center.confirm.delete-batch": "请确认是否批量删除!",
"alert.center.notify.no-mark": "未选中任何待标记项!",
"alert.center.confirm.mark-done-batch": "请确认是否批量标记已处理!",
"alert.center.confirm.mark-done": "请确认是否标记已处理!",
"alert.center.confirm.mark-no-batch": "请确认是否批量标记未处理!",
"alert.center.confirm.mark-no": "请确认是否标记未处理!",
"alert.notice.receiver": "告警接收人",
"alert.notice.receiver.new": "新增接收人",
"alert.notice.receiver.edit": "编辑接收人",
"alert.notice.receiver.delete": "删除接收人",
"alert.notice.receiver.people": "接收人",
"alert.notice.receiver.people.name": "接收人名称",
"alert.notice.receiver.type": "通知方式",
"alert.notice.receiver.setting": "配置",
"alert.notice.type.sms": "短信",
"alert.notice.type.phone": "手机号",
"alert.notice.type.email": "邮箱",
"alert.notice.type.url": "URL地址",
"alert.notice.type.wechat": "微信公众号",
"alert.notice.type.wechat-id": "微信OPENID",
"alert.notice.type.wework": "企业微信机器人",
"alert.notice.type.wework-key": "企业微信机器人KEY",
"alert.notice.type.access-token": "机器人ACCESS_TOKEN",
"alert.notice.type.ding": "钉钉机器人",
"alert.notice.type.fei-shu": "飞书机器人",
"alert.notice.type.fei-shu-key": "飞书机器人KEY",
"alert.notice.rule": "告警通知策略",
"alert.notice.rule.new": "新增通知策略",
"alert.notice.rule.edit": "编辑通知策略",
"alert.notice.rule.delete": "删除通知策略",
"alert.notice.rule.name": "策略名称",
"alert.notice.rule.all": "转发所有",
"alert.notice.rule.enable": "是否启用",
"dashboard.alerts.title": "最近告警列表",
"dashboard.alerts.title-no": "最近未处理告警",
"dashboard.alerts.no": "暂无未处理告警",
"dashboard.alerts.enter": "进入告警中心",
"dashboard.alerts.distribute": "告警分布",
"dashboard.alerts.num": "告警数量",
"dashboard.alerts.deal": "告警处理",
"dashboard.alerts.deal-percent": "告警处理率",
"dashboard.monitors.total": "监控总量",
"dashboard.monitors.title": "监控总览",
"dashboard.monitors.sub-title": "监控类型纳管数量分布",
"dashboard.monitors.formatter": "个监控 占比",
"dashboard.monitors.distribute": "纳管数量分布",
"monitors.list": "监控列表",
"monitors.new": "新增",
"monitors.new.success": "新增监控成功",
"monitors.new.failed": "新增监控失败",
"monitors.edit": "编辑",
"monitors.edit.success": "修改监控成功",
"monitors.edit.failed": "修改监控失败",
"monitors.not-found": "查询异常,此监控不存在",
"monitors.delete": "删除",
"monitors.edit-monitor": "编辑监控",
"monitors.delete-monitor": "删除监控",
"monitors.enable": "启用监控",
"monitors.cancel": "取消监控",
"monitors.search.placeholder": "搜索监控",
"monitors.search.filter": "监控状态过滤",
"monitors.total": "总量",
"monitors.advanced": "高级设置",
"monitors.advanced.tip": "设置高级可选参数",
"monitors.detect": "测试连接",
"monitors.detect.success": "测试连接成功",
"monitors.detect.failed": "测试连接失败",
"monitors.detect.tip": "新增监控前是否先探测检查监控可用性",
"monitors.detail": "监控详情",
"monitors.detail.name": "名称",
"monitors.detail.port": "端口",
"monitors.detail.description": "描述",
"monitors.detail.status": "状态",
"monitors.detail.basic": "监控基本属性",
"monitors.detail.realtime": "监控实时数据详情",
"monitors.detail.history": "监控历史图表详情",
"monitors.collect.time": "采集时间",
"monitors.collect.time.tip": "最近采集时间",
"monitors.detail.chart.zoom": "区域缩放",
"monitors.detail.chart.back": "缩放还原",
"monitors.detail.chart.save": "保存图片",
"monitors.detail.chart.query-1h": "查询近1小时",
"monitors.detail.chart.query-6h": "查询近6小时",
"monitors.detail.chart.query-1d": "查询近1天",
"monitors.detail.chart.query-1w": "查询近1周",
"monitors.detail.chart.query-1m": "查询近1月",
"monitors.detail.chart.no-data": "暂无数据",
"monitors.detail.chart.unit": "单位",
"common.name": "名称",
"common.value": "值",
"common.search": "搜索",
"common.refresh": "刷新",
"common.edit-time": "更新时间",
"common.new-time": "创建时间",
"common.edit": "操作",
"common.total": "总量",
"common.yes": "是",
"common.no": "否",
"common.enable": "开启",
"common.disable": "关闭",
"common.notify.no-select-edit": "未选中任何待编辑项!",
"common.notify.one-select-edit": "只能对一个选中项进行编辑!",
"common.confirm.delete": "请确认是否删除!",
"common.notify.no-select-delete": "未选中任何待删除项!",
"common.confirm.delete-batch": "请确认是否批量删除!",
"common.notify.delete-success": "删除成功!",
"common.notify.delete-fail": "删除失败!",
"common.notify.new-success": "新增成功!",
"common.notify.new-fail": "新增失败!",
"common.notify.apply-success": "应用成功!",
"common.notify.apply-fail": "应用失败!",
"common.notify.monitor-fail": "查询此监控定义详情失败!",
"common.notify.edit-success": "修改成功!",
"common.notify.edit-fail": "修改失败!",
"common.notify.mark-success": "标记成功!",
"common.notify.mark-fail": "标记失败!",
"common.notify.no-select-cancel": "未选中任何待取消项!",
"common.confirm.cancel-batch": "请确认是否批量取消监控!",
"common.confirm.cancel": "请确认是否取消监控!",
"common.notify.cancel-success": "取消监控成功!",
"common.notify.cancel-fail": "取消监控失败!",
"common.notify.no-select-enable": "未选中任何待启用监控项!",
"common.confirm.enable-batch": "请确认是否批量启用监控!",
"common.confirm.enable": "请确认是否启用监控!",
"common.notify.enable-success": "启用监控成功!",
"common.notify.enable-fail": "启用监控失败!",
"common.confirm.clear-cache": "请确认是否清理缓存!",
"common.notify.clear-success": "清理成功!",
"common.button.ok": "确定",
"common.button.detect": "测试",
"common.button.cancel": "取消",
"common.button.help": "帮助",
"common.button.edit": "编辑",
"common.button.delete": "删除",
"app.theme.default": "浅色主题",
"app.theme.dark": "深色主题",
"app.theme.compact": "紧凑主题",
"app.role.admin": "管理员",
"app.lock": "锁屏", "app.lock": "锁屏",
"app.lock.placeholder": "输入任意解锁", "app.login.message-need-identifier": "输入邮箱或手机号",
"app.passport.desc": "TanCloud-易用友好的高性能监控云服务",
"app.passport.welcome": "欢迎使用TanCloud探云-监控云服务-tancloud.cn",
"app.login.message-need-identifier": "请输入用户名",
"app.login.message-need-credential": "请输入密码", "app.login.message-need-credential": "请输入密码",
"app.login.message-invalid-credentials": "账户或密码错误", "app.login.message-invalid-credentials": "账户或密码错误",
"app.login.message-invalid-verification-code": "验证码错误",
"app.login.tab-login-credentials": "账户密码登录", "app.login.tab-login-credentials": "账户密码登录",
"app.login.tab-login-mobile": "手机号登录",
"app.login.remember-me": "自动登录", "app.login.remember-me": "自动登录",
"app.login.forgot-password": "忘记密码",
"app.login.sign-in-with": "其他登录方式",
"app.login.signup": "注册账户",
"app.login.login": "登录", "app.login.login": "登录",
"app.password.forgot": "忘记密码",
"app.password.reset": "重置密码",
"app.register.register": "注册",
"app.register.get-verification-code": "获取验证码",
"app.register.sign-in": "使用已有账户登录",
"app.register-result.msg": "你的账户:{{email}} 注册成功",
"app.register-result.activation-email":
"额外赠送监控额度邮件已发送到你的邮箱中。请及时登录邮箱,点击邮件中的链接领取。",
"app.register-result.login": "开始登录",
"app.register-result.back-home": "返回首页",
"app.register-result.view-mailbox": "查看邮箱",
"validation.email.required": "请输入邮箱地址!", "validation.email.required": "请输入邮箱地址!",
"validation.email.wrong-format": "邮箱地址格式错误!", "validation.email.wrong-format": "邮箱地址格式错误!",
"validation.email.invalid": "无效的邮箱地址!", "validation.email.invalid": "无效的邮箱地址!",